Skip to content

fix: tailwind-merge runtime dep, Button API docs, and a smoke test that replaces attw - #212

Merged
pathscale merged 3 commits into
masterfrom
fix/tailwind-merge-runtime-dep
Jul 26, 2026
Merged

fix: tailwind-merge runtime dep, Button API docs, and a smoke test that replaces attw#212
pathscale merged 3 commits into
masterfrom
fix/tailwind-merge-runtime-dep

Conversation

@pathscale

Copy link
Copy Markdown
Owner

You asked whether something better than attw exists. Yes — and it found three real bugs on its first run, two of them in the 1.3.0 I published twenty minutes earlier.

1. tailwind-merge is a devDependency, and the package needs it at runtime

127 shipped dist files do import { twMerge } from "tailwind-merge". It was declared only in devDependencies. A consumer installing into a project that doesn't already have it:

error: Cannot find package 'tailwind-merge' from
  .../@pathscale/ui/dist/components/button-group/ButtonGroup.js

Invisible in our own apps because every one of them installs tailwind-merge itself, so the import resolves from the app's node_modules. A fresh consumer has nothing to resolve it from. The package is broken on install today.

2. The documented Button API does not compile

ui-usage.md and the README both showed <Button color="primary" size="md">. The shipped type:

variant?: "primary" | "secondary" | "tertiary" | "outline" | "ghost" | "danger" | "danger-soft";
size?: "sm" | "md" | "lg";

No color prop at all, and the size union is narrower than the documented xs | sm | md | lg | xl. ComponentSize and ComponentColor are declared in src/components/types.ts but never re-exported from the root barrel, so consumers can't import them either. In practice color exists on eleven components and variant on about forty — there is no shared union to document.

I rewrote that README verifying every path and not one prop, and propagated the error from ui-usage.md straight onto the npm front page. Corrected in both places.

3. attw was the wrong tool, replaced

378 findings, split perfectly cleanly:

TS moduleResolution .css side-effect imports extensionless imports
node10 89 0
node16 0 200
bundler 89 0

Every consumer app in this org sets skipLibCheck: true, so none of it is ever felt. Zero actionable findings, and nothing about Node runtimes — those are TypeScript resolution modes.

Replaced with a consumer smoke test: pack the tarball, install it into a fixture app configured the way our apps are (bun, moduleResolution: bundler, solid-js, peer deps derived from the manifest), then typecheck and import it. It caught both bugs above; attw caught neither in 378 lines.

It takes SMOKE_TARBALL=/path/to.tgz so it can be run against any published version — that is how I verified it against the live 1.3.0 rather than wiring another untested gate into the release path.

Advisory, not blocking. Today's release failed four times on gates that had never executed in CI. This gets promoted once it has run green a few times.

Release

Merging publishes 1.3.1 automatically — two fix: commits, so a patch bump. That release is the one where a fresh bun add @pathscale/ui actually works.

🤖 Generated with Claude Code

meh and others added 3 commits July 26, 2026 19:42
127 shipped dist files `import { twMerge } from "tailwind-merge"`, but the
package declared it only as a devDependency. A consumer installing
@pathscale/ui into a project that does not already have tailwind-merge
gets a runtime failure on first import:

  Cannot find package 'tailwind-merge' from
  .../@pathscale/ui/dist/components/button-group/ButtonGroup.js

It went unnoticed because every app in this org installs tailwind-merge
itself, so the import resolves from the app's own node_modules. A fresh
consumer has nothing to resolve it from.

Found by the consumer smoke test on its first run, against the tarball
published as 1.3.0 twenty minutes earlier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ui-usage.md and the README both showed

  <Button color="primary" size="md">

Button has no `color` prop. The shipped type takes `variant`
(primary | secondary | tertiary | outline | ghost | danger | danger-soft)
and `size` (sm | md | lg) — narrower than the documented
xs | sm | md | lg | xl.

The blanket claim that sizes and colors are shared unions was also wrong
in practice: ComponentSize and ComponentColor are declared in
src/components/types.ts but never re-exported from the root barrel, so
consumers cannot import them, and components narrow them anyway. `color`
exists on eleven components; `variant` on about forty.

The npm page has been telling people to write code that does not compile.
I rewrote that README verifying every path and never once verifying a
prop, and it propagated the same error from ui-usage.md.

Also drops the warning about README paths that do not exist; both were
fixed in 1.3.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@arethetypeswrong/cli modelled four TypeScript resolution modes, three of
which nothing here ships to, and reported 378 findings. The split was
clean: 200 extensionless-import errors under node16 only, and 178 CSS
side-effect imports under node10 and bundler. Every consumer app in this
org sets skipLibCheck: true, so none of it was ever felt. Zero actionable
findings.

This installs the packed tarball into a fixture app configured the way
those apps are — bun, moduleResolution: bundler, solid-js, peer deps
derived from the manifest — then typechecks it and imports it at runtime.

On its first run it caught tailwind-merge being a devDependency while 127
shipped files import it, and that Button takes `variant` rather than the
documented `color`. attw found neither in 378 lines of output.

Advisory for now. Today's release failed four times on gates that had
never executed in CI; this one gets promoted to blocking only after it has
run green a few times.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview deployment is ready!

You can view the preview at: https://pr-ui-preview-212.surge.sh

@pathscale
pathscale merged commit e467b2b into master Jul 26, 2026
2 checks passed
@pathscale
pathscale deleted the fix/tailwind-merge-runtime-dep branch July 26, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant