# callstack/react-native-builder-bob: two CLIs and the parts of library publishing nobody documents

> Builder Bob is a JavaScript monorepo publishing react-native-builder-bob and create-react-native-library. The interesting content is in what its templates assume about Android tooling, Babel, Vite conditions, and Windows paths.

**callstack/react-native-builder-bob** — Simple set of CLIs to scaffold and build React Native libraries for different targets

- Repository: https://github.com/callstack/react-native-builder-bob
- Website: http://oss.callstack.com/react-native-builder-bob/
- Stars: 3,229 · Forks: 228
- Language: JavaScript
- License: not declared
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/callstack-react-native-builder-bob

## Two packages, one repository, released together

The repository description is a plain statement of intent: a simple set of CLIs to scaffold and build React Native libraries for different targets. Two verbs, two packages. `create-react-native-library` handles the scaffolding, and `react-native-builder-bob` handles building. The README carries a version badge for each, which is the visible reminder that they are independently published artifacts rather than one tool with two entry points.

The release record makes the relationship concrete. On 2026-09-08 both packages shipped on the same day: `react-native-builder-bob` at 0.43.1 and `create-react-native-library` at 0.63.1. The previous recorded release, `react-native-builder-bob` at 0.43.0, came on 2026-06-16. So the build package is on a 0.4x line and the scaffolder is on a 0.6x line, which means the scaffolder has been iterating faster, which fits since templates need to track whatever the current Android and React Native toolchain expects.

The project sits at 3,229 stars, 228 forks and 22 open issues on the `main` branch, with the last push recorded on 2026-09-08. An issue queue that small relative to the star count is unusual and worth reading as a signal: either the surface area is genuinely narrow, or the tool is adopted without much back and forth. The topic list is only `hacktoberfest`, `react-native` and `template`, which is consistent with the narrow reading.

## A Yarn 4 monorepo with Lerna Lite and a single test script

The tree is short and it is a monorepo with `yarn`, with `packages/*` and `docs` declared as workspaces. The root `package.json` pins `packageManager` to `yarn@4.11.0`, so the Yarn version is enforced rather than assumed, and `.yarnrc.yml` and `.yarn/` alongside it are the standard Yarn Berry footprint. There is a `.nvmrc` for the Node version.

Versioning and publishing run through Lerna Lite, with `@lerna-lite/cli`, `@lerna-lite/publish` and `@lerna-lite/run` as dev dependencies and `lerna.json` at the root. Lefthook handles git hooks through `lefthook.yml`, and ESLint is configured through the flat `eslint.config.mjs` file, which matches the flat-config ESLint version pinned in devDependencies.

The interesting detail is the script list, because it reveals where the test surface actually is:

The script list in the root package.json is short: lint, typecheck, watch, test, docs and release.

The `test` script is `yarn workspace react-native-builder-bob test`, scoped to one workspace rather than the monorepo. The scaffolder has no test target of its own, so its templates are validated indirectly, by the projects that use them. The `watch` script is more unusual: it runs `concurrently` over `yarn typecheck --watch` and a parallel `lerna run prepare -- --watch`, meaning the build outputs of every package are regenerated on change. That is a good fit for a tool whose own output is generated code.

## What 0.43.0 broke, and the migration it documents

The 0.43.0 release notes are the most substantive entry in the record and they are worth reading in full rather than skimming, because they contain an explicit migration for anyone affected.

The feature is described as using a unique name for the exports condition for source. In package.json terms, a library built by Builder Bob exposes its source through an export condition, and that condition had a name that collided with other tooling in a Vite setup. The release renames it. The notes state plainly that this is a breaking change for libraries using `react-native-builder-bob/vite-config`, and they tell you what to add to preserve existing behavior: a `conditions: ['source']` entry under `resolve` in your Vite config.

The same release drops `react-native-builder-bob/metro-config` and points at an external package, `react-native-monorepo-config`, as the replacement. Bundling Metro configuration was a reasonable thing to do when the project started and a liability once configuration needs to track React Native versions independently of the build tool, so moving it out is the kind of change that reduces this repository's maintenance surface.

Both changes are the sort that only cause pain in a specific configuration, which is why a project with 22 open issues can ship two breaking changes in a minor release without a firestorm. The affected surface is libraries doing monorepo Vite development with Metro, a narrow combination, and the notes handle it in three sentences plus a diff.

## The 0.43.1 pair is a snapshot of the Android toolchain moving underneath

Two packages, four fixes, one release day. Reading them together is more informative than any single entry.

In `react-native-builder-bob` 0.43.1, there are two fixes. One handles `bob init` producing incorrect paths on Windows (#954), which is a path separator bug and the kind of report that arrives the day someone tries the tool on a different OS than the author. The other gracefully handles Expo calling Babel config without a filename, which is a compatibility fix for a change in how Expo invokes Babel.

In `create-react-native-library` 0.63.1, there are three. One adds `ndkVersion` to the Nitro library templates (#951), contributed by an outside contributor, which means the generated templates now pin the Android NDK version rather than inheriting whatever the machine happens to have. One handles AGP9's built-in Kotlin support, which is Android Gradle Plugin 9 moving Kotlin support into the plugin itself, and a template that already declared Kotlin configuration would collide with that. The third removes `expo-dev-client` from the Expo example, which is a dependency trim on a template that shipped with something it did not need.

Taken as a group, these are four fixes about the ground shifting rather than about the tool being wrong. AGP9 changing where Kotlin support lives, Expo changing how it calls Babel, and an NDK version that needs pinning are all upstream decisions, and a scaffolder's job is to be at the right position relative to them.

## The alternative list is the most opinionated part of the README

Under Alternatives, the README names three other tools: `create-expo-module` from the Expo documentation, `create-nitro-module`, and `react-native-module-init`, which is marked unmaintained. The first two are current, the third is flagged, and the fact that all three appear in a project by Callstack is a reasonable signal about the state of the scaffolding ecosystem rather than about any one tool.

The Acknowledgments section is worth reading for a different reason. The project credits `create-react-native-module`, `react-native-webview` and `RNNewArchitectureLibraries` as inspirations. The second and third are the pattern most React Native library authors actually learn from, since both are libraries that ship real native code and had to solve the publishing problem before the tooling caught up. `RNNewArchitectureLibraries` in particular points at the New Architecture, and the presence of Nitro templates in the 0.63.1 release notes shows the project is tracking that direction rather than ignoring it.

Documentation is hosted separately at oss.callstack.com, not in this repository, though the docs source is the `docs` workspace and runs locally with `yarn docs dev`. The division is a deliberate one for a tool maintained by a company: the repository holds the CLIs and their tests, and the site holds the guides.

## How this gets developed day to day

The README's development section is short but complete, which is a good sign. Setup is `yarn` at the root, since it is a workspaces monorepo. Watch mode rebuilds on change. Type checking and linting both have to pass before a pull request, with `yarn typecheck` and `yarn lint`, and `yarn lint --fix` handles formatting.

```sh
yarn typecheck
yarn lint
```

Testing the CLI locally rather than against the published package has its own command, pointing at the executable inside the package directory rather than at a globally installed copy. That is the correct arrangement for a CLI, since the failure mode of CLI development is otherwise testing a stale installed version and concluding the fix did not work.

Publishing is gated on write access to both the GitHub repository and the npm organization, which is the right constraint for a package that gets installed by `npx`. It requires a `GH_TOKEN` environment variable, and then `yarn lerna publish` bumps the version and publishes, also pushing changelogs to GitHub for each package. Prereleases are a separate path: set `preId` and `preDistTag` in `lerna.json`, adjust `allowBranch` if needed, then publish with `--conventional-commits --conventional-prerelease --preid next`. Stable releases remove those fields and use `--conventional-commits --conventional-graduate` instead.

That prerelease mechanism is why the scaffolder can ship breaking template changes without waiting. A `next` tag lets a template change reach users on a controlled cadence, and the graduate step is what moves it to latest.

## Conclusion

This is a small repository doing a narrow job, and the release history is where the real design decisions are visible. Two packages, one for scaffolding and one for building, released in lockstep on the same day, with the fixes in each telling you what the ecosystem underneath them was doing at that moment. The 0.43.0 release is the one to read carefully, because dropping `react-native-builder-bob/metro-config` in favour of an external package and renaming the source exports condition is a real breaking change with a migration path spelled out in the notes rather than left to be discovered. The 0.43.1 pair is the same story at a smaller scale, with `bob init` producing incorrect paths on Windows (#954) and the nitro templates gaining an `ndkVersion` field (#951), both of which are the kind of fix that only appears once real users hit real platforms. At 3,229 stars with only 22 open issues, the issue queue is small enough that a maintainer is likely reading it, and the test command is scoped to a single workspace rather than the whole monorepo, which tells you where the actual test surface sits. If you are evaluating it, scaffold with `create-react-native-library` first and read the generated Android config before writing any of your own, because the template is where Builder Bob's opinion about your build lives.

## FAQ

### What does React Native Builder Bob do?

It is a set of CLIs for scaffolding and building React Native libraries for different targets. The repository publishes two npm packages, create-react-native-library for generating a new library project and react-native-builder-bob for building it once it exists. Documentation is hosted at oss.callstack.com.

### How do I run the Builder Bob CLIs locally during development?

The repository is a yarn workspaces monorepo, so setup is `yarn` at the root. `yarn watch` rebuilds package outputs on change, `yarn typecheck` and `yarn lint` must pass before a pull request, `yarn docs dev` runs the documentation site, and to test a CLI against your working copy rather than the published package you invoke the executable inside the package directory directly.

### What changed in Builder Bob 0.43.0 and how do I migrate?

0.43.0 gave the source exports condition a unique name, which is a breaking change for libraries using react-native-builder-bob/vite-config. Add `conditions: ['source']` under `resolve` in your Vite config to preserve existing behavior. The release also dropped react-native-builder-bob/metro-config, and the notes point to react-native-monorepo-config as the replacement.

### How does Builder Bob publish prerelease and stable versions?

Publishing needs write access to the GitHub repo and the npm organization, plus a GH_TOKEN environment variable, then `yarn lerna publish`. For a prerelease you set preId and preDistTag in lerna.json and publish with `--conventional-commits --conventional-prerelease --preid next`. For a stable release you remove those fields and use `--conventional-commits --conventional-graduate`.

## Sources

- [callstack/react-native-builder-bob on GitHub](https://github.com/callstack/react-native-builder-bob)
- [Issues](https://github.com/callstack/react-native-builder-bob/issues)
- [Project website](http://oss.callstack.com/react-native-builder-bob/)
- [README](https://github.com/callstack/react-native-builder-bob/blob/main/README.md)
- [Releases](https://github.com/callstack/react-native-builder-bob/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/callstack-react-native-builder-bob
