DocSpark documentation
Product

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": 20
24 },
25 "features": {
26 "search": true,
27 "darkMode": true,
28 "codeSnippets": true,
29 "testCoverage": true
30 }
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 button
4 * @renderVariants true
5 * @displayTemplate {variant} Button
6 */
7 variant?: 'primary' | 'secondary' | 'outline';
8
9 /**
10 * Button size
11 * @renderVariants true
12 */
13 size?: 'small' | 'medium' | 'large';
14
15 /**
16 * Loading state — disables interaction and shows spinner
17 * @renderVariants true
18 * @variantExclude disabled
19 */
20 loading?: boolean;
21
22 /**
23 * @hideInDocs
24 */
25 _testId?: string;
26
27 /** Button label */
28 children: React.ReactNode;
29}
30
31const Button: React.FC<ButtonProps> = ({
32 variant = 'primary',
33 size = 'medium',
34 loading = false,
35 children
36}) => {
37 return <button className={`btn btn--${variant} btn--${size}`}>{children}</button>;
38};
39
40export 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, and loading — producing titled previews like "Primary Button", "Secondary Button", "Outline Button"
  • Respects @variantExclude to avoid nonsensical combinations (e.g., loading + disabled)
  • Omits _testId from 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 state
4 * --button-text: Text color
5 * --button-radius: Border radius
6 */
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 directory
  • docspark dev — starts a dev server with Chokidar-based file watching and WebSocket live reload, rebuilding documentation as you edit components
  • docspark 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:

TechnologyRole
ts-morphTypeScript 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
ZodRuntime 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