celld dev, from celld, the Judt runtime, on port 3000. The dev server runs the same Worker code that production runs, with its own data. Use it to test each change before you deploy.
Before you begin
To follow these steps, you need a way to run commands in the App’s sandbox, such as the in-product agent, the API, or the MCP server. The sandbox starts when a request needs it. The platform starts the dev server when the sandbox starts. The first start runsnpm ci and the build, so it can take some seconds.
If the dev server stops, for example after a crash or a failed npm ci or build script, then nothing starts it again until the next preview request. Until then, curl to port 3000 gets “connection refused”. If the start failed, then the preview request reports the failure and doesn’t start the dev server again until a file changes.
To send a preview request, use the in-product agent’s preview tool, the MCP server’s create_preview tool, or POST /api/apps/{id}/preview. For more information about sandboxes and preview URLs, see Sandbox.
How the dev server starts
When the dev server starts, it prepares the App the way that a deploy does, and then it serves the App. It does the following, in order:- If the
package-lock.jsonfile differs from the one that the last install used, then it runsnpm ci. Install scripts don’t run. - If the
package.jsonfile has abuildscript, then it runs the script one time. - If the
package.jsonfile has adevscript, then it starts the script and keeps it running beside the dev server. Use thedevscript for a watcher that rebuilds on change, such astsc --watch. - It starts
celld devon port 3000.
node_modules when it stops, so the dev server installs the dependencies again after the sandbox starts. A change to the package.json file takes effect the next time that the dev server starts. You don’t need to restart anything yourself. For more information about the build and dev scripts, see npm packages and builds.
Test a change
1
Check the syntax
In the sandbox, check each module that you changed:If the App has a
build script, run the build instead. node --check checks only the syntax. Node.js can’t run Worker code, so a module that passes the check can still fail on the dev server.2
Send a preview request
Send a preview request before you send other requests. It starts the dev server if it isn’t running, and it waits for the rebuild that your change started. If the build or the start failed, it returns
422 preview_failed with the build’s output. Without this step, curl can get an answer from the previous build.3
Send a request
In the sandbox, request a route from the dev server:To open the App in a browser, use the URL that the preview request returned.
4
Read the logs
If a request fails, read the App’s logs. The dev server’s entries have the
development environment. For more information, see Troubleshoot.Logs and failed builds
The App’s logs collect the following entries from the dev server:- Your code’s output: each
console.*call and each uncaught exception, with theappsource. Production writes the same entries. - The dev server’s own events: builds, reloads, and exits, with the
dev_serversource. Adev.build_failedentry includes the bundler’s report.
422 preview_failed until the App builds again. You can also check the logs for a dev.build_failed entry.
Dev data
The dev server keeps its data in the.celld/dev/ directory. The data stays after the dev server restarts. Dev data and production data are separate.
Commands can’t read the .celld/dev/ directory. To read dev data, send a request to the App.
Generated dev server files
The dev server runs from.judt-dev.json, a copy of the wrangler.json file that the platform keeps. For an App with D1, its main key names .judt-dev.js, which loads your entry module and applies the migrations. Don’t edit or delete these files. If a dev server error names .judt-dev.json, then correct your wrangler.json file.
Test D1 migrations
The dev server applies D1 migrations to the dev database, as a deploy does to production. Each time a build starts to serve, the dev server applies the pending files in themigrations/ directory. A new file applies after the rebuild that it starts. Don’t write code that applies migrations.
If a migration fails, then the preview request fails with preview_failed and the SQL error, and nothing from that file stays. Correct the file, and the next rebuild applies it. A file that the dev server applied doesn’t apply again when you change it, so add a new file. For more information, see D1.
Test a Cron Trigger
The dev server runs Cron Triggers on their schedule, and you can’t start one manually. To test the job, put it in a function, and call the function from a temporary route. Remove the route after the test:index.js
cleanup is the job function, and json is a helper that returns a JSON response.
For more information, see Cron Triggers.
Secrets on the dev server
Your code reads the App’s Secrets asenv.NAME on the dev server, as it does in production. For more information, see Vars and Secrets.