# Quick overview This guide shows a practical path to get a Node + TypeScript Express API running on Railway fast, with a clear upgrade path to add a separate worker service for background jobs. It focuses on the minimal code, the Railway project setup, essential environment variables, and operational tips for small teams or solo projects.
# What you start with
package.json scripts should include at least:
- "build": "tsc"
- "start": "node dist/index.js"
- "dev": "tsx src/index.ts" (local development convenience)
Railway will set PORT for you, so don't rely on a hardcoded port in production.
# Railway project setup
- 1If your repo is a monorepo, point Railway at the correct root directory.
- 2In the service settings, set the Build command to your build script (npm run build / pnpm / yarn) and the Start command to npm run start.
Watch the first deploy logs. The process will confirm the app is listening on the PORT Railway provides.
# Environment variables and secrets Add at least these environment variables in Railway service settings:
- NODE_ENV=production
- DATABASE_URL (if your app uses a database)
- JWT_SECRET or other app secrets
Do not commit a.env file. If you paste secrets into a shared place, rotate them.
# Public URL & health check
# Adding a worker service (recommended for background jobs) When you need background processing (BullMQ, Redis-based queues):
- Create a second Railway service in the same project that points to the same repo.
- Use the same build step, but change the Start command to run your worker (for example, node dist/worker.js).
- Provision Redis as a plugin/add-on or use an external Redis instance and share the connection URL via environment variables.
- Set memory limits and a restart policy for the worker. Constrain concurrency so a burst of jobs won't OOM the process.
Separating web and worker avoids a stuck job taking down your HTTP service.
# Cost and operational mindset for solo/small teams Start with the smallest viable setup and watch the usage dashboard after 24 hours. Keep the web and worker services separate so failure domains are isolated. Set memory limits and restart policies before assuming you need to optimize code for performance.
# Wrap-up Ship a simple health check first. Deploy the web service, confirm the public URL responds, then add a worker service with its own start command and Redis. Keep secrets in Railway env vars and monitor the usage dashboard.