npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

next-swagger-doc

v0.5.0

Published

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

Readme

Welcome to next-swagger-doc 👋

All Contributors

Version Downloads/week Prerequisite Documentation License: MIT Twitter: jellydn

Generate Swagger JSON API from NextJS Api Routes

If you enjoy working with next-swagger-doc, you will love next-validations: NextJS API Validations, support Zod, Yup, Fastest-Validator, Joi, and more

🏠 Homepage

Demo

Prerequisites

  • Nextjs >= 9
  • Node >= 18

Motivation

This package reads your JSDoc-annotated source code on NextJS API route and generates an OpenAPI (Swagger) specification.

nextjs + swagger-jsdoc = next-swagger-doc

Install

yarn add next-swagger-doc

Usage #1: next-swagger-doc with Next.js 13

To incorporate next-swagger-doc with your Next.js 13 project, follow these steps. This setup will generate Swagger documentation for your API based on your code and provide a built-in Swagger UI for viewing the documentation.

1. Create Swagger Spec

Next, create a new file lib/swagger.ts. This file uses the next-swagger-doc library to create a Swagger specification based on the API routes in your Next.js project.

import { createSwaggerSpec } from "next-swagger-doc";

export const getApiDocs = async () => {
  const spec = createSwaggerSpec({
    apiFolder: "app/api", // define api folder under app folder
    definition: {
      openapi: "3.0.0",
      info: {
        title: "Next Swagger API Example",
        version: "1.0",
      },
      components: {
        securitySchemes: {
          BearerAuth: {
            type: "http",
            scheme: "bearer",
            bearerFormat: "JWT",
          },
        },
      },
      security: [],
    },
  });
  return spec;
};

2. Create Swagger UI Component

Generate a new file named app/api-doc/react-swagger.tsx. In this file, create and export a React component that utilizes the swagger-ui-react library to render the Swagger UI according to the provided specification.

For demonstration purposes, here is an example using swagger-ui-react

Feel free to employ any alternative swagger UI library, such as stoplightio/elements or Scalar. I have added an example using Stoplight Elements in the example folder.

Load swagger-ui-react on the client only. Next.js enables React Strict Mode by default, and swagger-ui-react still uses UNSAFE_componentWillReceiveProps in components such as ExamplesSelect and ParameterRow. That warning comes from Swagger UI, not this library.

'use client';

import dynamic from 'next/dynamic';
import 'swagger-ui-react/swagger-ui.css';

const SwaggerUI = dynamic(() => import('swagger-ui-react'), { ssr: false });

type Props = {
  spec: Record<string, unknown>,
};

function ReactSwagger({ spec }: Props) {
  return <SwaggerUI spec={spec} />;
}

export default ReactSwagger;

3. Create API Documentation Page

Create a new file app/api-doc/page.tsx. This page imports the Swagger spec and the Swagger UI component to display the Swagger documentation.

import { getApiDocs } from "@/lib/swagger";
import ReactSwagger from "./react-swagger";

export default async function IndexPage() {
  const spec = await getApiDocs();
  return (
    <section className="container">
      <ReactSwagger spec={spec} />
    </section>
  );
}

4. Add Swagger Comment to API Route

Lastly, add a Swagger comment to your API route in app/api/hello/route.ts. This comment includes metadata about the API endpoint which will be read by next-swagger-doc and included in the Swagger spec.

/**
 * @swagger
 * /api/hello:
 *   get:
 *     description: Returns the hello world
 *     responses:
 *       200:
 *         description: Hello World!
 */
export async function GET(_request: Request) {
  // Do whatever you want
  return new Response('Hello World!', {
    status: 200,
  });
}

Automatic App Router Documentation

Set autoDoc: true to generate basic operations for App Router route.ts files. The path is derived from the route directory, dynamic segments such as [id] become {id}, and exported HTTP handlers such as GET and POST become operations. Generated operations include a default successful response; use a manual @swagger block when an endpoint needs request, response, or other operation metadata. Manual operations take precedence over generated ones.

const spec = createSwaggerSpec({
  apiFolder: 'app/api',
  autoDoc: true,
  definition: {
    openapi: '3.0.0',
    info: { title: 'My API', version: '1.0.0' },
  },
});

Now, navigate to localhost:3000/api-doc (or wherever you host your Next.js application), and you should see the swagger UI.

https://gyazo.com/6bfa919c4969b000615df6bb9cabcd02.gif

Vercel builds

createSwaggerSpec does not glob .next during next build. Walking that folder while Next.js is compiling it can fail Vercel with ENOENT: .next/export-detail.json. Source API files and public OpenAPI files are scanned instead. Set scanBuildOutput: true only when you intentionally want compiled .next/server files included.

Next.js standalone output

output: 'standalone' copies a minimal server. Source app/api files are not included, so scanning routes at runtime yields an empty spec.

Generate the document at build time and load it from public/ (copied into the standalone output):

npx next-swagger-doc-cli next-swagger-doc.json --output public/swagger.json
const spec = createSwaggerSpec({
  specFile: 'public/swagger.json',
  apiFolder: 'app/api',
  autoDoc: true,
  definition: {
    openapi: '3.0.0',
    info: { title: 'Next Swagger API Example', version: '1.0' },
  },
});

If specFile is missing at runtime, autoDoc still documents compiled route.js handlers under .next/server (paths and methods only; JSDoc comments are stripped from compiled output). You can also set outputFile to write the spec when source files are present.

swagger-ui-react Strict Mode warning

React may log UNSAFE_componentWillReceiveProps for ExamplesSelect and ParameterRow. Those components live in swagger-ui-react, which this package does not depend on. Next.js turns Strict Mode on by default.

Workarounds:

  • Render Swagger UI with next/dynamic(..., { ssr: false }) as shown in Usage #1
  • Switch the viewer to Scalar or Stoplight Elements
  • Ignore the warning until Swagger UI drops the unsafe lifecycles

Usage #2: Create an single API document

yarn add next-swagger-doc swagger-ui-react
  • Create an live swagger page, e.g: pages/api-doc.tsx
import { GetStaticProps, InferGetStaticPropsType } from 'next';
import { createSwaggerSpec } from 'next-swagger-doc';
import dynamic from 'next/dynamic';
import 'swagger-ui-react/swagger-ui.css';

const SwaggerUI = dynamic<{
  spec: any;
}>(import('swagger-ui-react'), { ssr: false });

function ApiDoc({ spec }: InferGetStaticPropsType<typeof getStaticProps>) {
  return <SwaggerUI spec={spec} />;
}

export const getStaticProps: GetStaticProps = async () => {
  const spec: Record<string, any> = createSwaggerSpec({
    apiFolder: 'pages/api' // or 'src/pages/api',
    definition: {
      openapi: '3.0.0',
      info: {
        title: 'Next Swagger API Example',
        version: '1.0',
      },
    },
  });

  return {
    props: {
      spec,
    },
  };
};

export default ApiDoc;

https://gyazo.com/af250bab0d07f931c596ebc8c955ae2e.gif

Usage #3: Use NextJS API route to create Swagger JSON spec

  • Step 1: Create an api route on nextjs, e.g: pages/api/doc.ts
import { withSwagger } from "next-swagger-doc";

const swaggerHandler = withSwagger({
  definition: {
    openapi: "3.0.0",
    info: {
      title: "NextJS Swagger",
      version: "0.1.0",
    },
  },
  apiFolder: "pages/api",
});
export default swaggerHandler();
  • Step 2: Add JSdoc to any NextJS API routes, for example: pages/api/hello.ts
import { NextApiRequest, NextApiResponse } from "next";

/**
 * @swagger
 * /api/hello:
 *   get:
 *     description: Returns the hello world
 *     responses:
 *       200:
 *         description: hello world
 */
const handler = (_req: NextApiRequest, res: NextApiResponse) => {
  res.status(200).json({
    result: "hello world",
  });
};

export default handler;
  • Step 3: Access the Swagger API doc

https://gyazo.com/0bcf45f0e15778a5cb851b40526324f3.gif

Usage #4: Generate Swagger file from CLI

  • Step 1: create a JSON config file as next-swagger-doc.json
{
  "apiFolder": "pages/api",
  "schemaFolders": ["models"],
  "definition": {
    "openapi": "3.0.0",
    "info": {
      "title": "Next Swagger API Example",
      "version": "1.0"
    }
  }
}
  • Step 2: run cli for generating swagger file
yarn next-swagger-doc-cli next-swagger-doc.json

Run example app

Versioned sample apps live under examples/:

  • examples/next13-simple — Next.js 13 (Pages Router)
  • examples/next14-app — Next.js 14 (App Router)
  • examples/next15-app — Next.js 15 (App Router)
  • examples/next16-app — Next.js 16 (App Router)
gh repo clone jellydn/next-swagger-doc
cd examples/next16-app
pnpm install
pnpm dev

Then open http://localhost:3000/api-doc or http://localhost:3000/ on your browser ./example-screenshot.png

Linter

In order to set an eslint rule that checks that all the APIs actually have a swagger JsDoc description we can use the following settings:

Install the JsDoc eslint plugin:

yarn add -D eslint-plugin-jsdoc

Create the custom rule in your eslint configuration file:

{
    //...your configuration
    "overrides": [
        //...your overrides
        {
            // Force the setting of a swagger description on each api endpoint
            "files": ["pages/api/**/*.ts"],
            "plugins": ["jsdoc"],
            "rules": {
                "jsdoc/no-missing-syntax": [
                "error",
                {
                    "contexts": [
                    {
                        "comment": "JsdocBlock:has(JsdocTag[tag=swagger])",
                        "context": "any",
                        "message": "@swagger documentation is required on each API. Check this out for syntax info: https://github.com/jellydn/next-swagger-doc"
                    }
                    ]
                }
            ]
        }
    ]
}

Pre-commit hook

This project uses pre-commit to enforce code quality. To install pre-commit hooks, run:

pre-commit install

Author

👤 Huynh Duc Dung

Stargazers

Stargazers repo roster for @jellydn/next-swagger-doc

Show your support

kofi paypal buymeacoffee

Give a ⭐️ if this project helped you!

Contributors ✨

Thanks goes to these wonderful people (emoji key):

This project follows the all-contributors specification. Contributions of any kind welcome!