Docs
Updates & tests
Copy-paste libraries give you the code once, and then you are on your own: fix a bug upstream and your copy never gets it, re-add the component and you lose your edits. The ballmac command line tool remembers what it installed and merges new versions into your edited copies.
Install items with it
ballmac sits next to the shadcn CLI. shadcn still writes the files and installs packages; ballmac runs it for you and records what landed. Run it in a project that already has a components.json.
npx @ballmac/cli add dialog --with-testsThat installs dialog and the items it needs, then writes ballmac.lock.json and a .ballmac folder that holds an untouched copy of each file as it was installed. Commit both: the untouched copy is what makes merging possible, and your teammates and CI need it too.
See what is behind
ITEM INSTALLED LATEST YOUR CHANGES WHAT CHANGED
badge 1.0.0 1.1.0 none Slightly wider horizontal padding so short labels do not look cramped.
button 1.0.0 1.1.0 yes (will be merged) The lg size is taller and larger so it matches the lg input and select.
dialog 1.0.0 1.1.0 yes (will be merged) The overlay is a little lighter and uses a standard blur.
3 of 4 behind. Update with: ballmac update (add --dry-run to preview)Every item has a version and a changelog written for someone who customised the file: what behaviour changed, and whether props were added, renamed or removed. Breaking changes are marked. The same notes are on each component page under What changed.
Update, keeping your edits
npx @ballmac/cli update --dry-run # show what would happen, change nothing
npx @ballmac/cli update # do itFor each file, ballmac compares three versions: the one you installed, yours now, and the new one.
- You never touched it: replaced with the new version.
- You edited it, and Ballmac changed other lines: merged. Both sets of changes are kept.
- You and Ballmac changed the same lines: the file gets git-style conflict markers, because only you know which one you want. Search for
<<<<<<<, choose, and run your tests. - A file you deleted stays deleted. New files and new dependencies a version adds are installed and tracked.
button 1.0.0 → 1.1.0
1.1.0: The lg size is taller and larger so it matches the lg input and select.
merged src/components/ballmac/button.tsx your changes kept
updated src/components/ballmac/__tests__/button.test.tsx
dialog 1.0.0 → 1.1.0
CONFLICT src/components/ballmac/dialog.tsx 1 conflict(s): search for <<<<<<< and choose
2 item(s) updated. 1 file(s) have conflicts to resolve.
Originals are in .ballmac/backup/2026-10-11T10-54-02-743Z/Before anything is written, every file it might change is copied to .ballmac/backup/ (ignored by git), and if shadcn fails halfway your files are put back. Files that shadcn shares between items, such as your own edits to the i18n helper, are never overwritten.
See what you changed
npx @ballmac/cli diff buttonShows your changes against the version you installed, nothing else. Useful before an update, and for remembering why a file differs.
Tests that ship with components
Most free components come with the test we run on them: keyboard use, states and ARIA, written with vitest and Testing Library. Add them with --with-tests, or later with ballmac test add.
npx @ballmac/cli add dialog --with-tests
npx @ballmac/cli test add button # for items you already have
npx @ballmac/cli test # run every Ballmac test in the projectTests are installed in __tests__ next to the components, with one shared setup.ts. The tool installs the packages they need at versions known to work together (vitest, jsdom, Testing Library, the React plugin) and, if you have no vitest config yet, creates one with your @ alias. Pages for components that have a test say so. A test is yours once installed, and it is updated with the component: your additions are merged like any other file.
With an AI agent, this closes the loop: after it edits a component it can run the test and fix what it broke. Pro blocks are tested in batches rather than one by one, so they do not ship per-item tests yet.
Items you already installed
Installed with plain shadcn add? Adopt them:
npx @ballmac/cli track # every Ballmac item found in the project
npx @ballmac/cli track dialog buttonA file identical to what shadcn writes today is recorded as untouched. One that differs is recorded without a base, because it may be edited or from an older version and there is no way to tell. For those, an update puts the new version beside your file as <file>.ballmac-new instead of guessing. Once you have compared them, ballmac track --rebase button declares your file current.
Pro, CI and agents
- Pro items work the same way. Set
BALLMAC_LICENSE_KEYin your environment or.env.local(see Pro); without it only free items are listed. - CI:
ballmac outdated --exit-codefails when something is behind, and--jsonprints the same data for scripts. - Agents: the Ballmac MCP server has
get_changes(what changed since a version, with breaking changes flagged) andget_tests(the test for an item).
Limits
- Merging is line based and needs
giton your PATH (it usesgit merge-file; no repository is needed). Without git, edited files get the.ballmac-newtreatment. - A merge that applies cleanly can still be wrong in meaning. Run the tests, and read the changelog note.
- Themes are CSS variables, not files, so they are not merged. Re-apply a theme with the shadcn CLI.
- Examples and demos are not tracked, only the items you install. Needs Node.js 20 or later and a project with a
components.json.
The shadcn CLI is documented in CLI & registry. Something wrong? Tell us.