Skip to content

Dev Mode & Storage

The dev backend is opt-in: pass mode=dev on the bare command line (or deviceMode: false in code) for auth off and a fixed port 8080. Without it the runtime keeps the device defaults (auth on, ephemeral port), whatever else is passed. For a stateful consumer app (photos persisted across restarts) you also need storage:

import { createWorkletRuntime, resolveCliConfig } from '@ekrooh/bare/runtime';
// bare app.js mode=dev origin=http://localhost:5173 storage=./.store cache=./.cache
const config = resolveCliConfig(); // parses labeled bare CLI tokens
const runtime = createWorkletRuntime(config);

With mode=dev, resolveCliConfig() returns a dev-mode WorkletRuntimeOptions — auth off, fixed port 8080, no handoff. That’s the CLI equivalent of the hand-rolled options object:

import { createWorkletRuntime } from '@ekrooh/bare/runtime';
const runtime = createWorkletRuntime({
deviceMode: false, // the dev backend: auth off, port 8080
storage: './.justus-store', // durable app-sandbox dir
cache: './.justus-cache', // ephemeral
allowedOrigins: ['http://localhost:5173'], // the Vite dev server
});

What you get and what to watch for:

  • deviceMode defaults to true. Only an explicit deviceMode: false (or mode=dev) turns auth off; passing or omitting storage does not change it. auth: false without deviceMode: false throws.
  • Auth off is not an open server: requests must still target the bound loopback server, and a page Origin must be the server itself or listed in allowedOrigins, so another site open in the same browser cannot drive the dev backend.
  • With auth: false, no handoff.json is written even though storage is set — the handoff file is a host artifact, and a dev backend must not leave a stale one behind.
  • The canonical default plugin set is registered automatically. Add your own plugins with the plugins option instead of mutating the registry after creation:
import type { PluginManifest } from '@ekrooh/bare/core';
import { createWorkletRuntime } from '@ekrooh/bare/runtime';
declare const photosPlugin: PluginManifest; // your app.photos manifest
const runtime = createWorkletRuntime({
deviceMode: false,
storage: './.justus-store',
cache: './.justus-cache',
plugins: [photosPlugin], // your app.photos manifest
});

pluginRegistry remains reachable on the runtime if you need to register dynamically.

Anything your backend writes under storage (hyperdrive cores, photo metadata) survives restarts because you passed a real directory. cache is for spool/temp. The same dirs map 1:1 to the [webAssets, storage, cache] Bare.argv triple the host passes on device — so dev and device stay config-identical.