Doctests, the way you wished they worked
Lean defaults, no setup beyond the plugin, full control when you need it.
Zero boilerplate
describe, it, and expect are injected for you. Doctest bodies are pure assertions — no framework imports.
Multi-runner
One vite plugin works for vitest and vite-plus. A sibling jest transformer covers jest projects.
AST-aware imports
Multi-line and type-only imports inside a block are hoisted to module scope via ts-morph — no regex foot-guns.
Markdown stays markdown
The test marker lives in the fence info string, invisible to readers. Your docs site renders normal code blocks.
Per-block options
Use name="...", skip, or only inside the fence to override naming and focus or skip individual doctests.
Docs that cannot lie
If a snippet stops compiling or asserting, your CI breaks. Docs and code stay in sync by construction.
Write a doctest. Get a test.
Tag a fence with test and the block's body becomes the body of an it().
## Adds two numbers
```ts test
import { sum } from "./sum.ts"
expect(sum(1, 2)).toBe(3)
```$ pnpm test
✓ docs/sum.md (1)
✓ Adds two numbers
Test Files 1 passed (1)
Tests 1 passed (1)Stop writing docs that lie. Make them tests.
Install, mark a fence, run your usual test command. That's it.