rn-version-manager
v1.0.0
Published
CLI tool to manage version and build numbers across React Native CLI projects
Downloads
149
Maintainers
Readme
rn-version-manager
Keep your app's version and build number in sync across every file a React Native CLI project needs them in — one command instead of four manual edits.
rnvm reads and writes:
package.json—versionandroid/app/build.gradle—versionName,versionCodeios/<App>/Info.plist—CFBundleShortVersionString,CFBundleVersionios/<App>.xcodeproj/project.pbxproj—MARKETING_VERSION,CURRENT_PROJECT_VERSION
No runtime dependencies. No changes to your app's package.json scripts. It's a standalone binary (rnvm) you call from your terminal or from a CI/CD pipeline (Fastlane, Jenkins, GitHub Actions, etc.).
TOC
Installation
yarn add -D rn-version-manageror
npm install --save-dev rn-version-managerGetting Started
Run once, interactively, from your project root:
npx rnvm initinit autodetects your Android build.gradle and iOS Info.plist/project.pbxproj paths and asks you to confirm each one with an arrow-key menu:
🤖 Android
Found: android/app/build.gradle
● Yes, use this path
○ No, I'll enter my own path
○ Skip Android entirely
↑/↓ to navigate · Enter to confirmIf a platform isn't detected — or your project only ships one platform — you get a menu to enter the path manually or skip that platform entirely. At least one platform must stay configured; init refuses to write a config if you skip both.
This writes .rnvm/config.json to your project root.
[!WARNING] Commit
.rnvm/config.jsonto git. Every command other thaninitreads from it — nothing is re-autodetected on every run, which is what makesrnvmsafe to call from CI/CD. If the file is missing, commands fail with a clear "runrnvm initfirst" error instead of guessing at paths.
To reconfigure later (paths changed, a platform was added or dropped), just run rnvm init again — it fully overwrites the existing config.
Commands
| Command | Description | Reads/writes |
| -------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------- |
| init | Detect native paths, write .rnvm/config.json | writes .rnvm/config.json |
| status | Show current version/build across all configured files | read-only |
| set <semver> | Set version everywhere and increment build number | package.json, build.gradle, Info.plist, project.pbxproj |
| set-version <semver> | Set version everywhere (build number untouched) | package.json, build.gradle, Info.plist, project.pbxproj |
| set-build-number <n> | Set build number everywhere (version untouched) | build.gradle, Info.plist, project.pbxproj |
| reset-build-number | Reset build number to 1 everywhere | build.gradle, Info.plist, project.pbxproj |
Every command that writes files supports --dry-run to preview the change first.
rnvm init
Interactive, one-time setup. Detects native paths and writes .rnvm/config.json. See Getting Started above. Not intended to run unattended in CI — it's meant to be run once by a human and its output committed to git.
rnvm status
Reads (never writes) the version/build number from every configured file and reports whether they're in sync.
Examples
rnvm status📦 package.json 1.0.2
🤖 Android versionName 1.0.2 versionCode 26
🍎 iOS Info.plist shortVersion 1.0.2 bundleVersion 26
🍎 iOS project.pbxproj MARKETING_VERSION 1.0.2 CURRENT_PROJECT_VERSION 26
✅ Version in sync
✅ Build number in syncIf a platform was skipped during init, its line reads (not configured — skipped in .rnvm/config.json) instead, and it's excluded from the sync check.
rnvm set <semver>
Sets the version everywhere and increments the build number by 1, as a single atomic operation. This is the one you want for a normal release bump.
Examples
rnvm set 1.5.2🚀 Setting version to 1.5.2 and incrementing the build number...
📦 Updated:
- package.json
- Android build.gradle
- iOS Info.plist
- iOS project.pbxproj
✅ Version and build number updated successfully.
📱 Version: 1.5.2
🔢 Build number: 26 → 27rnvm set-version <semver>
Sets the version everywhere, leaving the build number untouched. Use this when you want to control the build number separately (e.g. your CI increments it, not the developer).
Examples
rnvm set-version 1.5.2rnvm set-build-number <n>
Sets an exact build number everywhere, leaving the version untouched. <n> must be a positive integer.
Examples
rnvm set-build-number 42rnvm reset-build-number
Shorthand for rnvm set-build-number 1.
Examples
rnvm reset-build-number--dry-run
Add to set, set-version, set-build-number, or reset-build-number to preview the change without writing anything.
Examples
rnvm set-version 1.5.2 --dry-run🔍 [dry-run] would set version to 1.5.2 in:
- package.json
- Android build.gradle
- iOS Info.plist
- iOS project.pbxproj--version / --help
rnvm --version prints rnvm's own installed version. rnvm --help prints the command usage summary.
The Config File
.rnvm/config.json, written by init, is the single source of truth every other command reads from:
{
"configVersion": 1,
"generatedBy": "1.0.0",
"android": { "buildGradle": "android/app/build.gradle" },
"ios": "skip"
}| Field | Meaning |
| --------------- | ------------------------------------------------------------------------------------------------- |
| configVersion | On-disk schema version — bumped only if this file's shape changes; reserved for future migrations |
| generatedBy | The rnvm version that wrote the file, for humans reading it; nothing reads it back for logic |
| android | Either { "buildGradle": "<relative path>" }, or the literal string "skip" |
| ios | Either { "infoPlist": "<relative path>", "projectPbxproj": "<relative path>" }, or "skip" |
"skip" is explicit on purpose — a missing key would leave a reader guessing whether the platform was forgotten or intentionally excluded. Android-only and iOS-only projects are fully supported; at least one platform has to stay configured, though.
Using it in CI/CD
Every command except init only reads the already-committed .rnvm/config.json — no interaction, no autodetection at pipeline time:
# Fastlane, Jenkins, GitHub Actions, etc.
npx rnvm set 1.2.0If the config is missing, or one of its paths no longer exists on disk, the command fails immediately with a clear, non-interactive error rather than silently doing the wrong thing — see Troubleshooting.
Troubleshooting
| Error | Cause | Fix |
| ------------------------------------------------------------------------------ | ------------------------------------------------------- | --------------------------------------------------------- |
| No package.json found in <dir> | Not run from inside a project root | cd into the project root (where package.json lives) |
| No .rnvm/config.json found in <dir>. Run "rnvm init" first. | init was never run, or its output wasn't committed | Run rnvm init |
| Path from .rnvm/config.json no longer exists: <path>. Run "rnvm init" again. | A configured native file was moved, renamed, or deleted | Run rnvm init again to re-detect and rewrite the config |
| At least one platform must be configured... | Both Android and iOS were skipped during init | Run rnvm init again and configure at least one platform |
| Invalid version format. Use semantic versioning... | <semver> argument isn't a valid semver string | Use e.g. 1.2.3 or 1.2.3-beta.1 |
| .rnvm/config.json is not valid JSON | The config file was hand-edited into an invalid state | Run rnvm init again to regenerate it |
Requirements
- Node.js >= 18
- A React Native CLI project (not Expo-managed) — the standard
android/+ios/native folders
License
MIT
