Introducing generate-jsdoc-example-tests v0.1.0 ðŸŽ‰

Repository

Intro – the why, the how and the ugly truth

To me, documentation by example is the best kind of documentation. As the saying goes: one example is worth a thousand words. However, I was tired of my examples getting obsolete.

Elixir has ExUnit’s DocTest ; I wondered if could we have something in that fashion in the JS/TS ecosystem.

Then I figured: why not reconcile the 2 ? Write JSDoc examples, and generate tests from them…
Plus JsDoc `@example` provide in-IDE documentation for free.

So here comes… generate-jsdoc-example-tests 🎉.

Demo

Let’s take a date format function, for instance.

1. Add the JSDoc example in the source code

// src/date-formatter.ts
/**
 * @example
 * ```ts
 * import { formatDateYear } from './date-formatter'
 *
 * expect(formatDateYear(new Date('2026-01-01')).toBe('2026')
 * ```
 */
export function formatDateYear(date: Date): string {…}

2. Generate the test using npx gen-jet

npx gen-jet ./src \
    --header 'import { expect, test } from "vitest"' \
    --test-file-extension '.example.test' # do not provide the `.ts` or `.js`
    # --watch              enables watch mode

3. The generated test:

// src/date-formatter.example.test.ts
// DO NOT EDIT …
import { expect, test } from 'vitest' // the provided header
import { formatDateYear } from './date-formatter'

test('Example 1', () => {
  expect(formatDateYear(new Date('2026-01-01'))).toBe('2026')
})

Contributions are more than welcome! If anyone is interested, please do get in touch 😊 (I rarely bite).


What can you document with that ?

Any developer-oriented documentation, really:

For now it supports functions, methods, interfaces/types & constants.

Bonus: if you have a prettier config, it uses it to format the generated test files.

Test-Runner Agnostic

To adapt the generated test files to your test runner, you can override the test function and add imports using options – see usage and the Vitest example.

Why

I’d rather integrate with test runners to benefit from goodies like coverage and reports rather than building my own micro test runner.

How I use it in my projects

I used it to implement yet-another schema library called unhoax – a type-driven one, you can check it out.
I managed to reach >99% of coverage just by using example tests. Bonus: The examples are re-used to generate the full reference.

Project setup

Sources files: package.json | .gitignore

In the CI

Generate test files after linting, type checking, … and before running the tests.
That way, I could benefit from my test runner’s coverage capabilities and generate the coverage badge.

Sources file: .github/workflows/coverage.yml

Final considerations

I personally enjoyed working that way. The only downside was writing code in comments, losing syntax checking and code completions for instance. I considered this trade-off acceptable.