Encore is a backend framework with built-in infrastructure. Express is a minimal HTTP router. Encore works with any framework, and your existing Express routes can run inside it with infrastructure from code in your own cloud on AWS or GCP, local infrastructure, tracing and type-safe service calls.
Updated November 5, 2026
“What used to take days or weeks of back-and-forth between developers and infra teams is now automated and completed in minutes.”
Plain Express plus Terraform and Docker, next to Encore.
| What it is | Backend framework with built-in infrastructure | Minimal HTTP router and middleware |
| Existing Express code | Runs inside a raw endpoint | Native |
| Request validation | From TypeScript types | Add a library such as zod or joi |
| Infrastructure | Infrastructure from code in your own cloud | Terraform, Docker and CI you write |
| Resources | Postgres, Pub/Sub, cron, buckets, cache, secrets | Separate services and client libraries |
| Local development | encore run starts local infra | Docker Compose you maintain |
| Tracing | Built in, locally and in the cloud | Add OpenTelemetry yourself |
| Service calls | Type-safe function calls | HTTP clients you keep in sync |
| Ecosystem | Smaller, and npm packages such as Express still work | Very large middleware ecosystem |
With plain Express, most of the time goes into the Terraform, Dockerfiles, Compose files, CI pipelines and tracing setup around the router. Encore sets those up from your application code, in your own AWS or GCP account.
Install the CLI and add Encore to your project as the migration guide describes. Then mount your Express app behind a raw endpoint with a catch-all path. Every route you already have keeps working, now started with encore run.
Tested with encore.dev 1.58.8, Express 5.3.0 and TypeScript 5.9.3.
brew install encoredev/tap/encore && encore app createimport { api, RawRequest, RawResponse } from "encore.dev/api";
import express, { request, response } from "express";
Object.setPrototypeOf(request, RawRequest.prototype);
Object.setPrototypeOf(response, RawResponse.prototype);
const app = express();
app.get("/health", (_req, res) => {
res.send("ok");
});
// Your existing Express routes keep working behind one raw endpoint.
export const expressApp = api.raw(
{ expose: true, method: "*", path: "/!rest" },
app,
);import { api } from "encore.dev/api";
import { SQLDatabase } from "encore.dev/storage/sqldb";
const db = new SQLDatabase("users", { migrations: "./migrations" });
interface User {
id: number;
email: string;
}
// Moved out of Express: typed request and response, traced automatically.
export const getUser = api(
{ expose: true, method: "GET", path: "/users/:id" },
async ({ id }: { id: number }): Promise<User> => {
const user = await db.queryRow<User>`SELECT id, email FROM users WHERE id = ${id}`;
if (!user) throw new Error("user not found");
return user;
},
);The request is validated against the TypeScript types, the call is traced, and the endpoint shows up in the generated API docs and clients. The database declared in the same file runs locally with encore run and becomes RDS or Cloud SQL in your own cloud when you deploy.
The same works for the rest of what an Express app usually reaches for: cron jobs instead of a node-cron process, buckets instead of hand-wired S3 clients, and secrets set with encore secret set --type prod instead of .env files on a server.
With Express, tracing means adding OpenTelemetry, instrumenting your database and HTTP clients, and running a backend to send traces to. Encore traces every API call, database query and Pub/Sub operation, locally and in the cloud. Routes still inside the raw endpoint do not get the full tracing detail.
See the tracing docs →"It's like a combination of Express and Heroku. You define infrastructure in your code and it's automatically spun up for you. You can go from zero to a deployed service on GCP in an hour."
Pick Encore when your backend needs more than a router: a database, background jobs, queues, file storage, several services that call each other, and environments in your own AWS or GCP account. You keep your Express code while you move over.
Pick plain Express for a small single service where you already have hosting and a deploy pipeline that works, when you rely heavily on Express middleware, or when your team already maintains Terraform and Docker for everything else and only needs an HTTP layer. Express is stable, well known and has a very large middleware ecosystem.
Start with a forklift migration: run the whole Express app inside one raw endpoint. Then move routes to Encore APIs one by one.
The guide covers the forklift approach and a feature-by-feature migration for APIs, databases, cron jobs, middleware and auth.
Read the Express migration guide"Encore is our foundation for all new development. Since adopting it, we've seen a 3x increase in development speed and 90% shorter project lead times."
"Encore lets us go from idea to shipped product at least 3x faster and saves us hours of devops work every week."
"We've reduced time spent on DevOps by 95%, and we're now on track to save $60K annually in cloud costs."
"Encore is an unfair advantage. At Pave we've moved 2x faster than we did at Monzo."
"We're saving $200k+ annually compared to additional hiring. The ROI is outstanding, easily 10x."
"You define infrastructure in your code and it's automatically spun up for you. You can go from zero to a deployed service on GCP in an hour. I don't know how else to do it."
"Encore's inferred infrastructure has allowed us to move at unprecedented speed. Combined with database branching in Neon, we're able to spin ephemeral environments up and down with incredible ease. Stakeholders love preview app URLs."
Common questions about Encore vs Express.
Yes. Mount your Express app behind a raw endpoint with a catch-all path, and your routes keep working while you run them with encore run. You can then move routes to typed Encore APIs one at a time. Until a route is moved, Encore cannot trace it in detail or include it in generated API clients.
Not for the resources Encore covers. Databases, Pub/Sub topics, cron jobs, object storage buckets, caches and secrets are declared in code and provisioned in your own cloud on AWS or GCP when you deploy. If you want to run somewhere else, encore build docker produces an image you can deploy to any container host.
Inside the raw endpoint, yes, because Express is still handling those requests. For routes you move to Encore APIs, you use Encore middleware and auth handlers instead.
Pick plain Express for a small single service where you already have hosting and a deploy pipeline you are happy with, when you depend on a large set of Express middleware, or when you only need an HTTP router and nothing else.
With Express, one service calls another over HTTP with a client you write and keep in sync. With Encore, you import the other service and call its endpoint like a function. The request and response types are checked at compile time, and each call shows up in the trace.
Deploy to your own AWS or GCP account, with infrastructure provisioned automatically.