Replit Deployments: Separate Build and Runtime for Production
A Replit deployment is a build artifact, not a copy of your editor session. How the build command, run command, and secrets scope differ — and how to verify the runtime is truly separate.
31 Dec 2025, 07:17 UTC

If your Replit project only runs while the editor tab is open, you do not have a deployed app — you have a development session with a public URL attached. Replit Deployments exists to close that gap: it builds and runs your project in a production runtime that is separate from the editor repl, so the published URL stays reachable after you close the workspace.
The useful mental model is that a deployment is a build artifact, not a copy of your editor session. Everything that makes the app work in the editor — installed dependencies, environment variables, the command that starts the server — has to be expressed again in terms the deployment runtime understands. That is where the practical decisions live.
What the deployment profile actually controls
When you open the Deployments section of a Replit project, you select a deployment profile, and the platform uses it to decide how the production container is assembled. Two pieces matter most:
- Build command — runs once to produce the artifact the runtime will serve, such as compiling TypeScript, bundling a client, or running a migration step.
- Run command — the long-lived process that listens for traffic. It should bind to the host and port the platform expects, not to a hardcoded localhost port.
Because the production runtime is isolated, edits you make in the editor are not live on the deployed URL. You have to trigger a new deployment for changes to appear. That is a feature rather than a bug: a half-finished edit cannot break the published site.
Worked example: a TypeScript server with a build step
Suppose the project is a small Express API written in TypeScript. In the Replit Shell, the package.json needs scripts the deployment profile can call:
{
"name": "example-api",
"type": "module",
"scripts": {
"build": "tsc",
"start": "node dist/server.js"
},
"dependencies": {
"express": "^4.19.2"
},
"devDependencies": {
"typescript": "^5.5.4"
}
}In the Deployments UI, set the build command to npm run build and the run command to npm start. The build step runs in the production environment, so anything the build needs — including devDependencies such as TypeScript — must be installable there. If your build tooling is listed only as a dev dependency and the deployment installs production dependencies only, expect a command-not-found style failure rather than a message that names the missing package.
Secrets are the second half of the example. A database URL or API key added under the editor repl's secrets is not automatically present in the deployment. Add it to the deployment's environment scope as well, then redeploy. The expected check is that the app reads the production value, not the development one. A quick way to confirm is to log a non-sensitive identifier derived from the variable, such as the database hostname, at startup and read it in the deployment logs.
Where editor and deployment drift apart
Two environments means two chances to disagree. The common failure modes:
- Secret drift. A key rotates in the editor but not in the deployment, so the published app starts returning auth errors while development looks fine.
- Lockfile drift. The editor repl resolves dependencies at run time; the deployment installs from whatever the build step sees. A dependency added in the editor but never reflected in the lockfile can be missing in production.
- Port assumptions. Code that hardcodes a port works in the editor and fails health checks in the container.
None of these are exotic. They are the ordinary cost of having a real production environment, and they are worth paying, because keeping an editor session alive to serve traffic is not a deployment strategy.
Verifying that the separation is real
Run these checks in the Replit UI and Shell, in order. They confirm behavior rather than assume it:
- Open the project and confirm a Deployments section or tab exists. Availability and limits are plan-dependent, so the controls you see may differ from another account's.
- Trigger a deployment and watch the deployment logs. They are separate from the editor console output; if you only see editor output, you are reading the wrong pane.
- Once the deployment reports active, stop the editor repl. Reload the deployed URL. It should still respond — that is the point of the isolated runtime.
- Compare the secrets and variables scopes for the repl and for the deployment. Confirm the production values are the ones you intend.
- Change a string in the editor, reload the deployed URL without redeploying, and confirm the old value is still served. Then redeploy and confirm the new value appears.
If step 3 fails, the deployment is not actually independent of the editor, and the rest of the configuration is worth re-checking before you rely on it.
Limits to keep in mind
Deployment options, machine sizes, and always-on behavior vary by account tier and change over time. Replit also updates its build system and platform defaults, which can change how a project is packaged between one deployment and the next. Treat the profile settings as configuration you own and re-verify after platform updates, rather than as a one-time setup. If a deployment behaves differently than described here, the deployment logs and the current UI are the authoritative source — not a blog post.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.