Can you build a game with React Native? What I learned from 7 games
Yes, and at 60 FPS, as long as you follow a few rules: no disk or network during gameplay, animations on the native thread, and engines written as pure functions. The real technical decisions behind my 7 games.

Yes, you can build a game with React Native and run it at 60 FPS, as long as it’s a puzzle, board, or casual game and you follow a few rules: no disk or network during gameplay, animations on the native thread, and game logic kept separate from the UI. For a 3D game or one with complex physics, a dedicated game engine is the better choice.
I’m saying this after building 7 games with React Native and Expo, all for Android and iPhone from a single codebase: three Sudoku variants, two Tetris-style block games, a block puzzle, and a color game with evolving pieces. This isn’t a framework comparison (that’s in React Native vs Flutter): these are the concrete technical decisions that worked for me and the bugs that only showed up on real phones.
Which games did I build, and what was hardest in each?
| Game | Mechanic | Hardest technical part |
|---|---|---|
| Sudoku Play | 9×9 Sudoku with 6,000 puzzles and an adventure mode | Holding 60 FPS while autosaving and syncing |
| Killer Sudoku Play | Sudoku with cages and sums | Drawing cages over the grid without losing performance |
| Color Sudoku Play | Sudoku with 9 colors instead of numbers | Real-time duels with consistent coin stakes |
| Block Puzzle Play | 8×8 board with drag and drop | Dragging pieces at 60 FPS, even on low-end phones |
| Block Drop Play | Tetris on a 10×20 board | SRS rotation with wall kicks and real-time gravity |
| Block Drop Merge | Tetris × 2048 | Chain reactions of merges |
| Color Match Drop | Falling color pairs that evolve | Chains with evolution, abilities, and biomes |
Rule 1: why gameplay has to be "sacred"
The first serious problem I hit in Sudoku Play was micro-stutter: the screen froze for a split second every so often. The cause was saving the game and syncing with the server while people played.
The fix became a rule across all my games: during gameplay, zero network or disk operations. All state lives in memory (in a Zustand store). Autosave runs every 10 seconds, on pause, and on exit, and is deferred until the UI finishes what it’s doing (with InteractionManager.runAfterInteractions). The result: a steady 60 FPS and autosave you never notice. How all of that syncs afterwards is in offline-first architecture.
Rule 2: how do you drag pieces without lag?
In Block Puzzle Play you drag pieces over an 8×8 board and see a shadow where they’ll land. In the first version, every finger movement triggered a cascade of re-renders: the shadow and the global state were recalculated on every pixel.
I solved it by splitting two things: the piece’s visual position lives on the native thread with Reanimated (shared values), and the game logic is only called when needed (via runOnJS). The shadow updates without redrawing the board. That keeps 60 FPS even on low-end phones. Another detail: checking whether any move is left can mean testing a lot of positions, so the check exits as soon as it finds the first valid one, and takes under 50 milliseconds.
How do you build a game loop with real-time gravity?
In Block Drop Play, a Tetris-style game, pieces fall on their own. The gravity tick, the grace period before a piece locks (lock delay), and auto-repeat when you hold a direction (DAS) live in a Zustand store with controlled intervals, and 17 selectors make sure each component only re-renders when what it shows actually changes.
The engine implements the genre’s standard rotation system (SRS) with its wall kick tables: 4 tests per rotation, different for the long piece and for the rest. It detects T-Spins with the 3-corner rule and uses the "7-bag" system: each of the 7 pieces appears exactly once every 7, so there are no unfair droughts of the piece you need. Touch controls use separate tap zones to move and rotate, swipes to drop, and 3 configurable repeat speeds.
Why write game engines as pure functions?
In Color Match Drop, 4 matching blocks are cleared, but 5 or more evolve into a higher tier with a special ability, which can in turn clear other blocks. The full chain is: find groups, classify them, evolve, apply abilities, drop the blocks, and search again. I wrote it as separate pure functions that repeat in rounds, with 300 ms animated pauses so you can see what’s happening.
The payoff came right away: since the engine doesn’t change anything outside itself, I could build "Prophecy", a mode where holding down simulates the whole move, chains included, on a copy of the board and shows the result without touching the real game. The biomes (ocean, volcano, forest, space, crystal) change real rules, like speed or gravity, and live in a separate, decoupled engine. In Block Drop Merge, the merge engine, scoring, and board logic are covered by Jest unit tests.
How do you make a fair daily challenge?
For daily challenges and duels to be fair, both players need exactly the same pieces. I use a seeded random number generator: in Block Drop Play’s daily challenge, the seed comes from the date plus the game’s name; in duels, both players share the same seed. Sequences are reproducible and the server can verify them. The server also validates maximum scores per mode, minimum times, and pieces per minute to catch cheaters.
How do you adapt to every screen size?
On iPad, everything rendered at double size because measurements were based on the real screen width. I built a centralized scaling system using an iPhone 13 mini as the baseline, capped at 500 px wide on tablets, so the UI stays consistent from an iPhone SE to an iPad Pro. In Block Drop Merge, the standard 10×20 board made 4-digit numbers unreadable, so I shrank it to 8×16 with a monospaced font. And in every game, respecting safe areas (the notch and Dynamic Island) keeps content from being covered.
Which bugs only showed up on real phones?
- Samsung and the notes grid: the system laid out elements differently and Sudoku notes rendered wrong. I replaced them with a fixed 3×3 structure.
- Samsung and background tasks: background sync crashed the app. I switched to syncing when the app is reopened.
- Huawei without Google services: the app crashed. It now checks whether the services exist before using them.
- Async loading: in Killer Sudoku Play, the game screen opened before the puzzles finished loading from the local database, and the app crashed. A loading indicator in the meantime fixed it.
What stack did I use?
- React Native 0.81 with the New Architecture and Expo SDK 54, in strict TypeScript.
- Zustand for state, with stores split by concern (game, user, friends, duels, premium).
- Reanimated and Gesture Handler for animations and gestures on the native thread.
- expo-av for sound: Block Drop Play has 22 sound effect types, and in Color Match Drop every color is a musical note, so matches sound like chords.
- Local SQLite for Sudoku Play’s 6,000 puzzles, which work offline.
- Supabase as a shared backend, Firebase Crashlytics for crash reports, and EAS for builds and updates.
Block Drop Play: a professional Tetris engine in React Native
Block Drop Play has full SRS rotation with wall kicks, T-Spin detection, Perfect Clears, official scoring, 5 game modes, async duels, and per-game missions, all at 60 FPS from a single codebase for iOS and Android. It’s live on the App Store.
See Block Drop PlayWhat if you’re not building a game?
These rules aren’t just for games. Any app that has to feel fast (a digital menu, an ordering system, a field-work tool) benefits from not blocking the screen on the network, animating on the native thread, and testing on real phones. What is specific to games is reusing all of this across several apps, which I cover in how to reuse code across apps, and the hurdles of publishing them, in why Apple rejects apps.
Frequently asked questions
Is React Native good for games?
It works very well for puzzle, board, and casual games: Sudoku, block games, color matching. For a 3D game or one with complex physics, a dedicated game engine is the better choice.
Can React Native hit 60 FPS?
Yes. The keys are avoiding disk and network operations during gameplay, moving animations to the native thread with Reanimated, and preventing every change from redrawing the whole screen.
Do I need Expo to build a game?
It isn’t required, but it simplifies a lot: cloud builds for Android and iOS, pushing fixes without going through the stores, and access to sound, haptics, and storage without writing native code.
How do I give every player the same pieces in a daily challenge?
Use a seeded random number generator: if the seed comes from the date, everyone playing that day gets exactly the same sequence, and the server can verify it.
If you have a game or app in mind and want it to run smoothly on Android and iPhone, tell me the idea. I’m Facundo Campo, and I built these 7 games end to end.