Automated, AST-based JSDoc comment generator and static documentation site builder for JavaScript & TypeScript. Fast, deterministic, and 100% local (No AI involved). No AI. No LLM. No surprises. Same input always produces the same output.
The official documentation site is available at imchintoo.github.io/jsdoc-scribe.
| Resource | Link |
|---|---|
| Website | What is jsdoc-scribe? |
| Quick Start | Install and generate your first docs |
| CLI Usage | Commands, checks, lint, and fix |
| GitHub Pages | Deploy generated docs |
| API Reference | Generated API docs |
| Blog | Guides and release notes |
Two CLIs, one dependency (typescript >=5.0.0, used purely as a syntax parser), 234
passing tests (deterministic, zero network calls — same self-test suite runs on every
npm test and before every npm publish). typescript ships as a regular dependency,
not a peerDependency, because it parses every file this tool touches (.js included, not
just .ts) and can't be left for a consumer to optionally provide.
| Tool | What it does |
|---|---|
gen-comments |
Inserts /** */ JSDoc blocks into your source by reading the AST — no guessing |
gen-docs |
Builds a static, multi-page HTML documentation site from your documented source |
Sticky topnav with centered search, white sidebar with an N-level folder tree, two-column symbol cards (prose left / dark code panel right), and a scroll-spy TOC on module pages.
With --quality, the index page becomes a Code Health dashboard — health score,
maintainability, complexity, duplicate-code, and orphan-file stats, each linking to a full
detail page — and every module page gets a compact per-file health strip. Full breakdown:
Features.
sample/ is a real, runnable-shaped fixture set — not toy one-liners — covering the stacks
teams actually ship with:
| Path | Stack | What's in it |
|---|---|---|
sample/express/ |
Express.js (TS) | app.ts, routes, a controller, a service, and auth middleware for a small task API |
sample/nestjs/ |
NestJS (TS, decorators) | A UsersModule with @Controller/@Injectable classes, a DTO using class-validator decorators, an entity, and a guard |
sample/vanilla-js/ |
Plain JavaScript (CommonJS, no types) | A logger, an event emitter, a retry/circuit-breaker helper, and input validators |
sample/*.ts (top-level) |
Generic TS | A fully-documented DI container, error hierarchy, event bus, HTTP middleware, models, and API layer — used as the "already good" reference case for --check-drift/--lint |
Run any of the CLIs directly against them to see real output on real code, not a demo script:
gen-comments sample/nestjs --dry-run # see what would be generated for decorator-heavy NestJS classes
gen-comments sample/express --check # coverage on an undocumented Express app
gen-docs sample --out docs --title "jsdoc-scribe sample"Measured directly against the CLIs, single Node process, no caching between runs.
| Source size | gen-comments --dry-run |
gen-docs (single file) |
|---|---|---|
| 231 LOC | 1.15s · 96 MB | 0.49s · 94 MB |
| 23K LOC | 1.47s · 167 MB | 0.71s · 155 MB |
| 233K LOC | 4.17s · 345 MB | 2.29s · 445 MB |
Both CLIs scale close to linearly with source size. A real 1,000-file/70K-LOC project
finishes gen-comments --write in 1.03s at 115 MB. gen-docs's multi-file scaling
had a superlinear ceiling past ~300-500 files, fixed in v2.4.2 (400→1,000 files is now
~5.2x time for 2.5x files, down from an unbounded curve) — enforced continuously by
npm run bench:perf-gate in CI. Full numbers and root cause: CHANGELOG;
residual memory-footprint notes at very large file counts: Known limitations.
npx jsdoc-scribe . --write # run once, no install
npm install --save-dev jsdoc-scribe # add to project
npm install -g jsdoc-scribe # or install globallyComments, docs, and lint are all reachable from the CLI, from inside your own Node code, or wired into CI — pick whichever fits the moment. Everything below is expanded in its own section further down; this is the map.
Comments (gen-comments) |
Docs (gen-docs) |
Lint (--lint) |
|
|---|---|---|---|
| CLI | gen-comments src --write |
gen-docs src --out docs |
gen-comments src --lint / --lint --fix |
| Inside your codebase | require('jsdoc-scribe').processFile(file, { write: true }) |
require('jsdoc-scribe/docs').generateSite(['src'], opts) |
require('jsdoc-scribe/lint').lintModule(moduleData) |
| GitHub Actions | run: npx gen-comments src --check (PR gate) |
run: npx gen-docs src --out _site (Pages deploy) |
run: npx gen-comments src --lint (PR gate) |
gen-comments src --write # insert missing JSDoc blocks in place
gen-comments src --check # CI gate: fail if anything is undocumented
gen-comments src --check-drift # CI gate: fail if JSDoc has drifted from the AST
gen-comments src --lint --fix # validate JSDoc content, autofix what's safe to fix
gen-docs src --out docs --quality # build the docs site (add --quality for the Code Health dashboard)Full flag references and walkthroughs live on the docs site: Quick Start · CLI Usage · Features.
Every CLI capability is also a plain function import — no child-process spawning, no
parsing your own stdout. Three subpath exports, one per capability, all with hand-written
TypeScript declarations (no @types/jsdoc-scribe needed):
const { processFile, analyseFile, collectFiles } = require('jsdoc-scribe'); // comments
const { generateSite, extractModule } = require('jsdoc-scribe/docs'); // docs
const { lintModule } = require('jsdoc-scribe/lint'); // lintFull walkthrough with real return shapes: Programmatic API.
Every CLI flag is a plain process exit code (0/1), so any of them drop straight into a
run: step. Copy-pasteable workflows (a PR quality gate covering comments + drift + lint,
plus a docs-to-Pages deploy) are documented in
GitHub Actions Integration
and GitHub Pages Deployment —
this repo's own test.yml, docs.yml,
and publish.yml (npm OIDC trusted publishing, no stored
token) are the same workflows running live.
- JSDoc linting without ESLint.
gen-comments --lintruns the same category of checks eslint-plugin-jsdoc'srecommendedconfig does — missing tags, bad ordering, blank descriptions — with zero new dependencies.--lint --fixrewrites what's mechanically safe to fix (tag order, stray asterisks, placeholderTODO:descriptions) and never touches what it can't safely resolve (a missing block entirely, or a typo'd tag name). - Already on ESLint? The same rules ship as a native flat-config plugin —
packages/eslint-plugin-jsdoc-scribe— so findings and fixes show up in your existingeslint/eslint --fixrun instead of a separate CLI invocation. - Optional code-quality dashboard.
gen-docs --qualitycan run code-multivitals (complexity, maintainability, duplicate-code, orphan-file detection) against the same files it documents. It's an optionalpeerDependency— never installed by default, andgen-docsbehaves identically whether it's present or not. - Config file support.
.jsdoc-scribe.jsonforgen-docsoutput dir, title, source URL, and ignore globs — CLI flags override it. Full reference: Features.
Bug reports and PRs welcome — see CONTRIBUTING.md for dev setup and guidelines (determinism is non-negotiable, no new runtime dependency without discussion first). This project follows the Code of Conduct. Found a security issue? See SECURITY.md rather than opening a public issue with exploit details.
- Inline anonymous callbacks (
arr.map(x => x * 2)) aren't documented — named declarations only. - Type inference is 100% syntactic — no evaluation, no imports, no type-checking.
- Multi-declarator statements (
const a = 1, b = 2;) get one combined block. .d.tsfiles are skipped.gen-docsdoesn't serve — usenpx serve docsor deploy statically.gen-docs's per-page superlinear scaling past ~300-500 files (unmemoized sidebar path-prefix recomputation) is fixed as of v2.4.2 — see Benchmarks and the CHANGELOG. The parse phase (TS Compiler API per file) was profiled and confirmed not co-dominant at the file counts tested, so it stays single-threaded (worker_threadsexplicitly out of scope for this fix — seedocs/backlog/adr-linear-scaling-fix.md).gen-docsholds every generated page's full HTML (including its own embedded sidebar markup) in memory until the whole site has been built, then writes it all to disk — at very large file counts (order of thousands) this is a memory-footprint concern independent of the scaling fix above. Not yet sized against real hardware; tracked indocs/backlog/task-ls-04-sidebar-node-caching.md's implementation notes.
See CHANGELOG.md for release history.
MIT © Chintan