# `tw-merge/` — vendored `tailwind-merge`

Upstream: **tailwind-merge v3.6.0** — https://github.com/dcastil/tailwind-merge
Licence: MIT, © 2021 Dany Castillo. Full text in the kit's `NOTICE`.

## Why it lives here

The kit publishes **zero runtime dependencies**. `tailwind-merge` is what makes
`cn()` work — it resolves Tailwind conflicts so a consumer's `className` beats
the variant's own utility without `!important` or specificity tricks — so it
could not simply be deleted. It is copied in instead of installed, which keeps
it out of every downstream lock file.

`radix-ui` took the other route (compiled into `dist` by tsup, see the
`noExternal` note in `tsup.config.ts`) because its `@radix-ui/*` sub-packages
publish only `dist`, with no source to copy. `tailwind-merge` publishes `src`,
has no dependencies of its own, and is 17 files — so copying is both possible
and cheaper to reason about.

## The one rule: do not edit these files

Every `.ts` file here is upstream's, unchanged except for one recorded edit.
`src/lib/tw-merge.test.ts` compares each file against the pinned
devDependency — so an edit here, or a version bump without a re-copy, fails the
suite rather than drifting silently. That is why the provenance note is in this
README rather than in header comments inside the sources: nothing in them is
ours to write.

**The one edit**, applied to 10 files and listed line by line in
`TYPE_IMPORT_PATCH` in that test: imports whose bindings are all types gain
`import type`. The kit compiles with `verbatimModuleSyntax` and upstream does
not. Unlike the ESLint rules — `eslint.config.js` switches four of them off for
this folder — that is a whole-program compiler option, so the files had to move
instead of the config.

To move to a newer upstream:

```bash
npm i -E tailwind-merge@<version>       # .ncurc.json rejects it, so this is deliberate
cp -r node_modules/tailwind-merge/src/. src/lib/tw-merge/
npx eslint src/lib/tw-merge --fix       # re-applies the import type edit
npm run test:run -- src/lib/tw-merge    # tells you if the patch table drifted
# then update the version above, in NOTICE, and in TYPE_IMPORT_PATCH
```

Only `twMerge` is used (`src/lib/utils.ts`). The rest of the upstream barrel is
carried unchanged so the copy stays diffable; it is side-effect-free and
tree-shakes away.
