Workflow

API docs and a collection, served by your own server

FastAPI shows Swagger UI at /docs with no extra work. Swastik Codes does the same thing for any framework, with two pages instead of one: full documentation at /swc/docs, and a request collection at /swc/collection where readers can fill in a request, press Send and read the response. Install one package with pip or npm, add one line, and your server serves both pages from the OpenAPI document it already has.

Get started freeSign inOpen the app

Documentation page served by a FastAPI app at /swc/docs, showing the Place an order request with its body fields, a cURL sample and an example response
Shell
pip install swastik-codes          # FastAPI, Starlette, Flask, Django, any ASGI or WSGI app
npm install @swastik-codes/docs    # Express, NestJS, Fastify, Hono, Koa, plain Node.js

Both packages are free, have no dependencies, and serve the same pages.

One line in your app

FastAPI: the package reads FastAPI's own cached app.openapi(), so there is nothing else to pass.

Python
from fastapi import FastAPI
from swastik_codes import mount

app = FastAPI(title="Acme Shop API")
# ... your routes ...
mount(app, config="swastik-codes.json")

Express and NestJS: pass the OpenAPI document you already have (from @nestjs/swagger, swagger-jsdoc, tsoa, zod-to-openapi or a JSON file).

JavaScript
const { swastikCodes } = require('@swastik-codes/docs');
app.use(swastikCodes({ spec: openApiDocument, config: './swastik-codes.json' }));

Fastify reads @fastify/swagger:

JavaScript
await fastify.register(require('@swastik-codes/docs').fastify, { spec: () => fastify.swagger() });

Flask (init_flask), Django (django_urls), Hono, Koa, Starlette and plain node:http take one line too. Each package's README on PyPI and npm has the exact code. Your own routes keep working, and FastAPI's /docs and /redoc stay unless you turn them off.

What you get

URLPage
/swc/docsDocumentation: introduction, base URL, authentication, then every request with its path, query and header parameters, request body fields, responses and an example response. Code samples in cURL, JavaScript, Python, Go and PHP. Search, a link to every request, light and dark themes.
/swc/collectionA collection of every request, grouped in folders. Edit params, authorization, headers and the body (JSON, form fields and file uploads), press Send and read the response: pretty JSON, headers, status, time and size.
/swc/openapi.jsonThe OpenAPI document both pages read, with your edits applied. Readers can download it.

Both pages have a Run in Swastik Codes button that opens the API in Swastik Codes as a collection, where readers can save requests, write tests, run them in the collection runner and share them with a team.

The collection page served by a FastAPI app: the Place an order request with a JSON body, sent with a bearer token, and its 201 Created response

Edit the pages with one JSON file

Run python -m swastik_codes init or npx @swastik-codes/docs init to write a starter swastik-codes.json. Every field is optional; your OpenAPI document provides everything else. Edit the file and reload the page: there is no restart and no build step.

JSON
{
  "title": "Acme Shop API",
  "description": "Products and orders for the Acme store.\n\n## Getting started\n\n1. Get a token.\n2. Send it as a bearer token.",
  "servers": [
    { "url": "https://sandbox.acme.example", "description": "Sandbox" },
    { "url": "https://api.acme.example", "description": "Production" }
  ],
  "theme": { "accent": "#0d9488", "mode": "system" },
  "groups": [
    { "name": "Start here", "tags": ["Authentication"] },
    { "name": "Store", "tags": ["Products", "Orders"] }
  ],
  "operations": {
    "POST /orders": { "summary": "Place an order", "description": "Reserves the stock for 15 minutes." }
  },
  "hide": ["/internal/*", "DELETE /admin/*"],
  "pages": [{ "title": "Errors", "body": "Every error is `{\"detail\": \"...\"}`." }],
  "links": [{ "label": "Status page", "url": "https://status.acme.example" }],
  "languages": ["curl", "javascript", "python", "go"]
}
  • Title, version and introduction: Markdown, tables included.
  • Servers: the base URLs readers can pick from. Readers can also type their own.
  • Theme: an accent colour, and whether the pages open light, dark or follow the reader's system.
  • Folders and sections: rename tags, describe them, and put them in sections such as Start here.
  • Requests: a better name or description for any request, by "METHOD /path" or operationId, or hide it.
  • Hide: leave out internal paths with patterns like /internal/*. Hidden requests are removed from openapi.json too.
  • Pages and links: extra Markdown pages under the introduction, and links to your status page or support.

The npm package ships a JSON Schema for the file, so editors like VS Code complete and check every field.

The Swastik Codes logo, the Built with Swastik Codes credit and the Run in Swastik Codes button are part of both pages. They have no setting, and a key such as logo in the file is ignored with a warning.

Small, fast and cheap to run

We measured the pages against the two common alternatives on 5 November 2026:

Downloaded by the browser (compressed)Unpacked
Swastik Codes docs22 KB74 KB
Swagger UI 5.17about 427 KBabout 1.6 MB
ReDoc 2.1about 232 KBabout 908 KB
  • One script and one stylesheet, compressed in advance (brotli and gzip) and cached by browsers for a year. The pages themselves are under 1 KB of HTML.
  • Little work on your server. The merged OpenAPI document is built once and cached until your spec or swastik-codes.json changes. A repeat request costs microseconds, and browsers that already have it get 304 Not Modified.
  • Large APIs stay fast. In our test with 2,000 requests the documentation showed its first content in under half a second and used about 5 MB of JavaScript memory, because each section is drawn only when it scrolls near the screen. The collection page lists all 2,000 at once.
  • No outside requests. Every file comes from your server, so the pages work offline, on an intranet and behind a VPN.

Security

  • The pages are sent with a strict Content-Security-Policy: no inline scripts, and scripts and styles from your server only.
  • Tokens a reader types into the collection stay in that browser tab (session storage) and are only sent with the reader's own requests.
  • Text from your OpenAPI document and Markdown is escaped before it is shown, so a description can't add scripts to the page.
  • Only swastik.codes and the Swastik Codes desktop app are allowed to read openapi.json from another origin, for the Run in Swastik Codes button.

Things to know

  • Requests come from the reader's browser. Requests to the server that serves the pages always work. To send requests to a different server (for example production, from docs hosted on staging), that server must allow CORS for the docs' address. Swagger UI has the same limit.
  • APIs on localhost. swastik.codes can't reach a server on your computer, so on localhost the Run in Swastik Codes button offers openapi.json as a download to import instead. The desktop app and swc bridge can call localhost directly.
  • Your framework needs an OpenAPI document. FastAPI and Fastify (with @fastify/swagger) make one for you. For Express, Flask and Django, use the generator you already have, such as swagger-jsdoc, @nestjs/swagger, apispec, flask-smorest or drf-spectacular.
  • Hosted docs instead. If you would rather not serve docs from your app, publish documentation from a Swastik Codes collection.

Frequently asked questions

Does it replace FastAPI's Swagger UI?

It can sit next to it or replace it. mount(app) adds /swc/docs and /swc/collection and leaves /docs and /redoc alone. To use only these pages, create the app with FastAPI(docs_url=None, redoc_url=None). To serve them at /docs, also pass prefix="" to mount().

Is it free?

Yes. Both packages are free to install and use, in development and in production. They are proprietary software from Shwastik Tech Solutions Pvt Ltd, not open source.

Which OpenAPI versions work?

OpenAPI 3.0 and 3.1, and Swagger 2.0. $refs, allOf, oneOf and anyOf, nested and self-referencing schemas, examples, enums, defaults and file uploads are all handled.

Can I remove the Swastik Codes logo or the Run in Swastik Codes button?

No. They are part of the pages, and the licence does not allow removing, hiding or changing them. Everything about your API itself (name, text, servers, colours, folders and which requests show) is yours to edit.

Does anything get sent to Swastik Codes?

No. The pages load nothing from swastik.codes and include no analytics. A reader's browser contacts swastik.codes only when they click Run in Swastik Codes.

Try it on your own API

Swastik Codes runs in the browser and is free to use. Create an account to send requests, sync your workspaces and invite your team.