Encore is a backend development platform that uses static analysis to understand your code and automatically provisions infrastructure — databases, queues, cron jobs, and APIs — from type definitions alone.
Why Encore Matters
Backend development is 20% business logic and 80% infrastructure glue: setting up databases, writing API boilerplate, configuring queues, managing secrets. Encore eliminates the glue.
What you get for free:
- Declare APIs, databases, and queues as code — Encore provisions them
- Automatic API documentation (OpenAPI)
- Built-in distributed tracing and structured logging
- Local development dashboard with service catalog
- Deploy to your own AWS/GCP with
encore deploy - TypeScript (encore.ts) and Go (encore.go) SDKs
Quick Start
# Install
curl -fsSL https://encore.dev/install.sh | bash
# Create project
encore app create my-app --template=ts
cd my-app
# Run locally (with dashboard)
encore run
# Deploy
encore deploy
Define an API (TypeScript)
import { api } from "encore.dev/api";
interface CreateUserParams {
name: string;
email: string;
}
interface User {
id: number;
name: string;
email: string;
createdAt: string;
}
// This IS your API endpoint — no router, no middleware, no boilerplate
export const createUser = api(
{ method: "POST", path: "/users", expose: true },
async (params: CreateUserParams): Promise<User> => {
const user = await db.insert(params);
return user;
}
);
export const getUser = api(
{ method: "GET", path: "/users/:id", expose: true },
async ({ id }: { id: number }): Promise<User> => {
return await db.findById(id);
}
);
Databases (Zero Config)
import { SQLDatabase } from "encore.dev/storage/sqldb";
// Declare database — Encore creates it automatically
const db = new SQLDatabase("users", {
migrations: "./migrations",
});
// Use it
const user = await db.queryRow<User>(
"SELECT * FROM users WHERE id = $1",
id
);
Pub/Sub (Built-in)
import { Topic, Subscription } from "encore.dev/pubsub";
// Declare topic
const signups = new Topic<{ userId: number; email: string }>("signups", {
deliveryGuarantee: "at-least-once",
});
// Publish
await signups.publish({ userId: 123, email: "alice@example.com" });
// Subscribe
const _ = new Subscription(signups, "send-welcome", {
handler: async (event) => {
await sendWelcomeEmail(event.email);
},
});
Cron Jobs
import { CronJob } from "encore.dev/cron";
// Runs every hour — Encore handles scheduling
const cleanup = new CronJob("cleanup", {
title: "Clean expired sessions",
schedule: "0 * * * *",
endpoint: cleanExpiredSessions,
});
export const cleanExpiredSessions = api(
{ method: "POST", path: "/internal/cleanup" },
async () => {
const deleted = await db.exec(
"DELETE FROM sessions WHERE expires_at < NOW()"
);
return { deleted: deleted.rowCount };
}
);
Boilerplate Comparison
| Feature | Express.js | Encore |
|---|---|---|
| API endpoint | 15 lines | 5 lines |
| Database setup | Manual config | Declare + auto |
| Pub/Sub | External service | Built-in |
| Cron jobs | node-cron + config | 3 lines |
| API docs | swagger-jsdoc | Automatic |
| Tracing | OpenTelemetry setup | Built-in |
Useful Links
Building backend data services? Check out my developer tools on Apify for ready-made web scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)