Metro Bundler is een gespecialiseerde JavaScript-bundler van Meta, exclusief ontwikkeld voor React Native en onderdeel van de kern van het framework. Volgens de officiële React Native 0.76 (2025) documentatie biedt Metro incrementeel builden met Fast Refresh en module-resolutie rekening houdend met platformextensies .native.js, .ios.js en .android.js. In tegenstelling tot Webpack gebruikt Metro geen langlevende module graph cache — in plaats daarvan herbouwt het de graaf elke keer wanneer bestanden veranderen, wat directe Hot Reload geeft tijdens het ontwikkelen.
Belangrijkste punten
Metro Bundler is een open-source JavaScript-bundler, ontwikkeld door Meta voor React Native en standaard gebruikt in alle projecten van het framework. De taak van Metro is om de JavaScript-code van het project samen met afhankelijkheden te nemen en een of meerdere bundles te bouwen die op het apparaat worden uitgevoerd. In tegenstelling tot universele bundlers (Webpack, Rollup, Parcel) is Metro geoptimaliseerd voor de specificiteit van mobiele ontwikkeling: minimale buildtijd, incrementele updates tijdens ontwikkeling en correcte werking met platformmodules (native modules Objective-C, Swift, Java, Kotlin). Metro wordt geleverd binnen React Native CLI en vereist geen aparte installatie. Vanaf React Native 0.72 ondersteunt Metro versie 0.80+ parallelle transpilatie van modules, wat het builden op multi-core processors tot 40% versnelt.
De architectuur van Metro is verdeeld in drie onafhankelijke componenten: Resolver, Transformer en Bundler. Resolver is verantwoordelijk voor het zoeken en oplossen van modules — het leest import/require-expressies, vindt de bijbehorende bestanden rekening houdend met platformextensies en retourneert absolute paden. Transformer voert transpilatie uit: past Babel toe met presets en plugins, zet JSX, TypeScript of Flow om in zuivere JavaScript. Bundler is de laatste fase: het ontvangt de afhankelijkheidsgraaf van Resolver en getransformeerde bestanden van Transformer, en serialiseert ze vervolgens in een of meerdere bundles (module bundles). De verdeling in drie stappen stelt Metro in staat om de resultaten van elke fase te cachen: als slechts één bestand is gewijzigd, kunnen Resolver en Bundler de cache gebruiken voor de overige modules, wat de buildsnelheid in ontwikkelmodus tot 10 keer verhoogt.
Resolver in Metro implementeert het module-resolutie-algoritme, gedeeltelijk compatibel met Node.js module resolution. Het belangrijkste verschil met Node.js — ondersteuning voor platformextensies: require('./Component') zoekt naar Component.native.js, Component.ios.js, Component.android.js in de gespecificeerde prioriteitsvolgorde. Resolver ondersteunt ook het package.json-veld "react-native" voor het mappen van modules naar alternatieve implementaties — dit is het standaardmechanisme voor bibliotheken met platformcode. Als het bestand niet wordt gevonden, gooit Resolver een fout met de volledige zoekstack.
Transformer binnen Metro gebruikt Babel met de preset metro-react-native-babel-preset. De standaardconfiguratie omvat: transformatie van JSX naar React.createElement, ondersteuning voor TypeScript (verwijderen van types), ondersteuning voor Flow en polyfills voor moderne JavaScript-standaarden (async/await, optional chaining, nullish coalescing). Transformer werkt in parallelle modus: elke module wordt onafhankelijk getranspileerd met behulp van een pool van worker-processen (standaard komt het aantal overeen met het aantal CPU's). Vanaf Metro 0.80 wordt Granular Transformer Cache ondersteund — cache-invalidatie op het niveau van een afzonderlijk bestand.
Een van de belangrijkste kenmerken van Metro is de ondersteuning voor platformbestandsextensies. Een React Native-project kan drie versies van één module bevatten: Component.ios.js (iOS), Component.android.js (Android) en Component.native.js (beide platformen). Bij import require('./Component') kiest Resolver automatisch de juiste versie op basis van het doelplatform van de build. Dit maakt het mogelijk om platformafhankelijke code te schrijven zonder conditionele Platform.OS-constructies. De prioriteitsvolgorde: naam.platform.js > naam.native.js > naam.js. De extensie .native.js wordt gebruikt voor gemeenschappelijke code die op beide platformen werkt maar niet compatibel is met het web. De extensies .ios.js en .android.js dienen voor het implementeren van specifieke functies — navigatie, gebaren, werken met het bestandssysteem. Metro ondersteunt aangepaste extensies via configuratie resolver.sourceExts.
// metro.config.js — sourceExts en watchFolders instellen
const config = {
resolver: {
sourceExts: ['jsx', 'js', 'tsx', 'ts', 'json'],
platformExtensions: ['ios', 'android', 'native'],
},
transformer: {
babelTransformerPath: require('metro-react-native-babel-transformer'),
},
watchFolders: [path.resolve('../shared')],
};
Fast Refresh is het hot reload-mechanisme van React Native, geïmplementeerd bovenop Metro. Wanneer een ontwikkelaar een bestand wijzigt, transpileert Metro alleen de gewijzigde module en stuurt de update naar de app via WebSocket. Fast Refresh werkt de interface bij zonder de hele app te herladen en behoudt de React-componentstatus als alleen JSX of stijlen zijn gewijzigd. Als code met hooks of status is gewijzigd, voert Fast Refresh een hermontage uit van alleen de gewijzigde component. Metro ondersteunt twee modi: Hot Module Replacement (HMR) voor het ter plekke vervangen van modules en Live Reload voor het volledig herladen van de app bij wijziging van native modules of configuratie. Fast Refresh is standaard ingeschakeld in React Native 0.76 en vereist geen extra configuratie — het volstaat om npx react-native start uit te voeren.
| Modus | Snelheid | Behoudt status | Trigger |
|---|---|---|---|
| Fast Refresh | 200-500ms | Ja | Wijziging van JS/TS-bestanden |
| HMR | 100-300ms | Ja | Wijziging van CSS/stijlen |
| Live Reload | 1-3s | Nee | Wijziging van native config |
| Full Rebuild | 10-60s | Nee | Wijziging van podspec/build.gradle |
metro.config.js is het configuratiebestand van Metro, gelegen in de hoofdmap van het React Native-project. Hierin worden geconfigureerd: resolver (sourceExts, platformExtensions, extraNodeModules), transformer (babelTransformerPath, minifierConfig), server (port, host, enableFastRefresh) en watcher (watchFolders, healthCheck). De standaard Metro-configuratie wordt overgenomen van het pakket @react-native/metro-config (React Native 0.76+). Voor projecten met een monorepository voegt u watchFolders toe — dit stelt Metro in staat om wijzigingen in pakketten buiten de projecthoofdmap te volgen. Voor het configureren van sourceExts voegt u 'svg', 'png', 'gql' toe voor aangepaste transformatoren. Metro ondersteunt asynchrone configuraties via async function — dit is handig voor het dynamisch genereren van configuratie op basis van de omgeving.
Optimalisatie van Metro-builden begint met de juiste cache-configuratie. Stel maxWorkers in op het aantal CPU's min 1. Gebruik voor distributies resetCache op CI. Minimaliseer sourceExts — extra extensies vertragen module-resolutie. Voor grote projecten configureert u watchFolders alleen op de benodigde mappen. Metro ondersteunt Hermes bytecode minification, die een kleinere bundelgrootte geeft dan standaard Terser — gebruik minifierPath: 'metro-minify-terser'.
Metro ondersteunt de modus om direct naar Hermes bytecode te builden — de JavaScript AST-fase overslaand. Bij builden met HermesTransformer worden modules gecompileerd naar HBC (Hermes ByteCode) in plaats van gewone JavaScript. Dit geeft: kleinere bundelgrootte (met 30-40%), snellere app-start (met 20-30%) en lager geheugengebruik. Om te activeren stelt u hermesCommand in in metro.config.js en activeert u de Hermes-vlag in build.gradle (Android) of Podfile (iOS). Het bouwen van Hermes-bundels gebeurt in twee fasen: eerst bouwt Metro de JavaScript-bundel, vervolgens converteert Hermes CLI deze naar HBC. Vanaf React Native 0.70 is Hermes de standaard-engine op Android, op iOS is expliciete activering vereist.
Het verschil tussen Metro en Webpack is te wijten aan verschillende doelen. Webpack is een universele bundler voor het web met een enorm ecosysteem van plugins en loaders. Metro is een gespecialiseerde bundler voor React Native, waar prioriteit ligt bij de snelheid van incrementeel builden en correcte werking met native modules. Webpack gebruikt een langlevende module-graaf met intelligente cache-invalidatie — dit geeft snelle herbuilds op het web, maar creëert problemen met platformextensies. Metro cacht de graaf niet tussen builds, maar bouwt deze elke keer opnieuw — dit vereenvoudigt de verwerking van platformextensies en Haste-modules. Webpack ondersteunt dynamische imports met chunks, Metro ook — via React.lazy() en Suspense, maar met een beperking van één actief verzoek. Het Metro-ecosysteem is aanzienlijk kleiner: er is geen vervanging voor style-loader, css-loader, file-loader — deze taken worden anders opgelost in React Native.
Metro is de enige juiste keuze voor React Native-projecten. Webpack ondersteunt geen platform-aware resolution uit de doos, en het configureren van React Native met Webpack vereist aanzienlijke inspanning (haul bundler, expo web packager). Metro is geïntegreerd in React Native CLI, wordt ondersteund door het officiële Meta-team en krijgt updates met elke React Native-release. Voor React Native Web-projecten kunt u Webpack gebruiken voor web-builds, terwijl Metro behouden blijft voor mobiele bundels.
Veelgestelde vragen
Voer npx react-native start --reset-cache uit of verwijder de map $TMPDIR/metro-* en de directory .metro-health-check* in de projecthoofdmap. Alternatief: npx react-native clean — dit commando verwijdert alle tijdelijke Metro-bestanden, inclusief de Babel-cache en Haste-kaart. Na het leegmaken zal de eerste build volledig zijn (60-120 seconden), maar daaropvolgende incrementele builds keren terug naar normale snelheid.
Controleer de aanwezigheid van het pakket in package.json dependencies (niet devDependencies). Als de module zich in een monorepository bevindt, voeg dan het pad toe aan watchFolders in metro.config.js. Metro volgt standaard geen symlinks — gebruik resolver.extraNodeModules voor expliciete mapping. Stel voor Yarn PnM resolver.useWatchman: false in. Als de module platformextensies gebruikt, zorg er dan voor dat de .ios.js- of .android.js-bestanden bestaan op het opgegeven pad.
Verhoog maxWorkers in metro.config.js naar het aantal CPU's min 1. Configureer watchFolders alleen op de benodigde mappen. Gebruik Hermes bytecode voor productie-builds — dit versnelt de uiteindelijke build door JS-minificatie over te slaan. Schakel voor ontwikkeling Fast Refresh in (standaard ingeschakeld). Beperk sourceExts tot alleen de benodigde extensies. Overweeg het opsplitsen van de bundel in chunks via lazy loading.
Technisch ja, maar het wordt niet aanbevolen. Metro is niet geoptimaliseerd voor web-builds: er is geen ondersteuning voor CSS, HTML, afbeeldingen als modules, geen code splitting met dynamische import op browserniveau. Gebruik voor het web Webpack, Vite of Parcel. Metro is een gespecialiseerde oplossing voor React Native en een poging om het aan te passen voor het web zal leiden tot prestatieverlies en gebrek aan een loader-ecosysteem.
Re.Pack is een community-tool voor het vervangen van Metro door Webpack in React Native-projecten. Het geeft toegang tot het Webpack-loader-ecosysteem (css-loader, svg-loader) en geavanceerde code splitting. Echter, Re.Pack is complexer in configuratie, wordt niet officieel ondersteund door Meta en garandeert geen compatibiliteit met nieuwe versies van React Native. Metro blijft de enige officieel ondersteunde bundler, wat stabiliteit en compatibiliteitsgarantie biedt bij elke release.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook