Installation
Three dev dependencies and one plugin line. This page lists the versions describe-me supports, what to install for each environment, and how to keep it healthy in a real project.
Supported versions #
The ranges below are the peer dependencies and engines of the published packages, exactly
as their package.json files write them. Your package manager checks them when
it installs.
| Package | Range | Asked for by | Needed |
|---|---|---|---|
react |
^18.0.0 || ^19.0.0 |
@describe-me/react |
Required. |
react-dom |
^18.0.0 || ^19.0.0 |
@describe-me/react |
Required. The live preview mounts components with it. |
@testing-library/react |
^16.0.0 |
@describe-me/react |
Optional. You need it for jsdom. |
vitest-browser-react |
^2.0.0 |
@describe-me/react |
Optional. You need it for browser mode. |
vitest |
^4.0.0 || ^5.0.0 |
@describe-me/vitest |
Required. Test tags, for
stories: 'tagged' and no-docs, need 4.1.
|
typescript |
^5.0.0 || ^6.0.0 |
@describe-me/vitest |
Optional. The reporter reads component props with it, for the props table. TypeScript 7 has no compiler API it can use, so with it the run records without props and warns once. |
@testing-library/user-event |
^14.0.0 |
@describe-me/vitest |
Optional. In jsdom, its interactions record frames when it is installed. |
vite |
^6.4.0 || ^7.0.0 || ^8.0.0 |
describe-me |
Required. The CLI runs the viewer on your Vite. |
node |
>=20^20.16.0 || >=22.4.0
|
core, react and vitestdescribe-me
|
Required. Your Vite and Vitest set the real floor. Vite 8.3.0 needs
^20.19.0 || >=22.12.0, and Vitest 5.0.1 needs
^22.12.0 || ^24.0.0 || >=26.0.0.
|
What CI tests
CI runs on Node 22 only. Its smoke job packs the packages, installs them into a fresh
project and runs browser mode (Chromium through @vitest/browser-playwright)
and jsdom on four toolchains:
- the examples' toolchain: Vite 8.3, Vitest 5.0 and React 19,
- Vite 8.2.2,
- Vitest 4.1.11 with Vite 6.4.3,
- React 18.3.1 with Vitest 4.1.11 and Vite 8.2.2.
CI does not test Node 20, Vite 7, Vitest 4.0, happy-dom or browser providers other than Playwright. They sit inside the ranges, but nothing checks them.
Every example runs React 19.3, Vite 8.3.0 and Vitest 5.0.1. The browser-mode examples,
react-browser and shadcn, add vitest-browser-react 2.3.0 and Playwright
1.63.0, and shadcn adds Tailwind 4.3.3. The jsdom examples, react-jsdom and mui, add jsdom
26.1.0, @testing-library/react 16.3.3,
@testing-library/dom 10.4.2 and
@testing-library/user-event 14.6.7, and mui adds Material UI 9.5.0. How
describe-me tells the two environments apart is on
Environments.
The packages #
describe-me ships as four packages. You install three of them, and the fourth comes with them.
| Package | What it holds | Entry points |
|---|---|---|
describe-me |
The CLI and the viewer. It installs the binary describe-me and has
nothing to import.
|
CLI |
@describe-me/vitest |
The plugin, the setup files, the reporter, step and
recorder.
|
., ./plugin, ./setup, ./setup-dom,
./reporter
|
@describe-me/react |
The recording render, which the plugin swaps in for your test
library's.
|
.,
./testing-library
|
@describe-me/core |
The recorder and the types. The other packages install it. |
.
|
Package managers #
Add the three packages as dev dependencies. pnpm and npm install missing peers on their
own. yarn does not, so add vite there yourself. Vitest needs it anyway.
# pnpm
pnpm add -D describe-me @describe-me/vitest @describe-me/react
# npm
npm install -D describe-me @describe-me/vitest @describe-me/react
# yarn
yarn add -D describe-me @describe-me/vitest @describe-me/react vite
Then add what your environment needs, as the next two sections show.
Browser mode #
Browser mode runs your tests in Chromium through Playwright. Add Vitest, its Playwright
provider, Playwright and vitest-browser-react, then download Chromium:
pnpm add -D vitest @vitest/browser-playwright playwright vitest-browser-react
pnpm exec playwright install chromium
Keep @vitest/browser-playwright on the same version as vitest:
version 5.0.1 peers on exactly vitest 5.0.1. The browser example asks for
vitest and @vitest/browser-playwright ^5.0.1,
playwright ^1.63.0 and vitest-browser-react
^2.3.0. Its config, trimmed:
vitest.config.ts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import { playwright } from '@vitest/browser-playwright'
import { describeMe } from '@describe-me/vitest/plugin'
export default defineConfig({
plugins: [react(), describeMe()],
test: {
browser: {
enabled: true,
headless: true,
provider: playwright(),
instances: [{ browser: 'chromium' }],
},
},
})
Getting started walks through a first story in browser mode.
jsdom #
For jsdom, add Vitest, jsdom, @testing-library/react and its peer
@testing-library/dom. @testing-library/react 16 peers on
@testing-library/dom ^10.0.0.
@testing-library/user-event is optional.
pnpm add -D vitest jsdom @testing-library/react @testing-library/dom
pnpm add -D @testing-library/user-event
The jsdom example asks for jsdom ^26.1.0,
@testing-library/react ^16.3.0,
@testing-library/dom ^10.4.0 and
@testing-library/user-event ^14.6.1. The plugin needs no browser
block to detect jsdom:
vitest.config.ts
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
import { describeMe } from '@describe-me/vitest/plugin'
export default defineConfig({
plugins: [react(), describeMe()],
test: { environment: 'jsdom' },
})
Getting started walks through a first story in jsdom, and Environments says what the plugin changes there.
One version for all packages #
Install every describe-me package at one version, and upgrade them together.
- Every release bumps all four packages to the same version, also those that did not change.
-
@describe-me/reactpeers on@describe-me/vitest, which has an optional peer ondescribe-me. Both peers are published as a caret range of the release, for example^0.5.2. Before 1.0 that accepts any later 0.5 patch. So the package manager warns about a mix of minor lines, such as 0.4 with 0.5, but not about a mix of patches. -
At run time, the test recorder carries a protocol number. When two copies of
@describe-me/corewith different protocols meet, every test file fails with this error:
describe-me: all describe-me packages must be on the same version. Another copy of @describe-me/core created the test recorder (protocol 2, expected 3). Install @describe-me/core, @describe-me/react, @describe-me/vitest and describe-me at one version.
Troubleshooting covers that error. To keep the packages together, give your update bot one group for all of them. With Renovate:
renovate.json
{
"packageRules": [
{
"matchPackageNames": ["describe-me", "@describe-me/**"],
"groupName": "describe-me"
}
]
}
With Dependabot:
.github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
groups:
describe-me:
patterns:
- "describe-me"
- "@describe-me/*"
minimumReleaseAge
or Renovate's
minimumReleaseAge
can therefore let some of them through and hold others back. Upgrade once the whole
release is past it.
What to commit #
The reporter writes .describe-me/ on every run, and
describe-me build writes the static site to describe-me-dist/,
or to the directory --out names. Both are generated, so keep them out of git:
.gitignore
.describe-me/
describe-me-dist/
If you set outDir or --out, ignore those directories instead.
Commit your Vitest config and any project files that previewHead links, such
as a fonts stylesheet. The reporter copies them into the output.
How it works lists the output files, and
Viewer and CLI the flags.
Build the docs in CI #
This workflow runs your tests, builds the static site and publishes it to GitHub Pages. This project's own workflow does the same for every example and the docs pages.
.github/workflows/docs.yml
name: docs
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
# Browser mode only.
- run: pnpm exec playwright install --with-deps chromium
- run: pnpm exec vitest run
- run: pnpm exec describe-me build
- uses: actions/upload-pages-artifact@v3
with:
path: describe-me-dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
- Set the Pages source to "GitHub Actions" in the repository settings once (GitHub docs).
-
pnpm/action-setupreads the pnpm version frompackageManagerinpackage.json, or takes aversioninput (its inputs). - The site uses relative URLs, so it works under a sub-path such as a project page (Hosting).
-
describe-me builddownloads web fonts into the site, which needs network. Without network, pass--no-vendor-fonts(the flag, font vendoring). -
describe-me build --liveadds Live to the published site. The site then holds the compiled code of your components, the test files and the setup files with their test data, so publish it only where that code may be seen (the flag). -
A failing test fails the
vitest runstep, so nothing deploys. The reporter still writes failed tests, and the viewer counts them in its header. To publish anyway, let that step fail without failing the job (continue-on-error):
- run: pnpm exec vitest run
continue-on-error: true
Monorepos and projects #
Add describeMe() to the root config. Every inline project that extends it
records: with extends: true, and in Vitest 5 also without
extends, because Vitest 5 extends an inline project by default. In Vitest 5
those projects share the root's Vite server and skip the plugin's
config hook, so the plugin gives them its setup file in
configureVitest. Before 0.6.1 they recorded nothing and left components
mounted (fixed).
A project with extends: false, or with a config file of its own, does not get
the root config's plugins. Without describeMe() in its own config it records
nothing, and Testing Library cleans up after each of its tests as usual. Before 0.6.1 its
components stayed mounted (fixed).
Two limits remain. describeMe() in the plugins of a project
alone writes no manifest, because Vitest runs only the root config's reporters (limitation). A test file that two projects run is one module in the manifest (limitation).
With test.projects entries that set their own root, the setup
file matches include and exclude against a path relative to the
project root, and the reporter against a path relative to the Vitest root. Globs that
start with **/ match both.
Which tests record shows the case.
Upgrading #
Upgrade all describe-me packages in one step:
pnpm up --latest describe-me '@describe-me/*'
A newer viewer reads older output, but not the other way round, and it shows a banner when the version that wrote the data differs from its own. How it works explains the version checks, and Viewer and CLI the banner.
Removing describe-me #
-
Config Remove
describeMe()and its import from your Vitest config. If you wired describe-me by hand, remove its setup file, its reporter and the settings you added for it. -
Tests Remove imports of
stepandrecorderfrom@describe-me/vitest. Keep the body of eachstep()call. Tests that importrenderfrom their test library keep working unchanged. Tests that import it from@describe-me/react, as a hand-wired setup does, go back to their test library. -
Packages Uninstall them:
pnpm remove describe-me @describe-me/vitest @describe-me/react, plus@describe-me/coreif you listed it. -
Files Delete the
.gitignorelines, the.describe-me/directory and the built site.