Introduzione alla Nuova Architettura di React Native
Il 2026 è stato, senza mezzi termini, un anno di svolta per React Native. Con il rilascio di Expo SDK 55, la Nuova Architettura è diventata l'unico sistema supportato — il vecchio Bridge asincrono, quello che ci ha accompagnato per anni, è ufficialmente andato in pensione. E onestamente? Era ora.
Non si tratta di un semplice aggiornamento tecnico. È una riprogettazione completa del modo in cui JavaScript e il codice nativo comunicano nelle app mobile.
In questa guida andiamo a esplorare ogni pezzo della Nuova Architettura — dal JavaScript Interface (JSI) ai TurboModules, dal Fabric Renderer al sistema Codegen — con esempi di codice concreti, confronti di performance e istruzioni per la migrazione. Che tu sia uno sviluppatore navigato o alle prime armi, qui troverai quello che ti serve per padroneggiare il futuro dello sviluppo mobile cross-platform.
Il Problema del Vecchio Bridge
Per capire davvero la Nuova Architettura, bisogna prima capire cosa non funzionava nel vecchio sistema. L'architettura legacy di React Native si appoggiava su un Bridge asincrono che faceva da intermediario tra il thread JavaScript e quello nativo.
Come funzionava il Bridge
Ogni volta che il codice JavaScript aveva bisogno di comunicare con il lato nativo (per accedere alla fotocamera, al GPS, o semplicemente per aggiornare l'interfaccia), i dati facevano un viaggio piuttosto tortuoso:
- Serializzati in formato JSON nel thread JavaScript
- Inviati attraverso il Bridge in modo asincrono
- Deserializzati nel thread nativo
- Elaborati, e il risultato rispedito indietro con lo stesso processo al contrario
Come puoi immaginare, questo meccanismo portava con sé diversi problemi:
- Overhead di serializzazione: La conversione continua dei dati in JSON e viceversa consumava risorse CPU non indifferenti
- Collo di bottiglia: Tutte le comunicazioni passavano attraverso un singolo canale, creando congestione durante le operazioni più intensive
- Latenza: La natura asincrona del Bridge introduceva ritardi percettibili, specialmente nelle animazioni e nelle interazioni utente
- Inizializzazione lenta: Tutti i moduli nativi venivano caricati all'avvio dell'app, anche quelli che non servivano
// Vecchia architettura: comunicazione tramite Bridge
// JavaScript → Serializzazione JSON → Bridge Asincrono → Deserializzazione → Nativo
// Tempo tipico: 5-15ms per singola chiamata
// Esempio di chiamata nativa con il vecchio sistema
import { NativeModules } from 'react-native';
// Tutti i moduli caricati all'avvio, anche se non usati
const { DeviceInfo, Camera, Geolocation, Bluetooth } = NativeModules;
// Ogni chiamata passa attraverso il Bridge
const deviceName = await DeviceInfo.getDeviceName(); // ~10ms di latenza
I Quattro Pilastri della Nuova Architettura
La Nuova Architettura butta via il Bridge e lo sostituisce con quattro componenti che lavorano in sinergia. Vediamoli uno per uno.
1. JavaScript Interface (JSI)
Il JSI è il cuore pulsante di tutta la Nuova Architettura. In pratica, è un'interfaccia leggera scritta in C++ che permette a JavaScript di parlare direttamente e in modo sincrono con il codice nativo. Niente più Bridge in mezzo.
Ecco cosa lo rende speciale:
- Comunicazione sincrona: JavaScript chiama funzioni native e ottiene risultati istantaneamente, senza aspettare risposte asincrone
- Riferimenti diretti: JavaScript può mantenere riferimenti a oggetti C++ (e viceversa), condividendo memoria senza serializzazione
- Indipendenza dal motore: JSI non è legato a JavaScriptCore — funziona con qualsiasi motore JavaScript, incluso Hermes
- Prestazioni elevate: L'eliminazione della serializzazione JSON porta i tempi di risposta da millisecondi a microsecondi
// Nuova Architettura con JSI
// JavaScript ↔ JSI (C++) ↔ Nativo
// Tempo tipico: <1ms per singola chiamata (miglioramento del 30-50%)
// Con JSI, JavaScript accede direttamente agli oggetti nativi
// Nessuna serializzazione, nessun Bridge, nessuna latenza aggiuntiva
In pratica, una funzione JavaScript può invocare direttamente una funzione C++, che a sua volta chiama API native di iOS (Objective-C/Swift) o Android (Java/Kotlin). E tutto questo avviene nello stesso frame di esecuzione — ecco perché l'esperienza utente risulta così fluida.
2. TurboModules
I TurboModules sono l'evoluzione dei vecchi Native Modules. La differenza chiave? Sfruttano il JSI per la comunicazione e implementano il caricamento lazy, cioè su richiesta.
I vantaggi sono notevoli:
- Caricamento on-demand: I moduli vengono inizializzati solo quando l'app li richiede effettivamente, riducendo in modo drastico il tempo di avvio
- Type safety tramite Codegen: Le specifiche TypeScript generano automaticamente codice nativo tipizzato
- Comunicazione sincrona: Grazie al JSI, le chiamate ai moduli nativi sono immediate
- Condivisione di codice: La logica condivisa può essere scritta in C++ e usata su entrambe le piattaforme
Creare un TurboModule: esempio pratico
Vediamo come creare un TurboModule personalizzato per ottenere informazioni sul dispositivo. Si parte dalla specifica TypeScript.
// specs/NativeDeviceInfo.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
// Metodi sincroni
getDeviceModel(): string;
getBatteryLevel(): number;
isCharging(): boolean;
// Metodi asincroni (per operazioni più lunghe)
getDeviceIpAddress(): Promise<string>;
getStorageInfo(): Promise<{
totalSpace: number;
freeSpace: number;
}>;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'NativeDeviceInfo'
);
Un dettaglio importante: il nome del file deve seguire il pattern Native<NomeModulo>.ts — Codegen va a cercare automaticamente file con questo formato. La specifica definisce l'interfaccia completa del modulo, inclusi i tipi di input e output di ogni metodo.
Poi serve configurare Codegen nel package.json:
// package.json
{
"name": "mia-app-react-native",
"version": "1.0.0",
"codegenConfig": {
"name": "MiaAppSpecs",
"type": "modules",
"jsSrcsDir": "specs",
"android": {
"javaPackageName": "com.miaapp.specs"
}
}
}
Quando lanci la build, Codegen analizza le specifiche TypeScript e genera il codice nativo per Android (Java/Kotlin) e iOS (Objective-C++), garantendo che i tipi siano coerenti tra JavaScript e le piattaforme native.
Utilizzare il TurboModule nell'app
// App.tsx
import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import NativeDeviceInfo from './specs/NativeDeviceInfo';
const DeviceInfoScreen = () => {
const [ipAddress, setIpAddress] = useState<string>('');
const [storageInfo, setStorageInfo] = useState<{
totalSpace: number;
freeSpace: number;
} | null>(null);
// Chiamate sincrone — risultato immediato grazie a JSI
const deviceModel = NativeDeviceInfo.getDeviceModel();
const batteryLevel = NativeDeviceInfo.getBatteryLevel();
const charging = NativeDeviceInfo.isCharging();
useEffect(() => {
const loadAsyncData = async () => {
const ip = await NativeDeviceInfo.getDeviceIpAddress();
const storage = await NativeDeviceInfo.getStorageInfo();
setIpAddress(ip);
setStorageInfo(storage);
};
loadAsyncData();
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>Informazioni Dispositivo</Text>
<Text>Modello: {deviceModel}</Text>
<Text>Batteria: {batteryLevel}%</Text>
<Text>In carica: {charging ? 'Sì' : 'No'}</Text>
<Text>IP: {ipAddress}</Text>
{storageInfo && (
<Text>
Spazio: {storageInfo.freeSpace}GB liberi su{' '}
{storageInfo.totalSpace}GB
</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, padding: 20, justifyContent: 'center' },
title: { fontSize: 24, fontWeight: 'bold', marginBottom: 16 },
});
export default DeviceInfoScreen;
Nota come le chiamate sincrone (getDeviceModel(), getBatteryLevel()) restituiscono risultati immediati senza bisogno di await o gestione di stati asincroni. Questa è una delle cose che preferisco della nuova architettura — prima era impensabile.
3. Fabric Renderer
Il Fabric è il nuovo sistema di rendering, quello che ha preso il posto del vecchio UI Manager. Introdotto come preview in React Native 0.70 e diventato il default dalla 0.76, Fabric ripensa da zero il modo in cui i componenti UI vengono creati, aggiornati e mostrati sullo schermo.
Come funziona Fabric
Fabric si basa su un Shadow Tree immutabile. Quando lo stato dell'interfaccia cambia, succede questo:
- React crea un nuovo Shadow Tree con le modifiche
- Fabric confronta il nuovo albero con quello precedente (diffing)
- Solo le differenze vengono applicate alla UI nativa
- I nodi che non sono cambiati vengono riutilizzati
La logica di rendering è tutta in C++, e questo porta due vantaggi enormi:
- Coerenza cross-platform: Lo stesso codice di rendering gira su iOS, Android e qualsiasi altra piattaforma supportata
- Prestazioni superiori: Il C++ è decisamente più veloce di Java o Objective-C per le operazioni di layout
Supporto per Concurrent React
Fabric supporta nativamente Concurrent React, una delle funzionalità più interessanti di React 18+. In concreto, questo significa che:
- Prioritizzazione degli aggiornamenti: Gli aggiornamenti critici dell'UI (come le risposte agli input) hanno la precedenza su quelli meno urgenti
- Rendering interrompibile: React può mettere in pausa un rendering in corso per gestire un'interazione utente più importante
- Transizioni fluide: Le API
startTransitionpermettono di differire aggiornamenti pesanti senza bloccare l'interfaccia
// Esempio di utilizzo di Concurrent React con Fabric
import React, { useState, useTransition, Suspense } from 'react';
import { View, TextInput, FlatList, Text, ActivityIndicator } from 'react-native';
const SearchScreen = () => {
const [query, setQuery] = useState('');
const [results, setResults] = useState<string[]>([]);
const [isPending, startTransition] = useTransition();
const handleSearch = (text: string) => {
// Aggiornamento immediato dell'input (alta priorità)
setQuery(text);
// Aggiornamento dei risultati differito (bassa priorità)
// Fabric gestisce questo senza bloccare l'UI
startTransition(() => {
const filtered = heavyFilterOperation(text);
setResults(filtered);
});
};
return (
<View style={{ flex: 1, padding: 16 }}>
<TextInput
value={query}
onChangeText={handleSearch}
placeholder="Cerca..."
style={{
borderWidth: 1,
borderColor: '#ccc',
padding: 12,
borderRadius: 8,
marginBottom: 16,
}}
/>
{isPending && <ActivityIndicator size="small" />}
<FlatList
data={results}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<Text style={{ padding: 12 }}>{item}</Text>
)}
/>
</View>
);
};
In questo esempio, l'input dell'utente si aggiorna subito, mentre l'operazione di filtro (quella pesante) viene gestita come transizione a bassa priorità. Il risultato? L'interfaccia resta reattiva anche durante operazioni computazionalmente intense.
4. Codegen
Il Codegen è il sistema di generazione automatica del codice che fa da collante tra JavaScript e il nativo. A partire dalle specifiche TypeScript (o Flow), genera strutture C++ tipizzate che garantiscono la type safety a compile-time.
Il processo è piuttosto lineare:
- Lo sviluppatore scrive la specifica TypeScript del modulo o del componente
- Codegen la analizza e genera il codice nativo corrispondente
- Il codice generato include validazione dei tipi, conversioni automatiche e interfacce native
- Le incompatibilità di tipo vengono rilevate durante la compilazione, non a runtime
// Specifica TypeScript per un componente Fabric
// specs/NativeCustomButtonNativeComponent.ts
import type { ViewProps } from 'react-native';
import type {
Float,
Int32,
WithDefault,
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
interface NativeProps extends ViewProps {
// Proprietà tipizzate — Codegen genera il codice nativo corrispondente
buttonText: string;
buttonColor?: string;
fontSize?: WithDefault<Float, 16.0>;
maxLines?: WithDefault<Int32, 1>;
isEnabled?: WithDefault<boolean, true>;
onButtonPress?: (event: {
nativeEvent: { timestamp: Float };
}) => void;
}
export default codegenNativeComponent<NativeProps>(
'CustomButton'
);
Codegen si occupa di generare il codice di validazione per Android e iOS, eliminando un'intera categoria di bug legati ai tipi non corrispondenti. È una di quelle cose che, una volta provate, non si torna più indietro.
Benchmark di Prestazioni: Vecchia vs Nuova Architettura
Ok, i numeri. Perché alla fine contano quelli. I miglioramenti della Nuova Architettura sono documentati e misurabili:
- Tempo di avvio dell'app: Fino al 40% più veloce, grazie al caricamento lazy dei TurboModules e alle ottimizzazioni di Hermes
- Frame rate: 60 fps costanti anche con animazioni complesse e scroll di liste lunghe
- Utilizzo memoria: Riduzione del 20-30% grazie alla condivisione diretta della memoria tramite JSI
- Latenza delle chiamate native: Da 5-15ms (Bridge) a meno di 1ms (JSI) — un miglioramento del 30-50%
- Rendering dell'UI: Pipeline sincrono che elimina i colli di bottiglia nel calcolo del layout
// Misurazione delle prestazioni nella tua app
import { PerformanceObserver, performance } from 'react-native/Libraries/Performance/Performance';
// Monitoraggio delle prestazioni dei TurboModules
const measureModulePerformance = async () => {
const start = performance.now();
// Chiamata sincrona tramite JSI
const model = NativeDeviceInfo.getDeviceModel();
const syncTime = performance.now() - start;
console.log(`Chiamata sincrona JSI: ${syncTime.toFixed(3)}ms`);
const asyncStart = performance.now();
// Chiamata asincrona
const ip = await NativeDeviceInfo.getDeviceIpAddress();
const asyncTime = performance.now() - asyncStart;
console.log(`Chiamata asincrona: ${asyncTime.toFixed(3)}ms`);
};
// Monitoraggio del frame rate
const monitorFrameRate = () => {
let frameCount = 0;
let lastTime = performance.now();
const checkFPS = () => {
frameCount++;
const currentTime = performance.now();
if (currentTime - lastTime >= 1000) {
console.log(`FPS: ${frameCount}`);
frameCount = 0;
lastTime = currentTime;
}
requestAnimationFrame(checkFPS);
};
requestAnimationFrame(checkFPS);
};
Guida alla Migrazione: Dal Bridge alla Nuova Architettura
Se il tuo progetto è ancora sulla vecchia architettura, è il momento di muoversi. Con Expo SDK 55, la Nuova Architettura è obbligatoria — non c'è più la possibilità di disabilitarla. Ecco come fare una migrazione sicura, passo dopo passo.
Step 1: Aggiornamento delle dipendenze
Prima di tutto, verifica che tutte le librerie di terze parti siano compatibili con la Nuova Architettura. La buona notizia è che la maggior parte delle librerie più usate ha già rilasciato versioni compatibili.
# Aggiorna React Native all'ultima versione
npx react-native upgrade
# Verifica la compatibilità delle dipendenze
npx react-native-new-arch-check
# Aggiorna tutte le dipendenze
npm update
# Per progetti Expo, aggiorna l'SDK
npx expo install --fix
Step 2: Abilitazione della Nuova Architettura
Per i progetti con React Native CLI (non-Expo), la Nuova Architettura è abilitata di default dalla versione 0.76. Per versioni precedenti bisogna attivarla manualmente:
# Android: modifica android/gradle.properties
# Imposta newArchEnabled=true
echo "newArchEnabled=true" >> android/gradle.properties
# iOS: abilita la Nuova Architettura durante l'installazione dei pod
cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
Per i progetti Expo è ancora più semplice:
// app.json o app.config.js per Expo
{
"expo": {
"name": "MiaApp",
"slug": "mia-app",
"newArchEnabled": true,
"plugins": [
// I plugin Expo sono già compatibili con la Nuova Architettura
"expo-camera",
"expo-location",
"expo-notifications"
]
}
}
Step 3: Migrazione dei Native Modules a TurboModules
Se hai moduli nativi personalizzati, dovrai convertirli in TurboModules. Non è complicato come sembra — ecco un esempio concreto:
// PRIMA: Vecchio Native Module
// OldAnalytics.js
import { NativeModules } from 'react-native';
const { AnalyticsModule } = NativeModules;
export const trackEvent = (name, params) => {
AnalyticsModule.trackEvent(name, params);
};
// DOPO: Nuovo TurboModule
// specs/NativeAnalytics.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
trackEvent(name: string, params: Record<string, string>): void;
trackScreenView(screenName: string): void;
setUserId(userId: string): void;
flush(): Promise<boolean>;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'NativeAnalytics'
);
Step 4: Migrazione dei componenti UI a Fabric
Anche i componenti nativi UI vanno aggiornati per Fabric. Serve creare una specifica TypeScript per ciascuno:
// PRIMA: Vecchio componente nativo
// OldMapView.js
import { requireNativeComponent } from 'react-native';
const MapView = requireNativeComponent('RNMapView');
// DOPO: Componente Fabric
// specs/MapViewNativeComponent.ts
import type { ViewProps } from 'react-native';
import type {
Double,
DirectEventHandler,
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
type OnRegionChangeEvent = {
latitude: Double;
longitude: Double;
zoom: Double;
};
interface NativeProps extends ViewProps {
initialLatitude: Double;
initialLongitude: Double;
zoomLevel?: Double;
showsUserLocation?: boolean;
onRegionChange?: DirectEventHandler<OnRegionChangeEvent>;
}
export default codegenNativeComponent<NativeProps>('MapView');
Step 5: Verifica e Profilazione
Dopo la migrazione, non saltare questo passaggio. Verifica che tutto funzioni e profila le prestazioni:
// Configurazione del profiling delle prestazioni
import { InteractionManager } from 'react-native';
// Verifica che le interazioni siano fluide dopo la migrazione
InteractionManager.runAfterInteractions(() => {
console.log('Tutte le animazioni e le transizioni completate');
// Esegui operazioni pesanti qui
});
// Usa React DevTools Profiler per identificare
// componenti che si ri-renderizzano troppo frequentemente
// e confronta con i benchmark pre-migrazione
Hermes v1: Il Motore JavaScript Ottimizzato
Accanto alla Nuova Architettura c'è Hermes v1, che rappresenta un bel salto in avanti per il motore JavaScript di React Native. Hermes è il motore open-source sviluppato da Meta, pensato specificamente per le app React Native.
Le novità più rilevanti di Hermes v1:
- Supporto migliorato per JavaScript moderno: Migliore compatibilità con le specifiche ECMAScript più recenti
- Compilazione bytecode ottimizzata: Avvio più rapido grazie alla precompilazione del JavaScript in bytecode
- Gestione della memoria migliorata: Garbage collector più efficiente, con meno pause e picchi di memoria
- Ottimizzazioni per IA: Miglioramenti specifici per operazioni matematiche e di tensori — utili se stai integrando modelli di machine learning on-device
// Verifica che Hermes sia attivo nella tua app
const isHermes = () => !!global.HermesInternal;
console.log(`Hermes attivo: ${isHermes()}`);
if (isHermes()) {
// Informazioni sulla versione di Hermes
console.log(
'Versione Hermes:',
global.HermesInternal?.getRuntimeProperties?.()
);
}
Expo SDK 55 e la Nuova Architettura
Con Expo SDK 55, rilasciato nel gennaio 2026, la Nuova Architettura è diventata l'unica opzione. Punto. Expo SDK 54 è stato l'ultimo in cui si poteva ancora disabilitarla.
Novità principali di Expo SDK 55
- Apple Zoom Transition: Nuova transizione animata con elementi condivisi interattivi su iOS, abilitata di default
- Stack.Toolbar API: API per costruire menu e azioni nella toolbar, al momento disponibile per iOS
- Supporto SplitView sperimentale: Finalmente — era una delle feature più richieste dalla community
- Pacchetto expo-brownfield: Permette di integrare codice React Native in app native esistenti senza dover configurare Node.js o le dipendenze di build di React Native
// Esempio: Apple Zoom Transition in Expo SDK 55
import { Stack } from 'expo-router';
export default function Layout() {
return (
<Stack
screenOptions={{
// La Zoom Transition è abilitata di default su iOS
animation: 'zoom',
// Supporto per gesti interattivi
gestureEnabled: true,
}}
>
<Stack.Screen name="index" options={{ title: 'Home' }} />
<Stack.Screen
name="dettaglio"
options={{ title: 'Dettaglio' }}
/>
</Stack>
);
}
// Esempio: Stack.Toolbar API (iOS)
import { Stack } from 'expo-router';
export default function ScreenWithToolbar() {
return (
<>
<Stack.Screen
options={{
title: 'Le Mie Note',
}}
/>
<Stack.Toolbar>
{/* Menu e azioni personalizzate nella toolbar */}
</Stack.Toolbar>
</>
);
}
Best Practices per la Nuova Architettura
Allora, per sfruttare al meglio la Nuova Architettura nel 2026, ecco le pratiche che consiglio di seguire.
1. Usa TypeScript per tutte le specifiche
TypeScript non è solo una buona pratica — è indispensabile per Codegen. Le specifiche TypeScript sono la fonte di verità da cui viene generato tutto il codice nativo tipizzato.
2. Preferisci le chiamate sincrone quando possibile
Grazie al JSI, le chiamate sincrone ai moduli nativi sono velocissime. Usale per operazioni rapide come leggere proprietà del dispositivo o eseguire calcoli nativi. Le chiamate asincrone vanno riservate per operazioni che richiedono davvero tempo (I/O, rete, eccetera).
3. Sfrutta il Concurrent Mode
Con Fabric che supporta Concurrent React, usa le API di transizione (useTransition, useDeferredValue) per mantenere l'interfaccia reattiva durante le operazioni pesanti. Fidati, i tuoi utenti noteranno la differenza.
// Best practice: useDeferredValue per liste pesanti
import React, { useState, useDeferredValue } from 'react';
import { FlatList, TextInput, View, Text } from 'react-native';
const OptimizedList = ({ items }: { items: string[] }) => {
const [filter, setFilter] = useState('');
// Il valore differito viene aggiornato con priorità più bassa
const deferredFilter = useDeferredValue(filter);
const filteredItems = items.filter((item) =>
item.toLowerCase().includes(deferredFilter.toLowerCase())
);
return (
<View style={{ flex: 1 }}>
<TextInput
value={filter}
onChangeText={setFilter}
placeholder="Filtra elementi..."
style={{ padding: 12, borderBottomWidth: 1 }}
/>
<FlatList
data={filteredItems}
keyExtractor={(item, i) => `${item}-${i}`}
renderItem={({ item }) => (
<Text style={{ padding: 16 }}>{item}</Text>
)}
/>
</View>
);
};
4. Monitora attivamente le prestazioni
Usa gli strumenti di profilazione per verificare che la tua app stia effettivamente sfruttando i benefici della Nuova Architettura. React DevTools, Flipper, Xcode Instruments e Android Profiler sono i tuoi migliori alleati in questo.
5. Mantieni aggiornate le dipendenze
Nel 2026, la maggior parte delle librerie della community ha ormai abbandonato il supporto per la vecchia architettura. Tieni le dipendenze aggiornate per beneficiare delle ottimizzazioni specifiche per la Nuova Architettura.
Risoluzione dei Problemi Comuni
Durante la migrazione (o anche durante lo sviluppo quotidiano), potresti incontrare qualche intoppo. Ecco i problemi più frequenti e come risolverli.
Errore: "TurboModule not found"
// Problema: il TurboModule non viene trovato
// Soluzione: verifica che il nome del file segua il pattern corretto
// ✅ Corretto: NativeDeviceInfo.ts (inizia con "Native")
// ❌ Errato: DeviceInfoModule.ts
// Verifica anche la registrazione nel package.json
// Il campo "name" in codegenConfig deve corrispondere
Errore: "Codegen type mismatch"
// Problema: tipi non corrispondenti tra JS e nativo
// Soluzione: usa solo i tipi supportati da Codegen
// Tipi supportati:
// - string, boolean, number (Double, Float, Int32)
// - Object (con proprietà tipizzate)
// - Array<T>
// - Promise<T> (per metodi asincroni)
// - Callbacks
// ❌ Non supportato: Map, Set, Symbol, BigInt
// ❌ Non supportato: Union types complessi
Problemi di performance dopo la migrazione
// Se noti cali di prestazioni dopo la migrazione:
// 1. Verifica che Hermes sia attivo
console.log('Hermes:', !!global.HermesInternal);
// 2. Controlla che non ci siano re-render non necessari
// Usa React.memo() per componenti puri
const MemoizedComponent = React.memo(({ data }) => {
return <Text>{data}</Text>;
});
// 3. Profila con React DevTools
// Cerca componenti che si ri-renderizzano senza cambiamenti di props
// 4. Verifica la configurazione di build
// Assicurati che la build di produzione usi le ottimizzazioni
Yoga: Il Motore di Layout Cross-Platform
C'è un componente della Nuova Architettura che spesso passa in secondo piano ma che merita attenzione: Yoga. È il motore di layout cross-platform che calcola posizione e dimensioni degli elementi UI. Implementa un sottoinsieme delle specifiche CSS Flexbox ed è scritto interamente in C++ — il che lo rende molto veloce e coerente tra le piattaforme.
Con la Nuova Architettura, Yoga è stato ulteriormente ottimizzato per lavorare in sinergia con Fabric. Il calcolo del layout è ora sincrono e thread-safe, il che vuol dire:
- Nessun ritardo nel layout: I calcoli di posizionamento vengono eseguiti subito quando lo Shadow Tree cambia, senza attendere comunicazioni asincrone
- Coerenza garantita: Lo stesso motore C++ gira su tutte le piattaforme, eliminando le discrepanze di layout tra iOS e Android
- Integrazione con componenti host: Il calcolo sincrono facilita l'integrazione di componenti nativi (come mappe o video player) nell'albero di rendering React Native
// Esempio: layout complesso gestito da Yoga + Fabric
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const DashboardLayout = () => {
return (
<View style={styles.container}>
{/* Yoga calcola questo layout in modo sincrono */}
<View style={styles.header}>
<Text style={styles.headerText}>Dashboard</Text>
</View>
<View style={styles.content}>
<View style={styles.card}>
<Text style={styles.cardTitle}>Vendite</Text>
<Text style={styles.cardValue}>€12,450</Text>
</View>
<View style={styles.card}>
<Text style={styles.cardTitle}>Utenti</Text>
<Text style={styles.cardValue}>3,280</Text>
</View>
<View style={styles.wideCard}>
<Text style={styles.cardTitle}>Grafico Attività</Text>
{/* Componente nativo integrato senza problemi di layout */}
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#f5f5f5' },
header: {
padding: 20,
backgroundColor: '#6200ee',
// Yoga supporta gap, un'aggiunta recente
},
headerText: { fontSize: 24, color: '#fff', fontWeight: 'bold' },
content: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
padding: 12,
gap: 12, // Supporto gap nativo in Yoga
},
card: {
flex: 1,
minWidth: '45%',
backgroundColor: '#fff',
borderRadius: 12,
padding: 16,
elevation: 2,
},
wideCard: {
width: '100%',
backgroundColor: '#fff',
borderRadius: 12,
padding: 16,
minHeight: 200,
elevation: 2,
},
cardTitle: { fontSize: 14, color: '#666' },
cardValue: { fontSize: 28, fontWeight: 'bold', marginTop: 8 },
});
Il Futuro di React Native: Cosa Aspettarsi
Con la Nuova Architettura ormai consolidata, il futuro di React Native è pieno di sviluppi promettenti. Ecco cosa c'è all'orizzonte:
- Integrazione IA on-device: L'ottimizzazione di Hermes per operazioni matematiche intensive apre la strada all'integrazione di modelli di machine learning direttamente nell'app, senza dipendere da server esterni
- Supporto multi-piattaforma ampliato: La base C++ condivisa di Fabric facilita l'espansione verso nuove piattaforme oltre iOS e Android
- Server Components: L'integrazione con React Server Components potrebbe cambiare radicalmente il modo in cui le app mobile gestiscono i dati
- Brownfield migliorato: Il pacchetto
expo-brownfielddi SDK 55 è solo l'inizio — aspettati un'integrazione sempre più fluida con le app native esistenti - Static Hermes: Il progetto Static Hermes punta a compilare JavaScript in codice nativo, eliminando del tutto l'overhead del motore JavaScript e raggiungendo prestazioni paragonabili a Swift o Kotlin
E la cosa bella è che non stiamo parlando di ipotesi: sono sviluppi che derivano direttamente dalle fondamenta poste dalla Nuova Architettura. Il passaggio da un Bridge asincrono basato su JSON a un'interfaccia C++ diretta e sincrona ha aperto possibilità che prima erano semplicemente impensabili.
La community di React Native è più attiva che mai, con contributi importanti da parte di Meta, Expo, Microsoft, Amazon e Shopify. Questa collaborazione assicura che il framework continuerà a evolversi rapidamente, mantenendo React Native come una delle scelte migliori per lo sviluppo mobile cross-platform.
Conclusioni
La Nuova Architettura di React Native è, senza dubbio, la più grande evoluzione del framework dalla sua nascita. Con JSI, TurboModules, Fabric e Codegen, React Native ha praticamente colmato il divario di prestazioni con lo sviluppo nativo puro, mantenendo la produttività e la flessibilità del cross-platform.
Nel 2026, con Expo SDK 55 che rende la Nuova Architettura obbligatoria, non c'è davvero più motivo per rimandare la migrazione. Avvio più rapido, animazioni fluide, meno consumo di memoria, type safety migliorata — i benefici sono troppo significativi per essere ignorati.
Il mio consiglio? Inizia subito. Aggiorna le dipendenze, verifica la compatibilità delle librerie di terze parti e pianifica la conversione dei tuoi moduli nativi. Il futuro dello sviluppo mobile è qui, ed è più veloce, più sicuro e più elegante che mai.