# The NestJS stack we would set up today

> Source: https://learn-nestjs.com/tools/
> Part of Learn NestJS, free to read.

Nest's opinionated structure means there is much less to decide than in a bare Node project. What is left is the data layer, validation, config and deployment.

:::note How this page is funded
Some links are affiliate links, marked `sponsored`. We earn a commission if you buy; it costs you nothing and does not buy placement.
:::

## Database

**Prisma** for most projects. The generated types are the best in the ecosystem, migrations are straightforward, and the Nest integration is a fifteen-line service — see [database access and testing](/database-and-testing/).

**TypeORM** if you want decorator-based entities that match Nest's own style, or you need something Prisma does not support. It is the more established Nest pairing and the documentation reflects that.

**Drizzle** if you want SQL-shaped queries with full type inference and no code generation step. Growing quickly and a good fit for teams that prefer writing SQL.

Pick one. A codebase with two data-access layers is a codebase where nobody knows which one a given query uses.

## Validation and config

**`class-validator` + `class-transformer`** is the built-in path, and Nest's `ValidationPipe` is designed around it. Always with `whitelist: true` — see [DTOs and validation](/dto-and-validation/) for why that specific option prevents mass assignment.

**`nestjs-zod`** if you prefer schemas to decorators. One schema gives you both runtime validation and the static type, which removes the drift between DTO and interface.

**`@nestjs/config` with a schema.** Validate environment variables at boot. An application that fails to start on a missing variable is much better than one that fails at 2am on the first request that needs it.

```ts
ConfigModule.forRoot({
  validate: (env) => EnvSchema.parse(env),
  isGlobal: true,
})
```

## Testing

Jest ships with Nest and the `@nestjs/testing` module is built around it. There is no strong reason to switch.

The setup that matters:

- Unit tests with `overrideProvider` for anything crossing the network — must stay under ten seconds.
- End-to-end tests with `supertest` against a real application instance, database in a transaction per test.
- Remember to register your global pipes in the test setup. `main.ts` does not run.

## Observability

**`nestjs-pino`** for structured logging with request correlation. Nest's built-in logger is fine for development and not enough for production.

**OpenTelemetry** for tracing. In a framework built on dependency injection and interceptors, adding tracing is genuinely a few lines, and distributed traces are the fastest way to find where a request actually spent its time.

## Hosting

:::promo digitalocean
:::

App Platform detects a Node project, builds it and gives you TLS. Managed Postgres alongside it means one bill and no networking to configure. This is the least-effort production setup for a Nest API.

:::promo hetzner
:::

If you would rather run a Docker container on your own box, Hetzner is materially cheaper for the same resources.

Whichever you choose: `app.enableShutdownHooks()` and a real health check endpoint. Without shutdown hooks, redeploys leak database connections.

## Editor

:::promo jetbrains
:::

WebStorm's understanding of decorators and dependency injection is meaningfully better than the default VS Code experience — it can actually resolve what a token injects. VS Code plus the Nest extensions is free and perfectly workable.

## Learning

:::promo frontendmasters
:::

For the TypeScript underneath Nest. Most Nest confusion turns out to be TypeScript confusion — generics, decorators, structural typing — and that is where to fix it.

## What to skip

- **A second HTTP framework inside Nest.** If you are reaching for raw Express middleware often, you are fighting the framework.
- **Custom decorators, early.** They are powerful and they make code harder for a new reader (or an agent) to follow. Earn them.
- **Microservices, early.** Nest makes them easy, which is a trap. A modular monolith with clear module boundaries is the right shape until it demonstrably is not.
- **GraphQL by default.** Excellent when you need it, and a large amount of machinery when you do not.

## Common questions

### Prisma or TypeORM with Nest?

Prisma for the type inference and the migration workflow; TypeORM if you want entity decorators that match Nest's style throughout. Both are well supported. The wrong answer is both.

### Should I use microservices?

Not at first. Nest's module system already gives you the boundaries that make a monolith maintainable, and you can extract a module into a service later with far less pain than merging services back together.

### Express or Fastify adapter?

Express by default — larger middleware ecosystem, more examples. Switch to Fastify if a benchmark tells you to; it is close to a one-line change.
