# AGENTS.md This repository is a pnpm monorepo hosting `tailwind-merge` — a TypeScript library that merges Tailwind class strings by removing style conflicts while preserving non-conflicting and non-Tailwind classes — and its sibling packages. Packages are independent: each owns its lint, test, and type-check setup and releases on its own schedule. ## Primary Goals - Keep merge behavior correct for the supported Tailwind versions listed in the library documentation. - Keep runtime fast (browser-oriented hot path, lazy init, lightweight cache). - Keep API and type contracts stable. ## Repo Map - The library package: `packages/tailwind-merge/` — source in `src/`, tests in `tests/`, human docs in `docs/`, build/release scripts in `scripts/`, published overview `README.md` (autogenerated from `docs/README.md`). - Unreleased workspace packages: `packages/configurator/` generates tailwind-merge configs from Tailwind v4 CSS; `packages/plugin-core/` adds what every bundler plugin needs on top (CSS root discovery, runtime-module generation, the generation session); `packages/vite/` and `packages/next/` wrap both for Vite and Next.js with automatic generation and usage pruning. The configurator and the plugins have a maintained `README.md` and user documentation in `docs/`; the plugin core is internal and inlined into both plugins. - Repo root: workspace orchestration only — `pnpm-workspace.yaml` (workspace list + shared tool-version catalog), `eslint.config.base.mjs` (shared lint base every scope spreads), root `eslint.config.mjs` (lints root files and `.github/`), root `vitest.config.mts` (aggregates the packages' Vitest projects plus the local GitHub actions' tests), repo-wide release tooling in `scripts/` (`update-pinned-links.mjs`, `pin-readme-links.mjs`, `stamp-dev-version.mjs`, `check-library-release.mjs`), and the repo-level `README.md`. - CI workflows: `.github/workflows/` - Local GitHub actions: `.github/actions/` ## Agent Docs Map - `agents/tailwind-merge-internals.md`: library architecture, file ownership, shared testing/build behavior, and CI/security guardrails. - `agents/configurator.md`: configurator goals, strategy, generation/classification architecture, correctness gates, and development follow-ups. - `agents/plugin-core.md`: the shared plugin core — discovery, generation, and session invariants, testing, and its inlined packaging. - `agents/vite-plugin.md`: Vite integration goals, runtime resolution, watching/failure contracts, packaging, and test coverage. - `agents/next-plugin.md`: Next.js integration goals, the loader-rule mechanism and its Turbopack/webpack facts, testing harness, packaging, and test coverage. - `agents/configurator-performance.md`: dated measurements, optimization rationale, and reproduction methodology. - `agents/tailwind-css-version-update.md`: Tailwind CSS version support workflow. - `agents/release-workflow.md`: changelog authoring, GitHub release text, sponsor handling, and release comments on issues/PRs. ## Environment and Commands - Package manager: `pnpm` with a workspace rooted at `pnpm-workspace.yaml` - Local development runtime: Node `22.18.0` or newer on a supported LTS release, satisfying the requirements of pnpm 11 and the Babel 8 build toolchain - CI runtime: Node `24.18.1`, pinned via `node-version` in the workflows under `.github/workflows/` (Renovate bumps it there; treat the workflows as the source of truth if this number looks stale) - Consumer TypeScript support: TypeScript `3.8` and newer; `pnpm test:exports` verifies the generated declarations with the pinned minimum compiler - Dependency supply-chain guardrail: `minimumReleaseAge: 4320` in `pnpm-workspace.yaml`, so newly published package versions must be at least three days old before pnpm installs them. Renovate has a matching cooldown in `.github/renovate.json` (see `agents/tailwind-merge-internals.md` for how the two must stay in sync). - Dependency build scripts are denied by default unless explicitly allowed in `pnpm-workspace.yaml`; `esbuild` is currently allowed because `.github/actions/metrics-report` needs it. - The root manifest's `devEngines.runtime` must encode the real documented Node floor (currently `>=22.18.0`), not a rounded-down one: pnpm validates dependency `engines` against the range's minimum version, and a floor looser than a dependency's own requirement makes pnpm silently skip optional dependencies during install — this is how rolldown's platform binary went missing under an earlier `>=22`, with only a debug-level log mentioning it. Core commands (repo root): - `pnpm install --frozen-lockfile` - `pnpm lint` — lints root files, then every package's own lint script (`pnpm --recursive lint`) - `pnpm test` — runs every package's Vitest project plus the local GitHub actions' tests through the root projects config, with coverage - `pnpm test:types` — every package's own tsc project (`pnpm --recursive test:types`) - `pnpm test:watch` — cross-package watch mode Library-specific commands (run with `pnpm --filter tailwind-merge