Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1a5a5da
chore: wire the bestax-migrate workspace into repo tooling
claude Jul 19, 2026
36f385d
feat(bestax-migrate): add react-bulma-components → bestax-bulma codem…
claude Jul 19, 2026
2df575f
docs: add the bestax-migrate skill and react-bulma-components migrati…
claude Jul 19, 2026
99d4d28
docs: fix Grid links in migration guides to relative paths
claude Jul 19, 2026
a5a3068
test(bestax-migrate): add real-world corpus validation script
claude Jul 19, 2026
8cfe21b
fix(bestax-migrate): faithfulness fixes found by visual story comparison
claude Jul 19, 2026
bde3619
feat(bestax-migrate): migrate stylesheets and package.json dependencies
claude Jul 19, 2026
b323f8f
fix(bulma-ui): remove typesVersions map that broke node10 type resolu…
claude Jul 19, 2026
cc423a7
fix(bestax-migrate): harden the codemod against real-world app patterns
claude Jul 19, 2026
441f058
docs: fold validation-campaign findings into the migration skill and …
claude Jul 19, 2026
6c1e141
fix(bestax-migrate): declare @allxsmith/bestax-bulma as a runtime dep…
claude Jul 19, 2026
4425c7a
Merge remote-tracking branch 'origin/main' into claude/react-bulma-mi…
claude Jul 19, 2026
0454a4f
fix(bestax-migrate): add the extras @use to partial-only SCSS files
claude Jul 19, 2026
d114a73
test(bestax-migrate): clean up CLI temp dirs in afterEach
claude Jul 19, 2026
774e584
chore: cover .mjs in the prettier globs and format the stragglers
claude Jul 19, 2026
387732a
docs: correct Tile flagging and skill workflow order per review
claude Jul 19, 2026
78e9ed4
docs: fix MDX parse error in migrate.mdx and use American 'afterward'
claude Jul 19, 2026
499eecb
fix(bestax-migrate): merge user className into plain-element rewrites
claude Jul 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ jobs:
path: |
bulma-ui/coverage
create-bestax/coverage
bestax-migrate/coverage
retention-days: 7

- name: Archive Bundle Stats
Expand Down Expand Up @@ -239,3 +240,13 @@ jobs:
run: |
git log -1 --show-signature
pnpm exec semantic-release

- name: Semantic Release (bestax-migrate)
working-directory: bestax-migrate
env:
GIT_COMMITTER_EMAIL: ${{ secrets.GIT_COMMITTER_EMAIL }}
GIT_COMMITTER_NAME: ${{ secrets.GIT_COMMITTER_NAME }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git log -1 --show-signature
pnpm exec semantic-release
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ pnpm-lock.yaml

# Generated by scripts/gen-component-catalog.mjs
skills/bestax-custom-component/references/component-catalog.md

# Codemod test fixtures: byte-exact expected transform output — reformatting
# them would change what the tests assert. The kitchen-sink fixture app is
# migration *input* (react-bulma-components source), also left untouched.
**/__testfixtures__/
bestax-migrate/fixtures/
bestax-migrate/.e2e-tmp/
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,15 @@ function Root() {

## 📦 What's in this repo

| Path | Package | What it is |
| ---------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| [`bulma-ui/`](bulma-ui/) | [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) | The component library |
| [`create-bestax/`](create-bestax/) | [`create-bestax`](https://www.npmjs.com/package/create-bestax) | Project scaffolder — `npm create bestax@latest` |
| [`docs/`](docs/) | — | Docusaurus source of [bestax.io](https://bestax.io) |
| [`skills/`](skills/) | — | [Agent Skills](https://bestax.io/docs/skills/intro) for coding agents (also bundled into `create-bestax`) |

The two packages are versioned and released independently.
| Path | Package | What it is |
| ------------------------------------ | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| [`bulma-ui/`](bulma-ui/) | [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) | The component library |
| [`create-bestax/`](create-bestax/) | [`create-bestax`](https://www.npmjs.com/package/create-bestax) | Project scaffolder — `npm create bestax@latest` |
| [`bestax-migrate/`](bestax-migrate/) | [`bestax-migrate`](https://www.npmjs.com/package/bestax-migrate) | Codemods for migrating existing apps from other React Bulma libraries |
| [`docs/`](docs/) | — | Docusaurus source of [bestax.io](https://bestax.io) |
| [`skills/`](skills/) | — | [Agent Skills](https://bestax.io/docs/skills/intro) for coding agents (also bundled into `create-bestax`) |

The published packages are versioned and released independently.

---

Expand Down
3 changes: 3 additions & 0 deletions bestax-migrate/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
coverage
.e2e-tmp
8 changes: 8 additions & 0 deletions bestax-migrate/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Codemod fixtures are byte-exact expected transform output; reformatting them
# would change what the tests assert. Mirrors the repo-root .prettierignore for
# package-local prettier runs (pnpm --filter bestax-migrate format:check).
src/sources/*/__testfixtures__/
fixtures/
.e2e-tmp/
dist/
coverage/
65 changes: 65 additions & 0 deletions bestax-migrate/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# bestax-migrate — codemods onto bestax-bulma

jscodeshift-based CLI (`pnpm dlx bestax-migrate <source> <paths…>`) that migrates existing
apps from other React Bulma libraries to `@allxsmith/bestax-bulma`. Multi-source by design:
each source library registers in `src/sources/registry.ts`; the first is
`react-bulma-components` (v4 only).

## Hard rules

- **react-bulma-components is NEVER installed anywhere in this repo** (supply-chain
policy). Fixtures are read as _text_ (`__testfixtures__`, `fixtures/kitchen-sink`); the
migration _input_ is never typechecked or executed. Validation typechecks the migrated
_output_ against the workspace `@allxsmith/bestax-bulma`.
- Mapping-table first: `src/sources/react-bulma-components/mapping.ts` is the single source
of truth. Every RBC v4 export must have an entry (`mapped`/`partial`/`todo`) — the
`mapping-coverage` test walks the vendored `RBC_EXPORTS` list against it. New coverage is
a table edit (plus a `special` handler in `specials.ts` when structure changes).
- Anything unsafe gets a `// TODO(bestax-migrate): <hint>` comment on the enclosing
statement + a report entry — never a silent skip, never a best-guess rewrite of dynamic
values.

## Architecture

- `src/cli.ts` — file walk + per-type routing (js-ish → jscodeshift transform,
.scss/.sass → `transformStyles`, nearest package.json → `updateDependencies`) with an
in-process runner (NOT jscodeshift's worker Runner: fragile from ESM, hides per-file
stats). `src/runner.ts` is shared by CLI and tests. `--css bestax|bulma|keep` picks the
stylesheet target; `--no-deps` skips the manifest step.
- `src/sources/react-bulma-components/`: `transform.ts` (orchestration: imports + css →
per-element special/rename/responsive/props → import rewrite), `mapping.ts` (data),
`specials.ts` (structural handlers), `props.ts` (PropAction interpreter), `responsive.ts`
(breakpoint-object flattening), `styles.ts` (line-based SCSS/SASS transform — Sass has
no jscodeshift parser, so it only rewrites provably-safe patterns), `deps.ts`
(package.json updater; never runs an install), `jsx-utils.ts` (AST helpers).
- Components with no bestax equivalent (Element, Tile) keep a trimmed, TODO-annotated RBC
import so the code still runs during gradual migration.

## Testing

- Fixture pairs: `__testfixtures__/<case>.input.tsx` → `.output.tsx`, exact-match. To
update outputs after changing the transform, regenerate them by running the built
transform over the inputs and reviewing the diff — do not hand-edit drift in.
- Kitchen sink e2e (`e2e/kitchen-sink.test.ts`): copies `fixtures/kitchen-sink` to
`.e2e-tmp/`, migrates it, and runs `tsc --noEmit` on the output against the built
bulma-ui (`turbo` orders the build; see `bestax-migrate#test` in root turbo.json).
`src/leftovers.tsx` holds every intentionally-unsupported pattern — excluded from the
typecheck, asserted via TODO rules instead. New unsupported patterns go there; new
supported ones go in the other fixture files, which must stay TODO-free.
- Fixtures and `.e2e-tmp` are excluded from tsc/eslint/prettier at both root and package
level (root `eslint.config.js` + both `.prettierignore`s) — keep them that way.
- Real-world corpus: `pnpm --filter bestax-migrate validate:corpus` fetches the
react-bulma-components repo's own MIT-licensed Storybook stories (pinned SHA, text only,
into `.e2e-tmp/`) and scores the transform over them — fails on any crash or
unknown-component TODO. Deliberately NOT in CI (no third-party fetches in the pipeline);
run it before releases and after mapping changes, and eyeball the before/after diffs it
writes to `.e2e-tmp/corpus-out/`.

## Releases

Independent semantic-release, keyed off the `bestax-migrate` commit scope
(`release.config.js`, tag `bestax-migrate@x.y.z`). The skill lives at repo-root
`skills/bestax-migrate/` and is deliberately **not** bundled into create-bestax (existing
sites only) — keep `create-bestax/scripts/sync-skills.mjs` untouched. When the mapping
gains or loses coverage, update `skills/bestax-migrate/references/` and the docs migration
guide in the same PR.
59 changes: 59 additions & 0 deletions bestax-migrate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# bestax-migrate

Codemods that migrate existing React apps to [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) — the actively maintained React component library for **Bulma v1**.

Currently supported source libraries:

| Source | Status |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [`react-bulma-components`](https://github.com/couds/react-bulma-components) (v4) | ✅ All 32 components mapped (a few patterns are flagged as TODOs) |

## Usage

```bash
# Preview what would change (no writes)
pnpm dlx bestax-migrate react-bulma-components src/ --dry

# Apply the migration
pnpm dlx bestax-migrate react-bulma-components src/
```

npm and yarn work too: `npx bestax-migrate …` / `yarn dlx bestax-migrate …`.

The codemod uses [jscodeshift](https://github.com/facebook/jscodeshift) to:

- rewrite `react-bulma-components` imports to `@allxsmith/bestax-bulma` (including `const { Input } = Form` destructuring and namespace imports)
- rename components and compound sub-components (`Form.Textarea` → `TextArea`, `Card.Footer.Item` → `Card.FooterItem`, `Hero.Footer` → `Hero.Foot`, …)
- convert props (`renderAs` → `as`, `loading` → `isLoading`, numeric spacing/text sizes → string unions, `textAlign="center"` → `textAlign="centered"`, …)
- flatten responsive breakpoint objects (`mobile={{ size: 4 }}` → `sizeMobile={4}`)
- restructure patterns bestax models differently (`Table.Container`, Navbar dropdowns, `Form.Help`, icon-font children → `<Icon name=…>`)
- migrate stylesheets: CSS imports converge on `@allxsmith/bestax-bulma/bestax.css`, and SCSS files move from Bulma 0.9's `@import` + `$var !default` overrides to `@use 'bulma/sass' with (…)` plus `@use '@allxsmith/bestax-bulma/scss/extras'`
- update `package.json`: remove `react-bulma-components`, add `@allxsmith/bestax-bulma`, bump `bulma` to `^1`, and swap the dead `node-sass` for dart `sass` (no install is ever run)

Anything without a safe automatic conversion is left in place with a `// TODO(bestax-migrate): …` comment, and the run ends with a report of every TODO by file and line. TODOs are expected output, not errors — resolve them with the [migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components), or let the [`bestax-migrate` Agent Skill](https://bestax.io/docs/skills/intro) walk them for you:

```bash
npx skills add https://github.com/allxsmith/bestax --skill bestax-migrate
```

## Options

| Flag | Description |
| -------------------- | -------------------------------------------------------------- |
| `--dry`, `-d` | Report what would change without writing files |
| `--print`, `-p` | Print transformed sources to stdout |
| `--extensions`, `-e` | File extensions to include (default `js,jsx,ts,tsx,scss,sass`) |
| `--css <mode>` | Stylesheet target: `bestax` (default), `bulma`, or `keep` |
| `--no-deps` | Skip updating package.json dependencies |

## After the codemod

1. Run your package manager's install (the codemod rewrote `package.json` but never installs)
2. Search for `TODO(bestax-migrate)` and resolve each comment
3. Typecheck/build and review the rendered app

Full walkthrough: [react-bulma-components migration guide](https://bestax.io/docs/guides/getting-started/migration/react-bulma-components).

## License

MIT © Alex Smith
Loading
Loading