Express OpenAPI Framework
express-openapi is an unopinionated framework designed to integrate OpenAPI (formerly Swagger) specifications into Express.js applications. It currently supports OpenAPI versions 2.0 and 3.0. The library prioritizes performance and extensive testing, aiming to keep development as close to native Express patterns as possible while providing robust API documentation and validation capabilities. It achieves its features, such as parameter defaults, type coercion, request/response validation, and security handling, by leveraging a suite of modular `openapi-*` packages. The current stable version is 12.1.3. While not explicitly stating a release cadence, its version history suggests active development. Key differentiators include its flexible, unobtrusive design, comprehensive middleware configuration via vendor extensions, and the ability to maintain API documentation in sync with application code.
Common errors
-
SyntaxError: Invalid regular expression: /^\/v2\/users\((?: ...
cause An incompatibility between a newer version of the `glob` dependency and `express-openapi`'s path parsing logic, particularly with nested route directory names.fixAdd `"resolutions": { "glob": "7.x.x" }` (for Yarn) or `"overrides": { "glob": "7.x.x" }` (for npm) to your `package.json` to force an older, compatible version of `glob`. -
HTTP 400 Bad Request or validation errors on API calls.
cause The incoming request body, parameters, or headers do not conform to the rules defined in your OpenAPI specification (`apiDoc`) for the requested endpoint.fixReview the exact validation error messages (often available in the response body or server logs). Adjust the client request to match the API's OpenAPI definition, or update the `apiDoc` if the specification is incorrect. -
Cannot GET /api-docs (or other configured Swagger UI path)
cause Swagger UI is not correctly initialized, the `docsPath` in `express-openapi.initialize` does not match the path used to serve Swagger UI, or the `apiDoc` is invalid or missing required `info` fields.fixEnsure `initialize({ ..., docsPath: '/your-docs-path' })` matches `app.use('/your-docs-path', swaggerUi.serve, swaggerUi.setup(apiDoc));`. Verify `apiDoc` is a valid OpenAPI document with at least `info` and `openapi` fields.
Warnings
- breaking Express.js 5 introduces significant changes to path matching via `path-to-regexp` (v8.x vs v0.x), which `express-openapi` relies on. Migrating an Express 4 application to Express 5 might cause unexpected routing behavior or `SyntaxError: Invalid regular expression` if path patterns are not updated.
- gotcha When using `express-openapi` with nested routes or complex file structures, an older version of the `glob` dependency (prior to v8) can cause `SyntaxError: Invalid regular expression` errors during initialization due to changes in how `glob` handles paths.
- breaking Upgrading your OpenAPI specification from 2.0 to 3.0, or from 3.0 to 3.1 (when supported by `express-openapi`), can introduce breaking changes to your API contract. `express-openapi` itself supports both 2.0 and 3.0, but changes in your API definition (e.g., parameter locations, schema structure, nullable types in 3.1) can break existing clients.
- gotcha Configuration of middleware (e.g., coercion, validation, defaults) can be done via vendor extensions like `x-express-openapi-disable-middleware`, `x-express-openapi-additional-middleware`. While powerful, these extensions are specific to `express-openapi` and their behavior or availability might evolve across major versions, potentially requiring adjustments to your `apiDoc` configuration.
Install
-
npm install express-openapi -
yarn add express-openapi -
pnpm add express-openapi
Imports
- initialize
const openapi = require('express-openapi'); const initialize = openapi.initialize;import { initialize } from 'express-openapi'; - OpenApiApp
import type { OpenApiApp } from 'express-openapi';
Quickstart
import express from 'express';
import { initialize } from 'express-openapi';
import * as swaggerUi from 'swagger-ui-express';
const app = express();
const PORT = process.env.PORT ?? 3000;
// Basic API Document - OpenAPI 3.0
const apiDoc = {
openapi: '3.0.0',
info: {
title: 'My Simple API',
version: '1.0.0',
description: 'A simple API with Express and OpenAPI'
},
paths: {
'/hello': {
get: {
summary: 'Responds with a greeting',
responses: {
'200': {
description: 'Successful response',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
message: { type: 'string' }
}
}
}
}
}
}
}
}
}
};
// Create a dummy 'operations' object for the path handler
const operations = {
get: (req: express.Request, res: express.Response) => {
res.status(200).json({ message: 'Hello, OpenAPI!' });
}
};
initialize({
app,
apiDoc,
paths: [
{
path: '/hello',
module: operations
}
],
docsPath: '/api-docs' // Path where Swagger UI will be served
});
// Serve Swagger UI
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(apiDoc as swaggerUi.JsonObject));
// Start the Express server
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
console.log(`Swagger UI available at http://localhost:${PORT}/api-docs`);
console.log(`API endpoint at http://localhost:${PORT}/hello`);
});