Express evolved: Type-safe routing, elegant transactions, and production-ready patterns for modern Node.js
Due to internal changes in the router used in Express v5 that breaks the ability to generate a full set of routes using the routes
management command and to generate the OpenAPI spec, this library doesn't officially support Express v5. But in most cases if will work just fine as long as you don't rely on these features.
Extremely opinionated set of utilities for cranking out production-ready Node.js apps in a timely manner. We assume you are using PostgreSQL as the main database, Redis for data you don't want in Postgres and Faktory for background jobs.
- Only works with ECMAScript Modules (ESM)
- Thin layer on top of Express with better support for
async
/await
and type safety.
const router = createRouter();
router.put(
'/posts/:id',
{
request: type({ title: 'string' }),
response: type({ id: 'number', title: 'string' }),
},
async (req) => {
await delay(1000);
return {
id: req.params.id,
...req.body,
};
},
);
- Clean graceful shutdown procedures and built-in health checks. Runs perfectly in Kubernetes.
- PostgreSQL with transactions and migrations
bin/dx manage migrate up
await postgres.transaction(() => {
const post = await postgres.get<{ title: string }>(
sql`SELECT title FROM posts WHERE id = ${id} FOR UPDATE`,
);
await postgres.query(
sql`UPDATE posts SET ${sql.spreadUpdate({ title: post.title.split('').reverse().join('') })} WHERE id = ${id}`,
);
try {
// Nested transactions with savepoints
await postgres.transaction(() => {
})
} catch () {
}
throw new Error('please rollback');
});
- CSRF protection
- Built in auth backends! Email+password, passwordless, easy to extend with more
- OpenAPI v3 generator
- Redis
- Slack/Discord client for sending operational notifications
- CLI commands inspired by Django's management commands
bin/dx manage --help
registerManagementCommand((command, cli) => {
command('hello').action(() => {
cli.writeLine('Hello World');
});
});
- Delayed/async jobs with Faktory
- Validation of HTTP requests using Standard Schema, including
jsonSchema()
and arktype. - Logging helpers to write well-formatted contextual JSON logs to
stdout
const logger = getLogger();
logger.info('hello world', { foo: 'bar', baz: 10 });
// {"level":"info","hostname":"machine.local","pid":43149,"name":"default","message":"hello world","foo":"bar","baz":10,"time":"2024-01-02T17:25:28.610Z","v":1}
- Request local context using AsyncLocalStorage (e.g. request ids)
- RFC 7807 Problem Details for HTTP APIs by default
- Uses Sentry for external error monitoring
- The Twelve-Factor App
- Time-to-market and top-notch developer experience.
- Support for multiple different database vendors and job processing systems.
See the example/ folder for a complete example.
Put environment variables in .env
at the application will automatically read those on startup. For test configuration in unit and integrations tests, use .env.test
.