[data-reveal]{opacity:1!important;transform:none!important}
dev
Frontend

dev

Run the dashboard with hot reload against a backend on the same machine, and what each kind of edit reloads.

ajs dms dev serves the dashboard with hot reload. It reads the frontend modules in place, from the backend's own directories, so the backend runs on the same machine.

$ ajs dms dev --help
Usage: ajs dms dev [options]

Run the dev server with hot reload. It reads the frontend modules in place, from
the backend's own directories, so the backend runs on this machine.

Options:
  -b, --backend-url <url>      Backend URL; when omitted, discovered from the
                               enclosing antelope project's .antelope/dev.json
                               (env: DMS_API_BASE_URL)
  -p, --port <port>            Port to serve on (default: "3001", env: PORT)
  -f, --force                  Reinstall the workspace dependencies
  --offline                    Reuse the last cached manifest instead of
                               fetching it (env: DMS_OFFLINE)
  --bootstrap-secret <secret>  Credential for the backend's layer endpoints;
                               prefer the variable, a command line is visible to
                               other processes. Discovered from
                               .antelope/dms-dev.json for the project's own
                               backend (env: DMS_BOOTSTRAP_SECRET)
  -h, --help                   Show help for a command

Finding the backend

Without -b or DMS_API_BASE_URL, dev walks up from the current directory to the first .antelope/dev.json, the file a running ajs project dev writes. It checks that the process that wrote it is still alive, then reads the API server's address from it. It stops at the first file it finds, so it never attaches to a parent project's backend.

$ ajs dms dev
✖ No backend URL provided and no running antelope project found
  Searched for .antelope/dev.json from the current directory upward.
  → Run this command inside an antelope project started with 'ajs project dev'
  → Or pass the backend explicitly with -b <url> (env: DMS_API_BASE_URL)

The bootstrap credential comes the same way: when the backend it calls is the one .antelope/dev.json names, dev reads the credential the development backend publishes in .antelope/dms-dev.json. A credential found this way is never sent to any other backend. An explicit --bootstrap-secret or DMS_BOOTSTRAP_SECRET always wins.

A discovered backend keys the workspace on the project directory, not on the URL, so it survives the backend landing on another port. ajs dms dev -b <url> keys it on the URL instead, and shares it with build and start for that URL. See Workspaces and cache.

The port

dev reserves its port before it asks the backend for the manifest, and sends the resulting address to the development backend, which serves a matching client URL and allows that origin. When the port is busy, dev moves to the next free one and says so: Port 3001 is busy, using 3002. -p 0 asks for any free port.

The server listens on 127.0.0.1 unless HOST says otherwise. HOST=0.0.0.0 opens it to the network.

Sessions and secrets

dev generates a random session secret when DMS_SESSION_SECRET is not set at all, so every restart signs everyone out. A value you set is kept, but an empty value or one shorter than 32 characters is refused. Cookies are not Secure unless DMS_COOKIE_SECURE says so, since the development server runs over HTTP.

The e-mail render and OAuth relay secrets come from the manifest the backend serves; the Secrets line of the ready block says where each one came from, never its value. A variable you set wins over the manifest. See Configuration.

What reloads, and how

dev copies each module into the workspace and watches its sources, mirroring every edit.

You changeWhat happens
A .vue file, a composable, a styleVite hot module replacement
A component a layer registersThe next server render sets every module up again, into empty registries, so it uses the edited component without a restart
i18n/locales/*.jsonThe merged catalogs are regenerated; the open page applies them in place. Adding or removing a locale reloads the page.
app/app.config.tsThe next server render uses it; the open page updates useDmsAppConfig() and Nuxt UI's config in place
A file under public/Served, or no longer served, at once
Adding or removing dms.frontend.ts or app/config/shortcuts-registry.tsThe module loader or the aggregated shortcuts are regenerated, and the page reloads
dms.frontend.build.tsVite restarts
dms.server.ts or a file it importsThe next request uses the edited handler
An e-mail templateThe e-mail bundle rebuilds in a separate, low-priority process; a render waits for a build in progress
A layer directory added to or removed from layers/The dev server says it needs a restart: Vite reads layer aliases and auto-imported directories at startup only

When the backend starts serving another set of frontend modules, because a module was installed or removed from the Modules page, dev stops the server, rebuilds the workspace and starts again:

ℹ Frontend modules changed on the backend: rebuilding the workspace

When the backend is down

dev falls back to the last manifest it cached for the workspace, with a warning, and API calls fail until the backend is back. --offline uses the cache without trying the backend. A refused credential never falls back: the cache can hold private options from an earlier authorized run.

Seeing who answers a path

In development, every answer carries an x-dms-route-owner header: renderer, module:<id>, backend:<pattern>, page or not-found.

$ curl -sI http://localhost:3005/api/dms/nothing | grep x-dms-route-owner
x-dms-route-owner: backend:/api/**

See Routing and the backend proxy for the order the server follows.

Stopping

Ctrl+C stops the server and exits with code 130:

■ Stopped the dev server · ran 3.2s