swagger-ui-express

Serves interactive Swagger UI API documentation directly from your Express app based on a Swagger/OpenAPI JSON or YAML document.

Library
npm
v5.0.1
1,495 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
48 /100 Fair
Development Activity 0
Maintenance 20
Community 72
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
64 /100 Good
Architecture 68
Code Quality 62
Innovation 40
Learning Curve 85

swagger-ui-express is a small piece of Express middleware that renders the Swagger UI single-page app inside your own server, bound to a Swagger/OpenAPI document you supply. Instead of hosting a separate static docs site, you mount it on a route (commonly /api-docs) and it serves the same interactive, explorable documentation UI that swagger.io uses, styled and driven by whatever spec your app produces.

The spec can come from a static JSON file, a dynamically generated object (for example from swagger-jsdoc), a remote URL, or even be computed per-request by attaching it to req.swaggerDoc. The library ships extensive customization hooks — custom CSS (inline or via URL), custom JavaScript (inline or via URL), custom page titles, favicon overrides, robots meta tags, and OAuth/API-key preauthorization — so the hosted docs page can be made to match a product’s branding rather than looking like generic tooling.

Because the actual rendering is handled by the versioned swagger-ui-dist package, swagger-ui-express stays a thin, focused wrapper: its job is templating the HTML shell, serving the static Swagger UI assets, and wiring options through to the client-side SwaggerUIBundle call. This keeps the middleware itself tiny while still exposing nearly all of Swagger UI’s underlying configuration surface to Express developers.

What You Get

  • serve + setup(swaggerDoc, opts) middleware pair to mount interactive API docs on any Express route
  • Support for static JSON specs, dynamically generated specs (e.g. from swagger-jsdoc), or specs loaded from a remote URL
  • Per-request spec support via req.swaggerDoc, so different documentation can be served to different callers
  • Custom CSS, custom JS (inline or external URL), custom page title, and custom favicon options for branding the docs page
  • A dropdown “explorer” mode for switching between multiple Swagger documents from one page
  • OAuth and API-key preauthorization hooks (customOptions.oauth, customOptions.preauthorizeApiKey) so testers don’t have to manually authenticate every session
  • serveFiles/serveWithOptions variants for hosting two or more independent Swagger UI instances from the same app

Common Use Cases

  • Hosting living API documentation for an Express-based REST API directly from the same process that serves the API
  • Pairing with swagger-jsdoc to generate the OpenAPI spec from JSDoc comments and immediately render it as browsable docs
  • Exposing a /api-docs endpoint internal teams and API consumers can use to try requests via the built-in “Authorize” and “Try it out” UI
  • Serving two versions of an API (e.g. /v1/api-docs and /v2/api-docs) with distinct Swagger documents via serveFiles
  • Preauthorizing a documentation page with an API key or OAuth token so internal reviewers don’t re-enter credentials

Under The Hood

Architecture

The module is a single index.js file built around one core function, generateHTML, which takes a Swagger document plus an options bag and does pure string templating: it substitutes placeholders (<% customCss %>, <% favIconString %>, <% title %>, and so on) into an HTML template string and a companion JS template string that ultimately calls SwaggerUIBundle in the browser. setup() wraps this in an Express handler that re-renders per-request when req.swaggerDoc is present (letting different requests see different specs), while serve/serveFiles compose that handler with express.static pointed at swagger-ui-dist’s asset directory (getAbsoluteSwaggerFsPath()). There is no class hierarchy, router, or plugin system — the entire surface area is a handful of exported functions operating on plain objects, which keeps the blast radius of a spec/options change limited to the templating layer itself.

Tech Stack

The library targets Node’s CommonJS module system and Express (>=4.0.0 as a peer dependency, with 5.x beta also declared compatible), with swagger-ui-dist as its one runtime dependency for the actual Swagger UI static bundle. Development tooling is Mocha for the test runner, nyc/istanbul-badges-readme for coverage, and Puppeteer to drive a real headless Chromium instance against a small Express testapp fixture for integration-style assertions rather than mocking the browser layer. CI is configured via a legacy .travis.yml targeting Node 8 and 10, which is older than the package’s stated >= v0.10.32 engines field and likely predates the project’s more recent 5.x releases.

Code Quality

Testing is integration-first: test/test.spec.js boots a real Express server backed by test/testapp/app.js, launches Puppeteer, and asserts against rendered DOM selectors (.information-container, .swagger-ui, auth-button lock state) rather than unit-testing generateHTML in isolation. This gives strong end-to-end confidence that the shipped HTML/JS actually renders correctly in a browser, at some cost to fast, isolated coverage of individual option combinations. The source itself uses plain var declarations, informal legacy-JS style (matching its 2016 origins), and no TypeScript types; error handling is minimal since the module does no I/O beyond serving static files and templating strings, so there is little that can throw at runtime. There is no linter configuration in the repo.

API Design The public API is small and pragmatic: serve + setup(doc, opts) covers the common case in two lines, while power users reach for serveFiles, serveWithOptions, or generateHTML directly for multi-spec or fully custom setups. Options are a single flat object (explorer, customCss, customJs, swaggerOptions, customSiteTitle, etc.) documented thoroughly in the README with runnable examples for every variant, which keeps the learning curve low even though the options surface itself is fairly large. The one legacy wrinkle is setup’s positional-arguments overload (opts, options, customCss, customfavIcon, swaggerUrl, customSiteTitle as separate parameters) kept alongside the newer single-options-object form for backward compatibility, which is undocumented as deprecated but still present in the function signature.

Used by 16 apps in this directory

TypeScript
92%
Other

n8n

Automation · No Code Platforms

208,437

Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.

View details
95
Repo Health
87
Technical
62
Dependency
Built with
TypeScript 92%
Updated 6 days ago
TypeScript
98%
Other

Novu

Developer Tools

40,195

Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.

View details
93
Repo Health
80
Technical
64
Dependency
Built with
TypeScript 98%
Updated 5 days ago
TypeScript
99%
AGPL 3.0

Pangolin

Networking

23,187

An open-source, identity-based zero-trust remote access platform built on WireGuard — a self-hostable alternative to Cloudflare Tunnel and Twingate with SSO, OIDC, and tunneled reverse proxying.

View details
87
Repo Health
68
Technical
68
Dependency
Built with
TypeScript 99%
Updated 6 days ago
TypeScript
96%
Apache 2.0

Pezzo

AI Development · Monitoring

3,278

Open-source LLMOps platform for prompt management, AI observability, intelligent caching, and real-time cost tracking across LLM providers.

View details
59
Repo Health
75
Technical
66
Dependency
Built with
TypeScript 96%
Updated 2 months ago
TypeScript
97%
Other

Rocket.Chat

Team Chat

46,304

The secure, self-hosted team communications platform for organizations that cannot compromise on data sovereignty.

View details
96
Repo Health
79
Technical
63
Dependency
Built with
TypeScript 97%
Updated 5 days ago
TypeScript
98%
Apache 2.0

Tianji

Analytics · Monitoring

3,119

Replace Google Analytics, UptimeKuma, and Prometheus with one self-hosted platform that tracks websites, monitors uptime, and reports server health.

View details
86
Repo Health
76
Technical
64
Dependency
Built with
TypeScript 98%
Updated 6 days ago
TypeScript
72%
AGPL 3.0

Worklenz

Collaboration · Product Management · Project Management

3,259

All-in-one open source project management for teams who want full control — plan projects, track tasks, manage resources, and monitor finances without the SaaS lock-in.

View details
87
Repo Health
7
Technical
64
Dependency
Built with
TypeScript 72%
JavaScript 21%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers