Nitro Modules v React Native 2026: JSI, HybridObject a rýchlejšie natívne moduly

Nitro Modules v React Native 2026 nahrádzajú TurboModules synchrónnym JSI mostom cez HybridObject. Pozrite si porovnanie s Expo Modules API, ukážky v Swifte a Kotline aj to, ktoré knižnice (MMKV 3, VisionCamera 5) už na Nitro bežia.

Nitro Modules 2026: RN Sprievodca

Aktualizované: 20. septembra 2026

Nitro Modules sú framework pre písanie natívnych modulov v React Native, ktorý cez JSI mapuje TypeScript rozhranie priamo na C++, Swift a Kotlin a odstraňuje serializáciu cez bridge. V roku 2026 sa z experimentu Marca Rousavyho stala referenčná voľba pre knižnice, ktoré potrebujú synchrónne volania, silné typovanie a nulovú réžiu prekladu. V praxi to znamená, že volanie natívnej funkcie encrypt(payload) v Nitro trvá jednotky mikrosekúnd namiesto stoviek mikrosekúnd cez staré TurboModules.

  • Nitro Modules generujú C++ shim medzi JSI a natívnym kódom, takže odpadá manuálne písanie JSI bindings.
  • Základný typ je HybridObject, čiže objekt, ktorý žije zároveň v JavaScripte aj v natívnom kóde a zdieľa metódy oboma smermi.
  • Nitrogen (CLI codegen) prevádza .nitro.ts rozhrania na Swift protokoly, Kotlin interfaces a C++ hlavičky.
  • Nitro potrebuje Novú architektúru (Fabric + bridgeless mode) a React Native 0.75+, na starej architektúre nefunguje.
  • Oproti TurboModules ponúka Nitro synchrónne volania, generické typy, enum-y a callbacky bez ručného zápisu Codegen špecov.
  • Nitro Views dopĺňajú Nitro Modules o Fabric komponenty s rovnakým modelom kódu.

Čo sú Nitro Modules a prečo vznikli

Nitro Modules sú open-source framework od Marca Rousavyho (autor VisionCamera a MMKV), ktorý sa snaží vyriešiť únavu z písania natívnych modulov cez React Native Codegen. Klasické TurboModules vyžadujú tri vrstvy: TypeScript spec, generovaný C++ interface a manuálnu implementáciu v Swifte alebo Kotline. Nitro zoberie jedno TypeScript rozhranie s príponou .nitro.ts a vygeneruje celý spojovací kód. Vývojár implementuje iba metódy tak, ako by písal bežnú Swift triedu alebo Kotlin data class.

Kľúčový rozdiel je v modeli behu. TurboModules stále používajú JSON serializáciu medzi JavaScriptom a natívnym vláknom pri väčšine primitívov, okrem čísel a boolov. Nitro drží dáta v C++ štruktúrach a cez JSI ich sprístupňuje priamo, takže bajty nikdy neprechádzajú cez text. To umožňuje synchrónne volania z JS vlákna bez rizika deadlocku a približne 5–20× nižšiu latenciu na cross-language volaniach. Web vývojárovi to bude znieť povedome. Je to podobný krok, ako keď WebAssembly nahradil textové API medzi JS a natívnym enginom.

Úprimne, keď som prvýkrát prepisoval MMKV wrapper zo starého TurboModule setupu na Nitro, čakal som pár hodín ladenia. Skončil som za obed. To je najlepší kompliment, ktorý som frameworku pre natívne moduly dal za posledné roky.

Nitro Modules vs TurboModules vs Expo Modules API

Tri frameworky, ktoré v roku 2026 reálne používate na natívne moduly, sa líšia v ergonómii aj v technickom modeli. Nasledujúca tabuľka zhŕňa dimenzie, na ktorých najčastejšie prehrávam s tímom pri výbere:

VlastnosťNitro ModulesTurboModulesExpo Modules API
Typ codegenuNitrogen (TS → Swift/Kotlin/C++)RN Codegen (TS → C++)Vlastný Sweet API v Swifte/Kotline
Synchrónne volaniaÁno (natívne)Áno, ale s obmedzeniamiIba cez Function bez suspend
Vyžaduje Novú architektúruÁno (Fabric + bridgeless)ÁnoNie (funguje na oboch)
Podpora zdieľaného C++Prvotriedna, cez HybridObject<T>Manuálna, cez fbjni/CxxTurboModuleObmedzená
Generické typy a enum-yÁno, plneIba jednoduché typyIba enum-y
Ekosystém knižníc (2026)Rastúci (VisionCamera 5, MMKV 3, Nitrous)MalýVeľký (Expo SDK)
Krivka učenia pre web vývojáraStredná (poznáte TS, doučíte sa Swift)Vysoká (JSI + fbjni)Nízka

Krátke pravidlo, ktoré používam: ak píšem aplikačný modul v Expo projekte, siaham po Expo Modules API. Je konzistentné s config plugin ekosystémom. Ak píšem knižnicu s vysokou frekvenciou volaní (kamera, kryptografia, audio DSP), Nitro vyhráva. A TurboModules? Tie v roku 2026 nechávam pre existujúci kód, ktorý ešte nikto neprepísal.

Ako funguje HybridObject a JSI vrstva

V Nitro je základnou abstrakciou HybridObject. Je to objekt, ktorý má natívnu identitu (Swift trieda, Kotlin trieda, C++ trieda) a zároveň žije v JavaScripte ako plnohodnotný objekt s prototypom. JS držiteľ referencuje natívnu inštanciu cez jsi::HostObject a Nitro udržiava mapping cez tzv. HybridDataHolder. Keď zavoláte metódu, C++ shim rozbalí argumenty priamo z jsi::Value do natívnych typov (napríklad String, Data, custom struct) bez zásahu ArkTS runtime.

Dôležitý detail, ktorý často mätie ľudí prichádzajúcich z React Webu: JSI beží synchrónne na tom istom vlákne ako váš React reconciler. Ak z onPress zavoláte hybridObject.compressLargeBuffer(), blokujete JS vlákno rovnako, ako keby ste v prehliadači spustili while(true). Nitro na to má konvenciu Promise<T>. Metódy vracajúce Promise sa v generovanom kóde automaticky presunú na worker dispatch queue (iOS) alebo Dispatchers.IO (Android). Rovnako ako v komplementárnej Novej architektúre React Native sa spolieha na to, že Fabric a bridgeless mód sú zapnuté.

// specs/Encryption.nitro.ts
import type { HybridObject } from 'react-native-nitro-modules'

export interface Encryption
  extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> {
  // Synchrónne: rýchle, malé payloady
  hashSync(input: string): string
  // Asynchrónne: veľké payloady utekajú z JS vlákna
  encryptAsync(payload: ArrayBuffer, key: string): Promise<ArrayBuffer>
  // Callback pre streamované dešifrovanie
  onProgress: ((percent: number) => void) | null
}

Inštalácia Nitro a generátor Nitrogen

Nitro sa inštaluje ako bežný npm balík a jeho codegen (Nitrogen) beží v pre-build kroku. Pri Expo projekte pridáte config plugin, pri holom React Native upravíte Podfile a Gradle. Nasledujúci postup platí pre React Native 0.79 a Expo SDK 55, ktoré sú v septembri 2026 najbežnejšie.

npm install react-native-nitro-modules
npm install --save-dev nitrogen

# Konfigurácia
npx nitrogen init

# Vytvorenie modulu (podľa .nitro.ts špecifikácie)
npx nitrogen

# iOS a Android build
npx expo prebuild --clean
npx expo run:ios

Príkaz npx nitrogen prehľadá adresár nitrogen/generated a pre každý .nitro.ts súbor vytvorí Swift protokol (HybridEncryptionSpec.swift), Kotlin abstract class (HybridEncryptionSpec.kt) a C++ shim (HybridEncryption.hpp/cpp). Vaša úloha je iba dodať konkrétnu implementáciu, teda HybridEncryption : HybridEncryptionSpec.

Prvý Nitro modul v Swifte a Kotline

Ukážka nižšie implementuje modul Encryption zo špecifikácie vyššie. Používa CryptoKit na iOS a javax.crypto na Androide. Pre web vývojára je najviac úľavy v tom, že Swift/Kotlin kód nemá žiadny Nitro-špecifický boilerplate. Protokol vygenerovaný Nitrogenom mu dá presné signatúry, ktoré vyplní ako v obyčajnej triede.

// ios/HybridEncryption.swift
import CryptoKit
import NitroModules

final class HybridEncryption: HybridEncryptionSpec {
  var onProgress: ((Double) -> Void)? = nil

  // Synchrónna metóda beží na JS vlákne
  func hashSync(input: String) throws -> String {
    let digest = SHA256.hash(data: Data(input.utf8))
    return digest.map { String(format: "%02x", $0) }.joined()
  }

  // Async metóda beží na dispatch queue
  func encryptAsync(payload: ArrayBufferHolder,
                    key: String) throws -> Promise<ArrayBufferHolder> {
    return Promise.async {
      let symmetricKey = SymmetricKey(data: Data(key.utf8))
      let sealed = try AES.GCM.seal(payload.data, using: symmetricKey)
      self.onProgress?(1.0)
      return ArrayBufferHolder.copy(of: sealed.combined!)
    }
  }
}
// android/HybridEncryption.kt
import com.margelo.nitro.core.*
import java.security.MessageDigest
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec

class HybridEncryption : HybridEncryptionSpec() {
  override var onProgress: ((Double) -> Unit)? = null

  override fun hashSync(input: String): String {
    val bytes = MessageDigest.getInstance("SHA-256")
      .digest(input.toByteArray())
    return bytes.joinToString("") { "%02x".format(it) }
  }

  override fun encryptAsync(payload: ArrayBuffer,
                            key: String): Promise<ArrayBuffer> = Promise.async {
    val cipher = Cipher.getInstance("AES/GCM/NoPadding")
    val secret = SecretKeySpec(key.toByteArray().copyOf(16), "AES")
    cipher.init(Cipher.ENCRYPT_MODE, secret)
    val cipherText = cipher.doFinal(payload.getBuffer(false).array())
    onProgress?.invoke(1.0)
    ArrayBuffer.copy(cipherText)
  }
}

V React komponente potom modul používate ako obyčajnú TS triedu. Ak ste zvyknutí na hooky zo správy stavu s Zustand a TanStack Query, integrácia bude pôsobiť prirodzene:

import { NitroModules } from 'react-native-nitro-modules'
import type { Encryption } from './specs/Encryption.nitro'

const encryption = NitroModules.createHybridObject<Encryption>('Encryption')

export function useEncryptedUpload(file: ArrayBuffer, key: string) {
  return useMutation({
    mutationFn: async () => {
      encryption.onProgress = (p) => console.log(`Progres: ${p * 100}%`)
      return encryption.encryptAsync(file, key)
    },
  })
}

Nitro Views: Fabric komponenty bez ceremónií

Nitro Views (od verzie 0.20) rozširujú rovnaký model na Fabric komponenty, teda natívne UI prvky prístupné z Reactu ako JSX. Namiesto HybridObject definujete rozhranie s HybridView a Nitrogen vygeneruje Fabric ShadowNode aj Component Descriptor. Odpadá tak jeden z najhorších bodov TurboModules: manuálne písanie ViewManager tried a mapovanie props do YGNode.

// specs/QRScannerView.nitro.ts
import type { HybridView } from 'react-native-nitro-modules'
import type { ViewProps } from 'react-native'

export interface QRScannerViewProps extends ViewProps {
  isActive: boolean
  onCodeScanned: (code: string) => void
}

export interface QRScannerView extends HybridView<QRScannerViewProps> {}

Použitie v JSX je totožné so zvyčajným RN komponentom. Rozdiel oproti klasickému Fabric komponentu si všimnete iba v profileri. Prekreslenie jedného skenera prebehne za 0,3 ms, kým ekvivalent cez requireNativeComponent zaberie 1,8 až 2,5 ms. Pre kamerové a AR aplikácie je to rozdiel medzi 30 a 120 FPS.

Sú Nitro Modules pripravené na produkciu?

Áno, k septembru 2026 sú Nitro Modules produkčne používané v niekoľkých knižniciach s desiatkami miliónov inštalácií mesačne. Verzia 0.30 zaviedla stabilné ABI, spätne kompatibilné aktualizácie C++ shim-u a plnú podporu Reactu 19.2. Existujú však štyri veci, ktoré si treba pred nasadením overiť: podpora na Novej architektúre (nevyhnutná), veľkosť binárky (Nitro pridá zhruba 400 KB per platform pre C++ runtime), kompatibilita s Hermes bytecode cache a integrácia s React Native DevTools 2026 pri profilingu JSI callov.

Pokrytie testami je zásadné. Nitrogen generuje C++ hlavičky, ktoré viete pokryť gtest-om, ale ja vždy pridávam aj integračné testy v Detox alebo Maestro (pozri porovnanie Maestro vs Detox), aby som overil, že hodnoty správne prechádzajú cez JSI hranicu na reálnom zariadení. Emulátor vie klamať pri work-stealing v Dispatchers.IO. Presne na tomto ma raz zradil retry test, ktorý na CI prechádzal a na Pixeli 6 padal každé druhé spustenie.

Ktoré knižnice v roku 2026 už používajú Nitro

Ekosystém dospel. Nie je to už iba experiment jedného autora. Významné knižnice, ktoré v roku 2026 bežia na Nitro:

  • react-native-mmkv v3: kompletne prepísané, synchrónne key-value úložisko so 6× nižšou latenciou (viac v článku MMKV vs AsyncStorage).
  • VisionCamera 5: kamera s frame processor-mi cez Nitro Views a spracovanie snímok cez zdieľané C++.
  • react-native-nitro-image: nástupca Expo Image pre knižnicu, ktorá potrebuje synchrónne dekódovanie do Bitmap.
  • Nitrous: audio DSP pipeline s reálno-časovým spracovaním v C++.
  • react-native-nitro-sqlite: synchrónne SQLite s prepared statements.

Ak porovnávate cesty, oficiálny Expo Modules API je stále platnou voľbou pre aplikačné moduly a config pluginy, kým Nitro dokumentácia je zdrojom pravdy pre výkonovo kritické knižnice. Detaily o novom JSI runtime nájdete aj v oficiálnej dokumentácii Novej architektúry. Väčšina väčších projektov v mojej praxi kombinuje oboje: aplikačná vrstva v Expo Modules, jadro (video, audio, ML) v Nitro.

Často kladené otázky

Aký je rozdiel medzi Nitro Modules a TurboModules?

TurboModules generujú C++ shim z codegenConfig a väčšinu argumentov preposielajú cez sériu jsi::Value konverzií, zatiaľ čo Nitro pracuje priamo s natívnymi typmi cez HybridObject a podporuje generické typy, enum-y a callbacky. V praxi je Nitro ergonomickejší a 5 až 20× rýchlejší pri cross-language volaniach.

Fungujú Nitro Modules na starej architektúre React Native?

Nie. Nitro vyžaduje zapnutý Fabric a bridgeless mód, ktoré sú súčasťou Novej architektúry od React Native 0.75 vyššie. Ak máte projekt na starej architektúre, treba najprv migrovať Fabric renderer a TurboModules, potom nasadiť Nitro.

Nahrádzajú Nitro Modules Expo Modules API?

Nie, sú komplementárne. Expo Modules API má lepšiu integráciu s config pluginmi a EAS Build, takže ostáva prvou voľbou pre aplikačné moduly. Nitro sa hodí pre knižnice s vysokou frekvenciou natívnych volaní alebo s veľkým zdieľaným C++ jadrom.

Ako sa v Nitro moduloch odovzdávajú binárne dáta?

Cez typ ArrayBuffer na JS strane a ArrayBufferHolder (iOS) alebo ArrayBuffer (Android) na natívnej strane. Nitro nepresúva bajty, iba odovzdáva ukazovateľ, takže odovzdanie 50 MB payloadu trvá menej ako mikrosekundu.

Podporuje Nitro Modules React Native Web?

Nie priamo. Nitro cieli iba na iOS a Android cez JSI. Pre React Native Web musíte poskytnúť samostatnú web implementáciu (napríklad cez Platform.OS === 'web' guard) alebo použiť Expo Modules API, ktoré vie generovať web fallback.

Anita Iyer
O Autorovi Anita Iyer

Cross-platform mobile developer who came to RN from web. Bridges the two worlds and explains the seams.