describe(me) docs
early v0.12.1 browser mode · jsdom Live · Foundations
Examples npm GitHub

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 vitest
describe-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:

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.

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/*"
Release cooldowns. The packages of one release reach npm minutes apart. A cooldown such as pnpm's 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
      - 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 #

  1. 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.
  2. Tests Remove imports of step and recorder from @describe-me/vitest. Keep the body of each step() call. Tests that import render from 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.
  3. Packages Uninstall them: pnpm remove describe-me @describe-me/vitest @describe-me/react, plus @describe-me/core if you listed it.
  4. Files Delete the .gitignore lines, the .describe-me/ directory and the built site.