
DocSpark: Command Line Documentation Tool for Typescript
DocSpark automatically generates beautiful, interactive, documentation for your React components. Just add a simple config file and a few JSDoc tags, then generate a complete documentation site—no story files, no complex setup required.
My primary driver for building this tool was a growing frustration with tools like Storybook — the constant version bumps introducing dependency conflicts, the mounting code overhead of maintaining a documentation site that increasingly outweighed its benefits. I wanted something leaner.
As someone who values data-driven, autonomous tooling, I set out to build a documentation toolkit purpose-built for design systems — one that generates documentation directly from the same source code it documents. No sidecar files. No parallel maintenance burden.
While Storybook supports auto-documentation by reading your JSDocs, DocSpark takes that concept further. It builds complete, deployable documentation directly from your TypeScript definitions and CSS. With a first-class understanding of design tokens — structured as CSS custom properties — DocSpark reads your component source files and produces a fully navigable documentation site from your codebase alone. No .story files needed.
Quick Breakdown of DocSpark
DocSpark is a zero-story-file documentation generator for React component libraries. You point it at your components, and it produces a static documentation site — complete with live previews, a props table, variant examples, CSS variable documentation, and optional test coverage metrics.
Getting started is a single config file. A docspark.config.json defines where your components live, where the output goes, and optionally configures themes, coverage thresholds, and feature toggles:
1{2 "name": "Acme Design System",3 "source": {4 "include": ["src/components/**/*.tsx"],5 "exclude": ["**/*.test.tsx"],6 "styleFiles": [".css", ".scss"],7 "importAliases": {8 "@acme/components/": "packages/components/"9 }10 },11 "output": {12 "directory": "./docs"13 },14 "theme": {15 "tokens": [{16 "light": { "source": "src/themes/light.css", "background": "#FFFFFF" },17 "dark": { "source": "src/themes/dark.css", "background": "#1F2937" }18 }],19 "defaultTheme": "light"20 },21 "variants": {22 "autoGenerate": true,23 "maxPermutations": 2024 },25 "features": {26 "search": true,27 "darkMode": true,28 "codeSnippets": true,29 "testCoverage": true30 }31}
Everything flows from that config. The source.include globs tell DocSpark which files to parse. importAliases handle monorepo-style paths so dependency resolution works across package boundaries. The theme.tokens array maps named themes to CSS files containing your design tokens as custom properties — enabling runtime theme switching in the generated site. And variants.autoGenerate controls the automatic example generation that makes DocSpark distinct.
The real power is in how components are authored. DocSpark uses ts-morph to parse your TypeScript AST, extracting prop interfaces, union types, default values, and JSDoc annotations. A set of custom JSDoc tags give you fine-grained control over what gets generated:
1export interface ButtonProps {2 /**3 * Visual style of the button4 * @renderVariants true5 * @displayTemplate {variant} Button6 */7 variant?: 'primary' | 'secondary' | 'outline';89 /**10 * Button size11 * @renderVariants true12 */13 size?: 'small' | 'medium' | 'large';1415 /**16 * Loading state — disables interaction and shows spinner17 * @renderVariants true18 * @variantExclude disabled19 */20 loading?: boolean;2122 /**23 * @hideInDocs24 */25 _testId?: string;2627 /** Button label */28 children: React.ReactNode;29}3031const Button: React.FC<ButtonProps> = ({32 variant = 'primary',33 size = 'medium',34 loading = false,35 children36}) => {37 return <button className={`btn btn--${variant} btn--${size}`}>{children}</button>;38};3940export default Button;
From that single file, DocSpark:
- Extracts the full props interface with types, defaults, and descriptions
- Generates variant examples for every value of
variant,size, andloading— producing titled previews like "Primary Button", "Secondary Button", "Outline Button" - Respects
@variantExcludeto avoid nonsensical combinations (e.g.,loading + disabled) - Omits
_testIdfrom the docs entirely via@hideInDocs - Produces a live-rendered preview alongside a copyable JSX code snippet for each variant
CSS design tokens get the same treatment. Document your variables in a JSDoc comment block above the relevant selector, and DocSpark extracts them into a dedicated CSS Variables table on the component page:
1/**2 * CSS Variables:3 * --button-bg: Background color for primary state4 * --button-text: Text color5 * --button-radius: Border radius6 */7.btn {8 background: var(--button-bg, #0066cc);9 color: var(--button-text, #ffffff);10 border-radius: var(--button-radius, 0.375rem);11}
Three CLI commands cover the full workflow:
docspark build— parses components, generates metadata, and compiles a static React site to your output directorydocspark dev— starts a dev server with Chokidar-based file watching and WebSocket live reload, rebuilding documentation as you edit componentsdocspark serve— serves a previously built site with metadata API endpoints and SPA routing
The generated output is a fully static site — an index.html entry point, a React SPA bundle, and a metadata/ directory containing JSON files for each component. It can be deployed to any static host with zero server-side requirements.
Core technologies under the hood:
| Technology | Role |
| ts-morph | TypeScript AST parsing — extracts props, types, JSDoc tags, and component metadata |
| PostCSS + postcss-scss | CSS/SCSS parsing — extracts documented CSS custom properties and theme tokens |
| Commander.js | CLI framework powering build, dev, and serve commands |
| Zod | Runtime validation of docspark.config.json with clear error reporting |
| Express.js | Dev and serve modes — metadata API, SPA fallback routing |
| Chokidar + WebSocket | File watching and live reload during development |
| React + React Router | Documentation site frontend — component pages, sidebar navigation, theme switching |
| react-syntax-highlighter | Syntax-highlighted code snippets in variant examples |
| Glob | File discovery from configured include/exclude patterns |
What sets DocSpark apart:
- Zero story files — documentation is derived entirely from source code and JSDoc
- Automatic variant generation — union types become rendered examples without manual authoring
- Design token awareness — CSS custom properties are first-class citizens, with multi-theme runtime switching
- Configuration-driven — a single JSON file controls source discovery, output, theming, coverage, and feature toggles
- Static output — deploy anywhere, no server runtime required
- Graceful degradation — if the website build fails (e.g., unresolvable dependency), DocSpark still produces all metadata and falls back to a pre-built template so documentation is never lost
- Test coverage integration — optionally parses Jest coverage data and displays per-component metrics with configurable thresholds