The unglamorous trick to shipping a whole catalog on release day
Mantine 9.5.0 came out this morning. By the afternoon every Mantine Extensions component was published on it, along with both starter templates and the docs hub.
I wish I could tell you that was skill. It's mostly one boring shell script and one rule I've learned the hard way.
The script does the whole dance per repo: branch, bump within semver, format, typecheck, lint, test, build the package, regenerate the API docs, build the docs site, test again, commit, PR, merge, publish, deploy. I run it in parallel batches and read the reports. The first repo is always done by hand though — a pilot — because the point of a pilot is to discover the surprise on one repo instead of on all of them.
Today's surprise was a good one. I'd planned to also align three dev-tool majors we'd fallen behind on. Two were harmless. The third, a stylelint config, turned out to enable a rule that rewrites rgba() to rgb() — in the CSS that actually ships inside every package. Nothing would have broken. It would just have quietly put a cosmetic diff inside twenty-six published packages, in a release whose entire story was "we bumped Mantine". So it got pulled out and parked in its own tooling pass, where a big diff is the expected outcome rather than a thing hiding in the corner.
The rule, then: a dependency bump should be boring, and anything that isn't boring belongs in its own release. If you can't describe a release in one sentence, it's probably two releases.
The other thing I found today wasn't a surprise so much as a small cold sweat. The release script used set -e, so I'd always assumed a red test suite would stop it. But every check piped its output through tail to keep the logs short — and a pipeline's exit code is the last command's. tail always succeeds. Which means for who knows how many rollouts, a failing test suite would have sailed straight through to npm publish. It never happened, but only because the tests never failed. That's luck, not a safety net. Fixed, with a helper that keeps the logs short and still aborts loudly.
If you maintain more than three repos, go check your CI and release scripts for cmd | tail right now. I'll wait.
And if you're upgrading your own app: 9.5 is a purely additive minor, and a generous one — a new Cascader for hierarchical data, a resizable FloatingWindow, alternating Timeline layouts, keyboard-navigable charts plus two new chart types. Mantine also moved to oxc this release and published its shared config as oxc-config-mantine.
We took its linter half across all 26 repos — and while doing it, found that its formatter half declares an import order through an importOrder key that oxfmt doesn't actually support. It is accepted and then silently ignored, so nobody using that config is getting the import order it promises, upstream included. Filed it with a repro. Worth knowing before you adopt it: take the oxlint side, keep your own formatter for now.
Curious what the rest of you do about the visual side of this. Green tests prove the code runs, never that it still looks right — and a good chunk of these components are CSS 3D, where a single overflow or opacity in the wrong place silently flattens the whole scene. I screenshot the deployed docs and actually look at them, which catches the obvious collapses but not subtle drift. How do you keep eyes on a catalog this size without spending a day in a browser?
📚 https://mantine-extensions.vercel.app/


Replies