{"id":13479306,"url":"https://github.com/jellydn/next-swagger-doc","last_synced_at":"2025-05-14T13:06:28.269Z","repository":{"id":37006033,"uuid":"364638177","full_name":"jellydn/next-swagger-doc","owner":"jellydn","description":"This package reads your JSDoc-annotated source code on NextJS API route and generates an OpenAPI (Swagger) specification.","archived":false,"fork":false,"pushed_at":"2025-05-04T05:08:46.000Z","size":9465,"stargazers_count":497,"open_issues_count":7,"forks_count":37,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-04T06:18:40.653Z","etag":null,"topics":["hacktoberfest","next-swagger","next-swagger-doc","nextjs","swagger"],"latest_commit_sha":null,"homepage":"https://next-swagger-doc-demo.productsway.com/api-doc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jellydn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["jellydn"],"ko_fi":"dunghd","buy_me_a_coffee":"dunghd","polar":"jellydn"}},"created_at":"2021-05-05T16:21:55.000Z","updated_at":"2025-05-04T00:11:41.000Z","dependencies_parsed_at":"2023-01-17T13:01:24.218Z","dependency_job_id":"d591bf02-a9c2-45c4-9c26-99b7f21c3a29","html_url":"https://github.com/jellydn/next-swagger-doc","commit_stats":{"total_commits":699,"total_committers":15,"mean_commits":46.6,"dds":0.5736766809728183,"last_synced_commit":"8e84f68419f8293bb5f0eae3c6d18e2f725719a3"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jellydn%2Fnext-swagger-doc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jellydn%2Fnext-swagger-doc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jellydn%2Fnext-swagger-doc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jellydn%2Fnext-swagger-doc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jellydn","download_url":"https://codeload.github.com/jellydn/next-swagger-doc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254149953,"owners_count":22022851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","next-swagger","next-swagger-doc","nextjs","swagger"],"created_at":"2024-07-31T16:02:13.249Z","updated_at":"2025-05-14T13:06:28.230Z","avatar_url":"https://github.com/jellydn.png","language":"TypeScript","funding_links":["https://github.com/sponsors/jellydn","https://ko-fi.com/dunghd","https://buymeacoffee.com/dunghd","https://polar.sh/jellydn","https://paypal.me/dunghd","https://www.buymeacoffee.com/dunghd"],"categories":["TypeScript"],"sub_categories":[],"readme":"# Welcome to next-swagger-doc 👋\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n\n[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-)\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\n[![Version](https://img.shields.io/npm/v/next-swagger-doc.svg)](https://npmjs.org/package/next-swagger-doc)\n[![Downloads/week](https://img.shields.io/npm/dw/next-swagger-doc.svg)](https://npmjs.org/package/next-swagger-doc)\n![Prerequisite](https://img.shields.io/badge/node-%3E%3D18-blue.svg)\n[![Documentation](https://img.shields.io/badge/documentation-yes-brightgreen.svg)](http://next-swagger-doc.productsway.com/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](#)\n[![Twitter: jellydn](https://img.shields.io/twitter/follow/jellydn.svg?style=social)](https://twitter.com/jellydn)\n\n\u003e Generate Swagger JSON API from NextJS Api Routes\n\n\u003csub\u003eIf you enjoy working with next-swagger-doc, you will love [next-validations: NextJS API Validations, support Zod, Yup, Fastest-Validator, Joi, and more](https://github.com/jellydn/next-validations)\u003c/sub\u003e\n\n## 🏠 [Homepage](https://next-swagger-doc.productsway.com/)\n\n### ✨ [Demo](https://next-swagger-doc-demo.productsway.com/api-doc)\n\n## Prerequisites\n\n- Nextjs \u003e= 9\n- Node \u003e= 18\n\n## Motivation\n\nThis package reads your JSDoc-annotated source code on [NextJS API route](https://nextjs.org/docs/api-routes/api-middlewares) and generates an OpenAPI (Swagger) specification.\n\n[nextjs](https://nextjs.org) +\n[swagger-jsdoc](https://github.com/Surnet/swagger-jsdoc/blob/v6/docs/README.md) = [next-swagger-doc](https://github.com/jellydn/next-swagger-doc)\n\n## Install\n\n```sh\nyarn add next-swagger-doc\n```\n\n## Usage #1: next-swagger-doc with Next.js 13\n\nTo 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.\n\n### 1. Create Swagger Spec\n\nNext, 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.\n\n```javascript\nimport { createSwaggerSpec } from \"next-swagger-doc\";\n\nexport const getApiDocs = async () =\u003e {\n  const spec = createSwaggerSpec({\n    apiFolder: \"app/api\", // define api folder under app folder\n    definition: {\n      openapi: \"3.0.0\",\n      info: {\n        title: \"Next Swagger API Example\",\n        version: \"1.0\",\n      },\n      components: {\n        securitySchemes: {\n          BearerAuth: {\n            type: \"http\",\n            scheme: \"bearer\",\n            bearerFormat: \"JWT\",\n          },\n        },\n      },\n      security: [],\n    },\n  });\n  return spec;\n};\n```\n\n### 2. Create Swagger UI Component\n\nGenerate 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.\n\nFor demonstration purposes, here is an example using [swagger-ui-react](https://www.npmjs.com/package/swagger-ui-react)\n\nFeel free to employ any alternative swagger UI library, such as [stoplightio/elements](https://github.com/stoplightio/elements). I have added an [example ](https://github.com/jellydn/next-swagger-doc/blob/main/examples/next13-simple/pages/playground.tsx)using this library in the `example` folder.\n\n```javascript\n'use client';\n\nimport SwaggerUI from 'swagger-ui-react';\nimport 'swagger-ui-react/swagger-ui.css';\n\ntype Props = {\n  spec: Record\u003cstring, any\u003e,\n};\n\nfunction ReactSwagger({ spec }: Props) {\n  return \u003cSwaggerUI spec={spec} /\u003e;\n}\n\nexport default ReactSwagger;\n```\n\n### 3. Create API Documentation Page\n\nCreate a new file `app/api-doc/page.tsx`. This page imports the Swagger spec and the Swagger UI component to display the Swagger documentation.\n\n```javascript\nimport { getApiDocs } from \"@/lib/swagger\";\nimport ReactSwagger from \"./react-swagger\";\n\nexport default async function IndexPage() {\n  const spec = await getApiDocs();\n  return (\n    \u003csection className=\"container\"\u003e\n      \u003cReactSwagger spec={spec} /\u003e\n    \u003c/section\u003e\n  );\n}\n```\n\n### 4. Add Swagger Comment to API Route\n\nLastly, 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.\n\n```javascript\n/**\n * @swagger\n * /api/hello:\n *   get:\n *     description: Returns the hello world\n *     responses:\n *       200:\n *         description: Hello World!\n */\nexport async function GET(_request: Request) {\n  // Do whatever you want\n  return new Response('Hello World!', {\n    status: 200,\n  });\n}\n```\n\nNow, navigate to `localhost:3000/api-doc` (or wherever you host your Next.js application), and you should see the swagger UI.\n\n![https://gyazo.com/6bfa919c4969b000615df6bb9cabcd02.gif](https://gyazo.com/6bfa919c4969b000615df6bb9cabcd02.gif)\n\n## Usage #2: Create an single API document\n\n```sh\nyarn add next-swagger-doc swagger-ui-react\n```\n\n- Create an live swagger page, e.g: `pages/api-doc.tsx`\n\n```typescript\nimport { GetStaticProps, InferGetStaticPropsType } from 'next';\nimport { createSwaggerSpec } from 'next-swagger-doc';\nimport dynamic from 'next/dynamic';\nimport 'swagger-ui-react/swagger-ui.css';\n\nconst SwaggerUI = dynamic\u003c{\n  spec: any;\n}\u003e(import('swagger-ui-react'), { ssr: false });\n\nfunction ApiDoc({ spec }: InferGetStaticPropsType\u003ctypeof getStaticProps\u003e) {\n  return \u003cSwaggerUI spec={spec} /\u003e;\n}\n\nexport const getStaticProps: GetStaticProps = async () =\u003e {\n  const spec: Record\u003cstring, any\u003e = createSwaggerSpec({\n    apiFolder: 'pages/api' // or 'src/pages/api',\n    definition: {\n      openapi: '3.0.0',\n      info: {\n        title: 'Next Swagger API Example',\n        version: '1.0',\n      },\n    },\n  });\n\n  return {\n    props: {\n      spec,\n    },\n  };\n};\n\nexport default ApiDoc;\n```\n\n![https://gyazo.com/af250bab0d07f931c596ebc8c955ae2e.gif](https://gyazo.com/af250bab0d07f931c596ebc8c955ae2e.gif)\n\n## Usage #3: Use NextJS API route to create Swagger JSON spec\n\n- Step 1: Create an api route on nextjs, e.g: `pages/api/doc.ts`\n\n```typescript\nimport { withSwagger } from \"next-swagger-doc\";\n\nconst swaggerHandler = withSwagger({\n  definition: {\n    openapi: \"3.0.0\",\n    info: {\n      title: \"NextJS Swagger\",\n      version: \"0.1.0\",\n    },\n  },\n  apiFolder: \"pages/api\",\n});\nexport default swaggerHandler();\n```\n\n- Step 2: Add JSdoc to any NextJS API routes, for example: `pages/api/hello.ts`\n\n```typescript\nimport { NextApiRequest, NextApiResponse } from \"next\";\n\n/**\n * @swagger\n * /api/hello:\n *   get:\n *     description: Returns the hello world\n *     responses:\n *       200:\n *         description: hello world\n */\nconst handler = (_req: NextApiRequest, res: NextApiResponse) =\u003e {\n  res.status(200).json({\n    result: \"hello world\",\n  });\n};\n\nexport default handler;\n```\n\n- Step 3: Access the Swagger API doc\n\n![https://gyazo.com/0bcf45f0e15778a5cb851b40526324f3.gif](https://gyazo.com/0bcf45f0e15778a5cb851b40526324f3.gif)\n\n## Usage #4: Generate Swagger file from CLI\n\n- Step 1: create a JSON config file as `next-swagger-doc.json`\n\n```json\n{\n  \"apiFolder\": \"pages/api\",\n  \"schemaFolders\": [\"models\"],\n  \"definition\": {\n    \"openapi\": \"3.0.0\",\n    \"info\": {\n      \"title\": \"Next Swagger API Example\",\n      \"version\": \"1.0\"\n    }\n  }\n}\n```\n\n- Step 2: run cli for generating swagger file\n\n```sh\nyarn next-swagger-doc-cli next-swagger-doc.json\n```\n\n## Run example app\n\n```sh\ngh repo clone jellydn/next-swagger-doc\ncd examples/next14-app\npnpm install\npnm run dev\n```\n\nThen open http://localhost:3000/api-doc or http://localhost:3000/ on your browser\n![./example-screenshot.png](./example-screenshot.png)\n\n## Linter\n\nIn order to set an eslint rule that checks that all the APIs actually have a swagger JsDoc description we can use the following settings:\n\nInstall the JsDoc eslint plugin:\n\n```sh\nyarn add -D eslint-plugin-jsdoc\n```\n\nCreate the custom rule in your eslint configuration file:\n\n```json\n{\n    //...your configuration\n    \"overrides\": [\n        //...your overrides\n        {\n            // Force the setting of a swagger description on each api endpoint\n            \"files\": [\"pages/api/**/*.ts\"],\n            \"plugins\": [\"jsdoc\"],\n            \"rules\": {\n                \"jsdoc/no-missing-syntax\": [\n                \"error\",\n                {\n                    \"contexts\": [\n                    {\n                        \"comment\": \"JsdocBlock:has(JsdocTag[tag=swagger])\",\n                        \"context\": \"any\",\n                        \"message\": \"@swagger documentation is required on each API. Check this out for syntax info: https://github.com/jellydn/next-swagger-doc\"\n                    }\n                    ]\n                }\n            ]\n        }\n    ]\n}\n```\n\n## Pre-commit hook\n\nThis project uses [pre-commit](https://pre-commit.com/) to enforce code quality. To install pre-commit hooks, run:\n\n```sh\npre-commit install\n```\n\n## Author\n\n👤 **Huynh Duc Dung**\n\n- Website: https://productsway.com/\n- Twitter: [@jellydn](https://twitter.com/jellydn)\n- Github: [@jellydn](https://github.com/jellydn)\n\n## Stargazers\n\n[![Stargazers repo roster for @jellydn/next-swagger-doc](https://reporoster.com/stars/jellydn/next-swagger-doc)](https://github.com/jellydn/next-swagger-doc/stargazers)\n\n## Show your support\n\n[![kofi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge\u0026logo=ko-fi\u0026logoColor=white)](https://ko-fi.com/dunghd)\n[![paypal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge\u0026logo=paypal\u0026logoColor=white)](https://paypal.me/dunghd)\n[![buymeacoffee](https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge\u0026logo=buy-me-a-coffee\u0026logoColor=black)](https://www.buymeacoffee.com/dunghd)\n\nGive a ⭐️ if this project helped you!\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://productsway.com/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/870029?v=4?s=100\" width=\"100px;\" alt=\"Dung Duc Huynh (Kaka)\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDung Duc Huynh (Kaka)\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=jellydn\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=jellydn\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/tmirkovic\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/6806116?v=4?s=100\" width=\"100px;\" alt=\"tmirkovic\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003etmirkovic\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=tmirkovic\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://holloway.co.nz/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/620580?v=4?s=100\" width=\"100px;\" alt=\"Matthew Holloway\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMatthew Holloway\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=holloway\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/leventemihaly\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/11655496?v=4?s=100\" width=\"100px;\" alt=\"leventemihaly\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eleventemihaly\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=leventemihaly\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/pahrizal\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/36581242?v=4?s=100\" width=\"100px;\" alt=\"PAHRIZAL MA'RUP\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ePAHRIZAL MA'RUP\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=pahrizal\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://ariskk.com/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/4972825?v=4?s=100\" width=\"100px;\" alt=\"Aris\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAris\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=ariskk\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://valerioageno.me/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/51341197?v=4?s=100\" width=\"100px;\" alt=\"Valerio Ageno\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eValerio Ageno\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=Valerioageno\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/cachho\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/14180064?v=4?s=100\" width=\"100px;\" alt=\"cachho\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ecachho\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/jellydn/next-swagger-doc/commits?author=cachho\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjellydn%2Fnext-swagger-doc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjellydn%2Fnext-swagger-doc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjellydn%2Fnext-swagger-doc/lists"}