Update from upstream
Pull fixes and new modules from a newer ReadyNative release into your app - with modules/ kept, after finalizing, and on the Free tier.
ReadyNative is a template you clone, not a dependency you install, so updates arrive through
git. Every release is one commit on main of your tier repo (ready-native-free,
ready-native-starter or ready-native-pro), tagged v<x.y.z>-sdk57. In the Starter and Pro
repos, each of those commits is the tree before setup: modules/ present, the default preset
applied at the root.
How you take an update depends on what setup left you with. Check once:
ls modulesmodules/is there - you ransetup --keep-modules. Merge the release, then re-apply your selection: With modules kept.modules/is gone - the tree is finalized, the default. A merge would fight you on every moved file, so you port the diff instead: Finalized tree.- Free tier - the release is already finalized the same way yours is, so a plain merge works: Free tier.
Hear about releases
On GitHub, open your tier repo, click Watch → Custom, tick Releases and apply. You get a notification for every release and nothing else. Each release has GitHub Release notes on what changed - read them before you pull.
Set up the remote once
git remote add upstream https://github.com/ReadyNative/ready-native-pro.git
git fetch upstream --tagsSwap pro for your tier. If you cloned the tier repo and never repointed origin, it already
is the upstream - use origin below instead. The fetch uses your GitHub access to the tier repo,
which comes with lifetime updates.
List the releases to find the one you're on and the one you want:
git tag --list 'v*' --sort=-v:refnameWith modules kept
The release and your tree have the same layout, so git can merge it:
git fetch upstream --tags
git merge v1.2.0-sdk57Expect conflicts in three kinds of file:
- Files owned by a module you didn't pick show up as modify/delete conflicts: upstream changed
them, you don't have them. Keep them deleted with
git rm <file>. - Generated files (
src/providers.tsx,src/lib/env.ts,src/ui/index.ts,.env.example,.readynative.json,package.json) - take either side;setuprewrites them next. - Files you edited (
readynative.config.ts, your screens) - resolve them the usual way.
Then re-apply your selection against the merged module sources and re-check:
bun run setup --yes --keep-modulesbun run typecheckbun run lintbun run doctorsetup is idempotent: with the same selection it rewrites only files whose content changed, so
the diff you commit is the update and nothing else.
Finalized tree
Finalizing moved files (modules/<category>/<option>/files/src/lib/auth.ts became
src/lib/auth.ts, src/ui/<stack>/* became src/components/ui/*) and deleted modules/, so
git merge would report every upstream change to a module as a modify/delete conflict. Take the
diff between the two release tags instead and apply it at the paths your tree uses.
git apply --3way falls back to a three-way merge when your copy of a file has drifted from the
release, so edits you made survive.
Start by looking at what changed:
git diff --stat v1.1.0-sdk57 v1.2.0-sdk57A module you use. --relative strips the module folder from the paths, so the patch lands at
the root where setup copied the files:
git diff v1.1.0-sdk57 v1.2.0-sdk57 --relative=modules/auth/supabase/files | git apply --3wayRepeat it for each module you picked (selection in .readynative.json lists them). Changes to
a module's module.json - a new dependency, env key or config plugin - don't apply themselves:
read that part of the diff and add them to package.json, .env.example / src/lib/env.ts or
modules.app in .readynative.json by hand.
Your UI kit. Upstream keeps it at modules/ui/<your-stack>/files/src/ui/<your-stack>; strip
that and point --directory at where the kit lives now. For nativewind4 (swap both occurrences
for your stack):
git diff v1.1.0-sdk57 v1.2.0-sdk57 --relative=modules/ui/nativewind4/files/src/ui/nativewind4 | git apply --3way --directory=src/components/uiUpstream imports read @/ui; yours read @/components/ui. A hunk that touches an import line
may conflict - resolve it to @/components/ui.
Core files - everything outside modules/:
git diff v1.1.0-sdk57 v1.2.0-sdk57 -- . ':(exclude)modules' | git apply --3way --exclude='src/ui/*'git apply is all-or-nothing: when the patch touches a file setup removed from your tree
(the demo screens, scripts/setup.ts, generated files), it prints
<path>: does not exist in index and changes nothing. Add an --exclude=<path> for each path
it names and run it again. Then re-install and re-check:
bun installbun run typecheckbun run lintSwitching a module is not an update
Restoring modules/ from upstream doesn't bring the module system back to a finalized tree. To
move to another option, see Can I change a module after
setup?.
Free tier
ready-native-free is finalized before it's published, with the same stack every time, so its
releases and your clone share one layout:
git remote add upstream https://github.com/ReadyNative/ready-native-free.git
git fetch upstream --tags
git merge v1.2.0-sdk57Conflicts only show up in files you both changed.
Lifetime updates
A paid license includes lifetime updates (section 5 of LICENSE), and your GitHub access to
the repo stays, so clone, fetch and the diffs above keep working for every future release.
License → Lifetime updates says what "lifetime" means.
SDK upgrades
The tag suffix is the Expo SDK: -sdk57 releases target SDK 57. When upstream moves to a new
SDK, take the last -sdk57 release first, then the first -sdk58 one as its own step. Run
bunx expo install --fix and bunx expo-doctor after it, then typecheck and lint as usual.