Dev Notes: Building GeraRush on React Native + Expo in a Monorepo
Published 21 April 2026 · 10 min read
core-auth, core-analytics and core-ui with every other Gera product, and was built inside the Gera monorepo with Turborepo concurrency capped at 2 on a 16GB Mac Mini. The one call we would redo: we should have picked Skia earlier.The stack
- Expo SDK 50 (managed workflow, EAS for builds)
- react-native-game-engine for the simulation loop
- react-native-reanimated + Worklets for gesture handling
- Zustand for run-state + persisted player state
- @gera/core-auth, @gera/core-analytics, @gera/shared-assets from the monorepo
- Next.js + React on the rush.gera.games marketing site (this one)
Why react-native-game-engine
RNGE is a light wrapper around requestAnimationFrame that treats entities as plain objects and systems as pure functions. For a lane-based runner with fewer than 200 simultaneous entities it is the path of least resistance. The trade-off is rendering: RNGE leans on View and Image, which is fine up to ~60fps with modest scenes but bites when you add particle effects.
The Skia regret
We shipped V1 with RN Views. Once we added coin particles, shield burst effects, and the world-change transition flash, we saw frame drops on mid-tier Android. The right fix, with hindsight, was @shopify/react-native-skia from day one. We are migrating particle-heavy effects incrementally in a V1.1.
Monorepo mechanics
The entire Gera portfolio — 29 products, including GeraRush — lives in one monorepo, managed by Turborepo. A few concrete constraints:
turbo.jsonconcurrency is pinned to the string"2"— we have OOM’d the Mac Mini many times when it crept up.- Jest is capped at
maxWorkers: 2with--max-old-space-size=384. CI relaxes this; local does not. - Shared packages live under
packages/*. For game-specific assets we have@gera-games/shared-assetswhich keeps sprites, SFX and fonts reusable across all four Gera games (City, Tycoon, Quest RPG, Rush).
Auth + analytics for free
The big win of being in the monorepo is that GeraRush gets the same core-auth package as GeraEats, GeraClinic, GeraMarket and every other product. Coins earned in the game land in the same wallet, because the wallet is a core service, not a game feature. Analytics goes through a single PostHog pipeline; errors through a single Sentry project.
Input latency is the whole game
Endless runners live or die on perceived input latency. The actual controls are all gesture-based, so we put the gesture recogniser on a Reanimated worklet and had the swipe buffer live on the UI thread. Inputs are committed to the game state on the next animation frame, not after a JS bridge round-trip. This sounds obvious but saved us probably 30ms off the perceived responsiveness.
What we shipped
V1 has four worlds, five power-ups, a daily challenge, a global leaderboard and full GeraCoin integration. It uses the same auth you use on gera.services and credits coins to the same wallet. We built it in the monorepo alongside the other 31 products, on a 16GB Mac Mini, with two developers and a lot of coffee.
What’s next
- Skia migration for particles
- V1.1 world: GeraFarm fields with crop hazards
- Cross-game quests with GeraCity
- Real-time 1v1 mode (experimental)
Try what we built.
Download GeraRush