1. JSI vs. the Old Bridge
The original React Native architecture connected JavaScript to native code through a bridge — every call serialized to JSON, queued, sent across asynchronously, and deserialized on the other side. That worked, but it meant every native call had latency, and nothing could ever be synchronous.
The JSI (JavaScript Interface) replaces that with direct C++ bindings — JavaScript objects can hold direct references to native objects and call their methods synchronously, with no serialization step and no queue. It's the foundation everything else in the New Architecture builds on.
2. Fabric: the New Renderer
Fabric is the New Architecture's renderer — it uses JSI to build and update the native UI tree directly and synchronously, rather than batching updates across the old asynchronous bridge. In practice, that means layout and rendering can happen on the UI thread without waiting on a round trip to JS, which is most visible in smoother, less janky interactions — the kind Week 18's performance lesson measures directly.
None of the code from earlier weeks changes to benefit from this — View,
FlatList, and every core component already render through Fabric on a
modern Expo/React Native project. There's nothing to opt into.
3. TurboModules & Codegen
TurboModules are the New Architecture's replacement for the old native module system — instead of every module loading eagerly at app startup, they load lazily, on first use, and communicate over JSI instead of the bridge.
Codegen generates the C++ glue code connecting a module's
TypeScript spec to its native implementation, from a typed spec file, catching
type mismatches between JS and native at build time rather than at runtime. The
module built with the Expo Modules API in Week 12 already targets this system — the
Function/AsyncFunction definitions there are what codegen
consumes; nothing about that module needs to be rewritten to be "New Architecture
compatible."
4. Native Module vs. JS Library
A short, practical checklist for the decision, now that both options have been seen in full:
- Search for an existing, maintained Expo or community package first — this covers nearly every "device API" need, as this entire phase demonstrated.
- Reach for a native module when the platform API has no wrapper at all, or you're exposing existing native code with no JS equivalent.
- Prefer a synchronous
Functiononly for something genuinely instant; useAsyncFunctionfor anything that touches disk, network, or a system service. - Budget for maintaining two native implementations (Swift and Kotlin) going forward, plus keeping up with OS and React Native version changes — a real, ongoing cost a pure-JS dependency doesn't carry.
5. Hands-on Exercise
Audit a module decision
A short written exercise — no new code, just applying this week's framework.
Requirements:
- Pick three features from earlier weeks (camera, location, notifications) and, for each, identify whether it was implemented via an existing package or would need a custom native module, and why.
- For the native module built in Week 12, write one paragraph describing what would break (or not) if it were run on an app still using the old bridge architecture.
- Write down one hypothetical feature request where you would justify building a native module from scratch, and one where you would push back and look harder for an existing package first.
- Sketch (in words, or a simple diagram) the path a call to
DeviceInfoModule.getBatteryLevel()takes from the JS call site to the native return value, naming JSI and TurboModules at the point each is involved.
If you're unsure whether something "needs" a native module, the question that usually settles it is: does a maintained package already exist for this? Only after searching and finding nothing does the native-module conversation become worth having — most feature requests that sound like they need one, don't.
6. Knowledge Check
Four quick questions. Expand each to check your answer.
Q1
What specific limitation of the old bridge did JSI remove?
What specific limitation of the old bridge did JSI remove?
The old bridge required every native call to be serialized to JSON, queued, and sent asynchronously across the bridge, which meant every call had latency and none could be synchronous. JSI gives JavaScript direct references to native objects it can call synchronously, with no serialization or queueing.
Q2
Does a component built with plain View/FlatList in Week 1 need to be rewritten to benefit from Fabric?
Does a component built with plain View/FlatList in Week 1 need to be rewritten to benefit from Fabric?
No — Fabric is the renderer underneath every core component on a modern React Native/Expo project; there's no separate API to opt into. Every screen built across this entire course already renders through it.
Q3
What does codegen actually generate, and from what input?
What does codegen actually generate, and from what input?
It generates the C++ glue code that connects a native module's typed JS/TypeScript spec to its native (Swift/Kotlin) implementation, from that spec file — the same kind of module definition written with the Expo Modules API in Week 12. This lets type mismatches between the JS and native sides surface at build time instead of failing at runtime.
Q4
Per this week's checklist, what should happen before deciding to write a native module for a new feature request?
Per this week's checklist, what should happen before deciding to write a native module for a new feature request?
A search for an existing, maintained package covering the need — the overwhelming majority of device-facing features (as demonstrated by every prior week in this phase) already have one. Writing and maintaining a native module across two platforms is a real, ongoing cost that's only worth taking on once that search comes up empty.