Local development
Guide for running Buntime on desktop: monorepo in watch mode, .env at the root, external plugins with hot-reload, Docker Compose with profiles, and three binary execution modes (dev, bundle, compiled).
For environment variables and directories, see Environments. For Kubernetes deploy, see Helm charts.
# From the monorepo rootbun installbun devThis starts in parallel:
@buntime/runtimein watch mode@buntime/cpanelin watch mode- Each
@buntime/plugin-*core in watch mode
With no additional configuration, the runtime listens on http://localhost:8000 and the cpanel is available at /cpanel. Required variables come from the .env file at the monorepo root.
Launch configurations (.claude/launch.json)
Section titled “Launch configurations (.claude/launch.json)”For one-click starts via tooling that reads Claude Code’s launch config, the repo ships four named configurations:
| Name | Command | Port | Standalone? |
|---|---|---|---|
buntime-dev | bun run dev (root: runtime + cpanel watcher + plugin watchers in parallel) | 8000 | yes — recommended default |
runtime-dev | bun run --filter @buntime/runtime dev (runtime in watch mode) | 8000 | partial — see note |
cpanel-watch | bun run --filter @buntime/cpanel dev (build-watcher emitting to apps/cpanel/dist/) | — | no — pair with running runtime |
plugins-watch | bun run --filter '@buntime/plugin-*' dev (build-watchers emitting to each plugins/*/dist/) | — | no — pair with running runtime |
The launch file mirrors the pattern from the sibling zomme monorepo (<thing>-dev for full apps, <thing>-watch for build-only watchers); the entries make these commands addressable by name to harness/IDE integrations.
Common workflows:
- “Iterate on everything” →
buntime-dev. - “Iterate on runtime code only, UI/plugins are stable” →
runtime-dev(build cpanel/plugins once first). - “Iterate on cpanel UI while runtime stays up” → run
buntime-dev(orruntime-dev) in one terminal +cpanel-watchin another. Refresh the browser to see UI changes. - “Iterate on a single plugin” →
bun run --filter @buntime/plugin-<name> devdirectly +POST /api/plugins/reloadafter each rebuild (no launch entry; one-off per plugin).
.env at the root
Section titled “.env at the root”The .env file in buntime/ configures the runtime and core plugins:
# RuntimeRUNTIME_PLUGIN_DIRS=/path/to/external-pluginsRUNTIME_WORKER_DIRS=/path/to/buntime-apps:/path/to/edge-functions
# plugin-gateway (app shell)GATEWAY_SHELL_DIR=/path/to/functions/app-shellGATEWAY_SHELL_EXCLUDES=cpanelImportant rules:
RUNTIME_WORKER_DIRSandRUNTIME_PLUGIN_DIRSpoint to parents, not to individual apps/plugins. The loader scans direct children.- Separator is
:(PATH style). Commas do not work. - Core plugins from the monorepo (
plugins/*) are automatically loaded vianode_moduleswhen the runtime runs in dev mode — no need to addplugins/toRUNTIME_PLUGIN_DIRS. - External plugins without
dist/plugin.jsare silently ignored.
External plugins in watch mode
Section titled “External plugins in watch mode”Plugins outside the monorepo (in other repos) load via RUNTIME_PLUGIN_DIRS. For simultaneous hot-reload:
# Terminal 1 — runtime + cpanel + core pluginscd /path/to/buntimebun dev
# Terminal 2 — external plugin in watch modecd /path/to/external-plugins/plugin-foobun dev
# Terminal 3 — another external plugincd /path/to/external-plugins/plugin-barbun devFor a one-time build without watch:
cd /path/to/external-plugins/plugin-foobun run buildThree execution modes
Section titled “Three execution modes”| Mode | Command | Use case | Size |
|---|---|---|---|
| Dev | bun dev | Hot reload, debugging, source maps | — |
| Bundle | bun run dist/index.ts | Production-like, requires Bun | ~1.5 MB |
| Compiled | ./dist/buntime | Standalone, no Bun required | ~130 MB |
Hot reload + source maps. Plugins load from node_modules. Slower startup.
cd apps/runtimebun devBundle
Section titled “Bundle”Bundles the runtime but requires Bun to run:
cd apps/runtimebun run buildbun run dist/index.tsOutput in dist/: index.ts (~1.3 MB) + wrapper.ts (~23 KB).
Compiled
Section titled “Compiled”Standalone binary with everything embedded (Bun + core plugins):
cd apps/runtimebun run build:bin./dist/buntimeConfiguration via env vars or a .env file in the execution directory:
RUNTIME_WORKER_DIRS=/apps RUNTIME_PLUGIN_DIRS=/plugins ./dist/buntimeComparison:
| Feature | Dev | Bundle | Compiled | Docker |
|---|---|---|---|---|
| Hot reload | Yes | No | No | Yes (dev profile) |
| Requires Bun | Yes | Yes | No | No |
| Size | — | ~1.5 MB + Bun | ~130 MB | ~132 MB |
| Core plugins | node_modules | Embedded | Embedded | Embedded |
Docker Compose
Section titled “Docker Compose”Two profiles: dev (hot reload, source mounted) and prod (compiled binary).
# Hot reload with source mounteddocker-compose --profile dev up
# Production imagedocker-compose --profile prod up
# Force rebuilddocker-compose --profile dev up --build
# Backgrounddocker-compose --profile dev up -d
# Logsdocker-compose --profile dev logs -f buntime
# Shell into containerdocker exec -it buntime sh
# Stop and remove volumesdocker-compose --profile dev down -vDev profile volumes
Section titled “Dev profile volumes”| Container | Local | Purpose |
|---|---|---|
/build/packages | ./packages | Source hot reload |
/build/apps | ./apps | Source hot reload |
/build/plugins | ./plugins | Source hot reload |
/data/.apps | ./apps | Core apps (image symlink) |
/data/.plugins | ./plugins | Core plugins |
/data/apps | ${RUNTIME_WORKER_DIRS} or ./tmp/apps | External apps |
/data/plugins | ${RUNTIME_PLUGIN_DIRS} or ./tmp/plugins | External plugins |
Dev profile variables
Section titled “Dev profile variables”NODE_ENV: developmentPORT: 8000RUNTIME_API_PREFIX: /_RUNTIME_LOG_LEVEL: debugRUNTIME_PLUGIN_DIRS: /data/.plugins:/data/pluginsRUNTIME_WORKER_DIRS: /data/.apps:/data/appsRUNTIME_POOL_SIZE: 10DATABASE_LIBSQL_URL: http://libsql:8080GATEWAY_SHELL_DIR: /data/apps/example-spaLibSQL service
Section titled “LibSQL service”Runtime dependency (the Turso/LibSQL integration points to http://libsql:8080):
| Port | Use |
|---|---|
8880:8080 | HTTP API |
8881:5001 | gRPC (replication) |
SQLD_DISABLE_AUTH: "true" — dev only. In production, use a token via DATABASE_LIBSQL_AUTH_TOKEN or LIBSQL_TOKEN.
Troubleshooting
Section titled “Troubleshooting”Container fails to start
Section titled “Container fails to start”docker-compose --profile dev logs buntimelsof -i :8000 # check if the port is in useLibSQL unreachable
Section titled “LibSQL unreachable”docker-compose --profile dev pscurl http://localhost:8880/healthHot reload not triggering
Section titled “Hot reload not triggering”- Confirm that volumes under
/build/*are mounted - Confirm
NODE_ENV=development - On macOS/Windows with Docker Desktop, the file watcher may be limited by
inotify— restart the service
Permissions (Linux)
Section titled “Permissions (Linux)”sudo chown -R $USER:$USER ./tmpExternal plugin not showing up
Section titled “External plugin not showing up”Symptom: plugin does not appear in GET /api/plugins. Common causes:
dist/plugin.jsdoes not exist — runbun run buildinside the pluginmanifest.yamlis missing or has nonamefieldRUNTIME_PLUGIN_DIRSis pointing to the individual plugin instead of its parent- Build was updated but the runtime was not restarted
FRONT_MANAGER_API is required
Section titled “FRONT_MANAGER_API is required”The plugin-resource-tenant plugin is fatal if this env var is not set. Define it in the root .env or disable the plugin (enabled: false in manifest.yaml).
Systemd (running the compiled binary on a VM)
Section titled “Systemd (running the compiled binary on a VM)”[Unit]Description=Buntime RuntimeAfter=network.target
[Service]Type=simpleUser=buntimeGroup=buntimeWorkingDirectory=/opt/buntimeExecStart=/opt/buntime/buntimeRestart=alwaysRestartSec=5Environment=PORT=8000Environment=RUNTIME_WORKER_DIRS=/opt/buntime/appsEnvironment=RUNTIME_LOG_LEVEL=info
[Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable --now buntimesudo systemctl status buntime