# Local development

URL: https://docs.domainruntime.dev/docs/environments/local-development
Status: Planned
Reviewed: 2026-09-23



<div className="docs-note">
  **Planned for public use.**

   Runs against production since 2026-09-22; public once the CLI is on npm.
</div>

Your code is local; your development environment is in the cloud. `druntime` connects the two.

```bash
druntime
```

1. Signs you in, once, and picks your organization.
2. Reuses your development environment, or creates a project named after your app and a personal environment in it the first time.
3. Starts or reattaches to the machine that runs your action code.
4. Writes `DOMAIN_RUNTIME_URL` and the environment's public configuration into `.env.local`, between `# BEGIN DomainRuntime development` markers, leaving your own variables alone.
5. Publishes your domain.
6. Starts the clients listed in `.domainruntime/dev.json`, with the environment configured.
7. Watches your domain and republishes on every save.

## While it runs [#while-it-runs]

| Key |                                                             |
| --- | ----------------------------------------------------------- |
| `p` | publish now                                                 |
| `r` | restart your clients                                        |
| `q` | stop your clients and detach; the environment keeps running |

A save that fails to compile leaves the previous version serving. Fix it and save again. An unchanged build is not re-uploaded.

## Without the live session [#without-the-live-session]

```bash
druntime env open --once     # publish and exit, without starting your clients
npm run dev
druntime push                # after each domain change
druntime env stop            # stop the environment's machine; data is kept
```

For agents and CI, add `--json` for structured output and pass `--env` so nothing is guessed:

```bash
druntime --env=dev-orders-alice-7f3k9x2m --once --json
```

## Several clients [#several-clients]

```json title=".domainruntime/dev.json"
{
  "name": "orders",
  "domain": "domain/src/index.ts",
  "clients": [
    { "name": "web", "cwd": "apps/web", "command": ["pnpm", "run", "dev"] },
    { "name": "android", "cwd": "apps/mobile", "command": ["pnpm", "run", "android"] }
  ]
}
```

`druntime` starts each command and supplies the environment's URL. Emulators and SDKs are your project's; `druntime` only supervises the process.

## One environment, one workspace [#one-environment-one-workspace]

A development environment follows the folder that opened it. Running `druntime` from another checkout does not silently take it over; pick another environment or stop the first session.

## What is the same as production [#what-is-the-same-as-production]

Development runs your actions the way production does:

* Actions run **as the caller**: `runtime.auth` is the signed-in user (or `admin` for a service key), and permission rules apply to their reads and writes.
* Publishing applies your schema with the same rules, refusals and confirmations. See [Changing the schema](/docs/data/modeling-data#changing-the-schema).
* Executions are admitted, recorded and retried by request id the same way.

## What is different [#what-is-different]

* Workflow actions are not available in development yet: a domain with a `"use workflow"` action is refused at push with `development_workflow_adapter_unavailable`. Test them in a production release.
* Action traces and the execution timeline are production-only; in development, `console.log` output stays in the machine's logs.

## Limits [#limits]

The machine stops after 30 minutes with no `druntime` attached and lives at most 7.9 hours. The next save or `druntime` starts a new one and republishes your code; your data is untouched. An organization runs at most two development machines at a time. Development environments refuse production targets, even with `--prod`.
