← Back to list

Swagger in NestJS — And Why Scalar Is the Upgrade Your API Docs Deserve

If you’re building APIs with NestJS, you’re probably using Swagger. And you should be. It gives you automatic OpenAPI generation, type…

Silversky Technology · 2026-03-02 06:08 · 210 claps · 3.8 min read
#nestjs #swagger #scalar #javascript #web-development
Open on Medium ↗
Wiki topics: 🌐 · Web Development

Swagger in NestJS — And Why Scalar Is the Upgrade Your API Docs Deserve

If you’re building APIs with NestJS, you’re probably using Swagger. And you should be. It gives you automatic OpenAPI generation, type safety, and zero YAML maintenance.

But here’s the shift more teams are realizing in 2026:

Your API documentation isn’t an internal tool. It’s a product surface.

And that’s where Swagger UI starts to show friction.

When Swagger UI Starts to Feel Heavy

Swagger itself is excellent at generating OpenAPI specs.

Swagger UI? It works. But at scale, it often becomes:

  • Visually dense
  • Slower with large schemas
  • Overloaded for partner-facing APIs
  • Harder to brand cleanly
  • Cluttered for public developer portals

In a recent internal project (~300 endpoints, ~60 DTOs):

OpenAPI schema size: 1.3MB
Swagger UI initial load (dev): ~1.8s
Scalar initial load: ~900ms

The raw numbers aren’t the story. The cognitive load is.

When documentation becomes external-facing, presentation matters.

That’s where Scalar comes in.

The Architecture That Actually Makes Sense

Instead of replacing Swagger, you separate responsibilities:

  • NestJS → Application structure
  • Swagger → OpenAPI contract generation
  • Scalar → Documentation presentation layer

Swagger generates. Scalar presents.

No duplication. No spec rewrites. No YAML.

Swagger in NestJS: The Foundation

NestJS integrates seamlessly with @nestjs/swagger.

You document directly in your controllers:

@Get(':id')
@ApiParam({
  name: 'id',
  description: 'The ID of the post',
  example: '1',
})
async findOne(@Param('id') id: string) {}

And in your DTOs:

export class CreatePostDto {
  @ApiProperty({ example: 'Understanding NestJS' })
  title: string;
  @ApiProperty({ example: 'Deep dive into controllers and providers.' })
  content: string;
}

What you get:

  • Strongly typed contracts
  • Automatic OpenAPI generation
  • Zero manual schema maintenance
  • Documentation that stays in sync with code

This is the right way to generate specs.

Now let’s upgrade how they’re rendered.

Installing Swagger + Scalar

Install both:

npm install --save @nestjs/swagger @scalar/nestjs-api-reference

No custom build tooling. No spec transformation layer.

Step 1: Generate the Swagger Document

const config = new DocumentBuilder()
  .setTitle('Demo API')
  .setDescription('API documentation for Demo Service')
  .setVersion('1.0')
  .addTag('demo')
  .build();

const documentFactory = () =>
  SwaggerModule.createDocument(app, config);

At this stage:

  • The OpenAPI contract exists
  • Metadata is defined
  • Nothing is rendered yet

Step 2: Disable Swagger UI (Intentionally)

SwaggerModule.setup('api', app, documentFactory, {
  swaggerUiEnabled: false,
});

Why disable it?

In production, exposing Swagger UI:

  • Adds unnecessary static assets
  • Encourages interactive calls against live systems
  • Increases automated scanning surface
  • Makes branding harder

If docs are public-facing, presentation becomes a deliberate decision.

Step 3: Serve Scalar Instead

const scalarHandler = apiReference({
  pageTitle: 'Demo API Reference',
  content: documentFactory(),
});

app.use('/api', (req, res, next) => {
  if (req.path === '/' || req.path === '') {
    return scalarHandler(req, res);
  }
  return next();
});

What’s happening here?

  • Scalar consumes the same OpenAPI document
  • No spec transformation
  • No duplicated annotations
  • No Scalar-specific decorators

Result:

/api → Scalar API Reference

Same routes. Same decorators. Cleaner presentation.

Why Scalar Improves the Developer Experience

The difference isn’t feature count. It’s cognitive load.

Scalar improves:

  • Typography and layout clarity
  • Endpoint grouping readability
  • Dark mode consistency
  • Initial load performance on larger schemas
  • Overall visual minimalism

Swagger UI prioritizes completeness.

Scalar prioritizes readability.

If your API is external-facing, that distinction matters.

What Breaks If You Ignore This?

If your OpenAPI spec grows beyond ~1MB or exceeds a few hundred routes:

  • Load times increase
  • Scanning tools hit exposed UIs
  • Public docs feel internal
  • Partner onboarding slows down

Documentation becomes friction.

And friction becomes support tickets.

When You Should Adopt This Setup

Strong Fit

  • Public APIs
  • Developer platforms
  • SaaS products with partner integrations
  • APIs embedded in SDK ecosystems
  • Teams that care about branding

Probably Overkill

  • Small internal microservices
  • CRUD-only admin APIs
  • Teams under 3 engineers

If your API is internal-only, Swagger UI is perfectly sufficient.

Be honest about your scale.

Extending the Setup

Once Scalar is in place, you can:

1. Drive Docs Through DTOs

Use @ApiProperty() aggressively. Your request/response schemas become self-documenting.

2. Define Auth Once

Add Bearer or JWT configuration globally via DocumentBuilder.

3. Version Your API

Expose /api/v1, /api/v2 with separate OpenAPI documents.

Scalar doesn’t care. It just renders what Swagger generates.

Decision Matrix

The decision isn’t technical. It’s product-facing.

The Real Insight

The mistake teams make is coupling generation and presentation.

Swagger is exceptional at generating contracts from code.

But documentation rendering is a UX decision.

Separate those concerns.

You’ll move faster, present better, and avoid rewriting specs later.

Portable Heuristics

  • Generate your OpenAPI spec as close to code as possible.
  • Treat API documentation as a product surface.
  • Separate contract generation from presentation.
  • If docs are public, optimize for cognitive load — not feature count.
  • If your schema exceeds ~1MB, measure load times.

Final Thoughts

If you’re already using Swagger in NestJS, adding Scalar requires no architectural change.

You continue generating your OpenAPI spec the same way. You don’t rewrite controllers. You don’t maintain separate documentation.

You simply replace the UI layer.

For internal-only services, Swagger UI is sufficient. For public or partner-facing APIs, separating generation from presentation is a practical improvement that reduces cognitive load and improves perceived quality.

Adopt it when documentation becomes customer-facing. Ignore it when it doesn’t.

If you found this guide useful, consider sharing it with your team or bookmarking it for your next deployment.

We regularly write about backend architecture, DevOps practices, and building reliable production systems. Follow us for more engineering deep dives and practical guides from the field.

Brought to you by Suman Samanta from the Silversky Technology crew. Curious what else we’re building? Explore more at silverskytechnology.com.


메타데이터
post_id
d2d3370e04c6
slug
swagger-in-nestjs-and-why-scalar-is-the-upgrade-your-api-docs-deserve-d2d3370e04c6
url
https://medium.com/@silverskytechnology/swagger-in-nestjs-and-why-scalar-is-the-upgrade-your-api-docs-deserve-d2d3370e04c6
canonical_url
https://medium.com/@silverskytechnology/swagger-in-nestjs-and-why-scalar-is-the-upgrade-your-api-docs-deserve-d2d3370e04c6
author_url
https://medium.com/@silverskytechnology
status
ok
fetched_at
2026-07-13 21:33:00