@cc_arpan_dev/apicopilot
v1.0.1
Published
Auto-generate Swagger/OpenAPI 3.0 documentation from any backend codebase (Express, NestJS, Laravel, Django, FastAPI, Flask)
Maintainers
Readme
ApiCopilot
Your copilot for API docs. Auto-generate Swagger / OpenAPI 3.0 documentation from any backend codebase — no decorators, no annotations, no AI required.
Point it at your project, get a complete swagger.json (or YAML) plus a live, interactive Swagger UI. Works on Express, NestJS, Laravel, Django, FastAPI, and Flask out of the box.
Why?
Writing API documentation by hand is tedious, drifts out of sync with the code, and is the first thing skipped when shipping fast. Existing tools usually require you to litter the codebase with custom annotations.
This tool reads the code as-is. It detects routes, controllers, validators, and response shapes through static analysis — so an undocumented codebase still produces a usable spec, and a well-documented one (JSDoc / PHPDoc / docstrings) produces an even richer one.
What it extracts
| Feature | How |
|-------------------------------|------------------------------------------------------------------------------------------------------|
| Routes & methods | AST/regex parsing per framework (app.get, Route::post, @app.get, @Controller, etc.) |
| Path & query parameters | From the URL pattern + req.query.X accesses |
| Mounted prefixes | Follows app.use("/v1", apiRouter) → apiRouter.use("/user", userRouter) chains |
| Request body schema | Reads Zod (z.object({...}).safeParse(req.body)), Joi, destructuring, and direct property access |
| Request body example | Generated from field names (email → [email protected], price → 99.99) |
| Response shapes per status| Walks every res.status(N).json(X) call and analyzes X |
| Envelope helpers | Recognizes wrappers like handleResponse(status.OK, 'msg', data) and unpacks them |
| Summaries / descriptions | Priority waterfall: docstring → @swagger annotation → handler-name humanization → method+path template |
| Tags | Derived from controller / route file name |
Quick start
No clone, no install — just run it with npx (or bunx):
npx @cc_arpan_dev/apicopilot --path /path/to/your-backend --serve
# or
bunx @cc_arpan_dev/apicopilot --path /path/to/your-backend --serveOpen http://localhost:3000 and you'll see your live API docs. Three files are written next to where you run it: swagger.json, coverage.json, postman_collection.json.
Supported frameworks: Express, NestJS, Laravel, Django, FastAPI, Flask.
Or install globally
npm install -g @cc_arpan_dev/apicopilot
apicopilot --path /path/to/your-backend --serveOr run from a clone (for development)
git clone https://github.com/CodecloudsArpan/apicopilot.git
cd apicopilot
npm install
node bin/cli.js --path /path/to/your-backend --serveCLI usage
apicopilot [options]
# or, without installing:
npx @cc_arpan_dev/apicopilot [options]| Option | Description | Default |
|------------------------|--------------------------------------------------------------------------|----------------|
| -p, --path <dir> | Path to the backend codebase to analyze | current dir |
| -o, --output <file> | Output file path (.json or .yaml) | swagger.json |
| -f, --format <fmt> | Force output format: json or yaml | inferred from --output |
| --framework <name> | Force framework detection: express, nestjs, laravel, django, fastapi, flask | auto-detect |
| --serve | Start a local Swagger UI server after generating | off |
| --port <port> | Port for the Swagger UI server | 3000 |
| --no-open | Don't auto-open the browser when serving | opens by default |
| -h, --help | Show help | |
| -V, --version | Show version | |
How it detects the framework
| If your project has... | It's identified as |
|------------------------------------------|--------------------|
| package.json with @nestjs/core | nestjs |
| package.json with express | express |
| composer.json with laravel/framework | laravel |
| requirements.txt containing fastapi | fastapi |
| requirements.txt containing django | django |
| requirements.txt containing flask | flask |
If detection fails or you have a hybrid setup, override with --framework <name>.
Examples
Run against an Express / TypeScript backend
npx @cc_arpan_dev/apicopilot \
--path ~/projects/my-api \
--output ./docs/swagger.json \
--serve \
--port 3001Generate YAML and skip the UI
npx @cc_arpan_dev/apicopilot \
--path ~/projects/my-laravel-app \
--output ./docs/openapi.yaml \
--format yamlForce a framework when auto-detection picks the wrong one
npx @cc_arpan_dev/apicopilot \
--path ./backend \
--framework fastapi \
--serveTips for richer output
The tool produces a usable spec with zero changes to your codebase, but you can boost the quality of the generated docs by following a few conventions:
Use validation libraries. If you already validate with Zod or Joi, the tool will pick up your schemas automatically and turn them into proper OpenAPI request bodies + examples.
const result = z.object({ name: z.string(), price: z.number(), email: z.string().email(), }).safeParse(req.body);Add JSDoc / PHPDoc / docstrings above your handlers when you want a summary or description in the docs.
/** * Get user by ID * Returns the user's profile and credit balance. */ userRouter.get('/:id', getUser);Use a consistent response wrapper (e.g.
handleResponse(status, msg, data)). The tool recognizes the pattern and produces clean envelope examples per status code.Prefer descriptive handler names. Names like
getUserByIdandcreate_credit_packageget humanized into "Get user by ID" / "Create credit package" automatically.
Architecture (in case you want to extend it)
apicopilot/
├── bin/cli.js # CLI entry point (commander)
├── src/
│ ├── index.js # Orchestration: detect → parse → build → output
│ ├── detector.js # Detects framework from config files
│ ├── describer.js # Description waterfall (docstring → swagger ann. → humanize → template)
│ ├── exampleGen.js # Field-name-aware example value generator
│ ├── handlerIndex.js # Builds a global map: exportName → fnNode
│ ├── schemaExtractor.js # Pulls Zod/Joi/destructure shapes from handler bodies
│ ├── responseExtractor.js # Walks res.status(N).json(X) calls, extracts response shapes
│ ├── builder.js # Assembles final OpenAPI 3.0 object
│ ├── output.js # Writes & validates JSON/YAML
│ ├── server.js # Express + swagger-ui-express local preview
│ ├── utils.js # Path normalization, param extraction, tagging
│ └── parsers/
│ ├── express.js
│ ├── nestjs.js
│ ├── laravel.js
│ ├── django.js
│ ├── fastapi.js
│ └── flask.jsTo add a new framework:
- Drop a file in
src/parsers/yourframework.jsexportingparseProject(rootPath) → routes[] - Register it in
src/detector.jsandsrc/index.js - Each route should have:
{ method, path, handlerName, comment, parameters, bodySchema?, responses?, tags, sourceFile }
Limitations
- Static analysis only. Dynamically registered routes (
routes.forEach(r => app.get(r.path, ...))) are not detected. - No deep type resolution. Prisma model shapes, TypeScript interfaces from external files, and ORM result types are not traced — fields fall back to name-based inference (
user→{},email→string). - First-match wins when the same handler name exists in multiple files — the one in
controllers/is preferred. - Works best on conventionally structured codebases. Highly dynamic / metaprogramming-heavy code may need
--frameworkand JSDoc hints.
Output format
Standard OpenAPI 3.0 JSON or YAML. Compatible with:
- Swagger UI / Swagger Editor
- Postman (import as OpenAPI)
- Redoc, Stoplight, Insomnia
- Code generators (
openapi-generator-cli)
License
MIT
