Skip to content

feat(dev): prisma dev --detach returns once every service answers and leaves the app running - #363

Merged
wmadden-electric merged 13 commits into
mainfrom
feat/dev-detach
Oct 15, 2026
Merged

wmadden-electric merged 13 commits into
mainfrom
feat/dev-detach

Conversation

@wmadden-electric

@wmadden-electric wmadden-electric commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Linked issue

n/a. Part of the local-dev work; the plan is in .drive/projects/emulator-commands/.

Summary

prisma dev --detach brings the app up, waits until every service answers, prints the URLs, and returns:

$ prisma dev module.ts --detach
dev: ready
gateway: http://localhost:3001
quotes: http://localhost:3000
$ curl http://localhost:3001       # same terminal; the app keeps running
$ prisma dev stop                  # stops it

Decision: prisma dev stays in the foreground by default. It watches your build output, redeploys on change, and stops the app on Ctrl-C, exactly as before. Running the app in the background is opt-in with --detach. ADR-0053 records this.

Why

Agents and scripts don't want a long-running foreground process. Today they have to background prisma dev themselves and watch its output for "ready". With --detach, the exit code answers the question:

  • 0: every service answers.
  • Non-zero: the start failed, and the same error is printed as in the foreground.

The app then runs until prisma dev stop.

What --detach does

A detached run goes through the same steps as prisma dev up to "ready". It deploys the app to the local emulators, Composer's local stand-ins for Prisma Cloud. It then waits until every service accepts connections, because the emulator reports a service as running only once its port answers. Then it returns.

It starts no file watcher and doesn't stop the app on exit. The dev operation in @prisma/composer/control takes the same detach option. The session it returns is already closed, and its stop() does nothing.

When something goes wrong

  • A detached run that fails before ready stops the app. That includes an app an earlier --detach left running, because a failed redeploy has already replaced that service's old process. The docs say so, and tell you to fix the build and run --detach again.
  • Ctrl-C before ready stops the app and exits 130.
  • --detach combines with --fresh and --name.

Testing performed

  • Unit tests:
    • A detached run never starts the file watcher and never stops a service.
    • The command exits 0 with the URLs.
    • Ctrl-C before ready stops the app.
  • test/integration/test/local-dev-detach.integration.ts, which runs the installed prisma binary against real emulators in a temporary directory:
    • --detach exits 0, and both services still answer afterwards.
    • Stopping the app closes every service and database port.
    • A detached run that fails during deployment leaves no port open.
    • Its services use ports from 3200 up, so other local servers can't affect the result.
  • The CLI tests, pnpm build, typecheck, the lints, the docs checks, and the local-dev integration scripts, each run on its own.

Checklist

  • All commits are signed off (git commit -s) per the DCO. The DCO status check will block merge if any commit is missing a Signed-off-by: trailer.
  • I read CONTRIBUTING.md and the change is scoped to one logical concern.
  • The PR title is a conventional commit (feat, fix, chore, docs, refactor, test, build) — PR titles drive the auto-generated release notes.
  • Tests are updated (or n/a if the change is doc-only / refactor with no behavioural delta).

Notes for the reviewer

Alternatives considered

  • Background by default, with --watch for the foreground loop. Simpler for agents, but against prior art: Docker Compose (up -d --wait), .NET Aspire (run --detach), Laravel Sail (up -d) and Prisma ORM's own prisma dev --detach all default to the foreground. The ORM's prisma dev ships in the same prisma binary, so the two would contradict each other.
  • A separate prisma dev start. It reads naturally next to dev stop, but it adds a second spelling of the run command. --detach is the name the ORM's prisma dev and Docker already use.

Agent: attila-51

🤖 Generated with Claude Code

wmadden-electric and others added 6 commits October 15, 2026 16:23
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…s it running

The `dev` operation takes `detach`. A detached run converges, waits until
every service accepts connections, reports the front door, and returns a
session that is already closed: no watch loop, and stop() stops nothing.
The app keeps running on the emulators until `prisma dev stop` or the next
`prisma dev` in the directory.

`prisma dev --detach` renders it and exits 0. A failure before ready
stops what the run started, as the foreground path does. A Ctrl-C before
ready stops the app through the devStop operation and settles 130.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Runs the installed `prisma` host against the local-dev fixture with a
temporary emulators directory. `prisma dev --detach` exits 0 once every
service answers and both services still answer after it exits. Stopping
the app then closes every service and database port; the host does not
mount `prisma dev stop` yet, so the script calls the devStop operation the
command renders. With the Compute emulator restarted on a one-millisecond
readiness timeout, a detached run fails before ready and leaves no port
of the app open. The target's own teardown deletes the app's instances
and data at the end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The ADR that records dev url, dev stop and emulator list now also records
--detach: what it does, why the foreground stays the default, the prior
art (Docker Compose, .NET Aspire, Laravel Sail, Prisma ORM's prisma dev),
and detached-by-default and a run-then-stop mode as alternatives.
local-dev.md describes the app's process lifetime in both modes. The
running-locally guide and the core-concepts skill tell agents, scripts and
CI to use --detach and then prisma dev stop. The run-then-stop mode is
recorded in deferred.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…scripts

A detached run that fails before ready stops the whole app, including one
an earlier --detach left running: a failed redeploy has already replaced
that service's old process, so the previous app cannot be kept. The guide,
the skill, local-dev.md and ADR-0053 now say so, and say to fix the build
and run `prisma dev --detach` again.

local-dev.md no longer calls a detached mode a later extension and lists
--detach among dev's flags. ADR-0041 gets an amendment note, and the
index's note on ADR-0050 mentions --detach. The guide says `prisma dev
stop` is how to stop an app started with --detach. The --detach flag brief
says to use it in scripts, agents and CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…he emulators to exit

Both port checks now require the record to hold a service port and a
database port before asserting none accepts connections, so an empty
record can no longer pass them. Ending an emulator waits until its process
has exited, with a SIGKILL after five seconds, so it cannot write into the
temporary directory after the script removes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@prisma-gizmo

prisma-gizmo Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

✅ Gizmo reviewed d456f13 — posted 0 inline comment(s) this pass.

Open findings: none

Change walkthrough

This incremental delta layers release 0.30.0 bookkeeping, an emulator-behavior doc amendment, and integration-test hardening on top of the already-reviewed prisma dev --detach feature.

Emulator docs (docs/design/10-domains/local-dev.md). The readiness and concurrency sections now describe what compute-main.ts implements: listens: false is recorded in the artifact's compute.manifest.json and honored per deployment; readiness probes loopback on both 127.0.0.1 and ::1 every 50 ms (--ready-poll-ms exists but the CLI never passes it); and a start whose process has already exited is no longer joined by a concurrent resume or redeploy — the newcomer starts the service again, matching joinableStart's processExited check.

Skill and version bumps (skills/prisma-composer-core-concepts/SKILL.md, test/integration/package.json, website). The 0.29.1 → 0.30.0 bump is consistent across the public packages, integration tests, and website, and the alchemy pin moves to 2.0.0-beta.83, matching composer's dependency and the lockfile. The skill's new paragraph on node-address identity (logicalId on Branch, rename/id/module changes creating new entities and deleting database or bucket data) restates the same rule added to the deploying guide, so the two docs agree.

Integration tests. local-dev-detach.integration.ts and the sibling control.dev-current.test.ts now throw a descriptive error when creating a placeholder instance in the emulator's admin API returns a non-2xx status. Previously such a response would surface later as a confusing missing-port parse failure; the guard keeps the success path reading the body exactly once and applies the same pattern in both tests.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 100811e9-5ed1-4bb4-a81b-5c876a8f3b43
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@prisma/composer@363
npm i https://pkg.pr.new/@prisma/composer-cli@363
npm i https://pkg.pr.new/@prisma/composer-prisma-cloud@363

commit: 9112f57

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟡 1 minor · trace

Comment thread test/integration/test/local-dev-detach.integration.ts Outdated
wmadden-electric and others added 3 commits October 15, 2026 16:50
…arses its output

The local-dev scripts read the front door from `prisma dev`'s piped
output, relying on a piped stdout being NDJSON. That stops being true
once a pipe gets plain data lines and JSON only with --json. The detach,
criteria 4 and 5, and store scripts now pass --json and parse only the
status and endpoint frames; their comments say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The proof asserts a service's port is closed after the app stops, which
failed once when something else on the machine bound port 3000. Before
the first run the script now starts the Compute emulator and fills every
port below 3200 with placeholder instances, which the emulator keeps
across its restart in part 3, so the fixture's services get 3200 and up.
Both closed-port checks assert the service ports are at or above 3200.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟡 1 minor · trace

Comment thread test/integration/test/local-dev-detach.integration.ts
wmadden-electric and others added 3 commits October 15, 2026 17:50
Brings in #353's start fixes and tests, the readiness tests' own ports, main, and the placeholder check in the dev url test. No conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…of at its cause

reserveServicePortsBelow read .port from any response to POST /instances. It now throws with the emulator's status and body when creating a placeholder fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Brings in #353's own port range for the readiness tests; the test file keeps the instance-keyed version. No other changes.

Signed-off-by: Will Madden <madden@prisma.io>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: none · trace

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Gizmo finding is open and the head commit has been reviewed. Approving.

Base automatically changed from feat/emulator-commands to main October 15, 2026 19:35
Signed-off-by: Will Madden <madden@prisma.io>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Gizmo finding is open and the head commit has been reviewed. Approving.

@wmadden-electric
wmadden-electric merged commit 089bfcb into main Oct 15, 2026
23 checks passed
@wmadden-electric
wmadden-electric deleted the feat/dev-detach branch October 15, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants