Metro Bundler: o que é, agrupamento de projeto e princípio de funcionamento

Autor: IT Sectr Publicado: 2026-07-06 Tempo de leitura: 8 min

Metro Bundler é um agrupador JavaScript especializado da Meta, desenvolvido exclusivamente para React Native e incluído no núcleo do framework. De acordo com a documentação oficial do React Native 0.76 (2025), o Metro fornece compilações incrementais com Fast Refresh e resolução de módulos com extensões específicas de plataforma .native.js, .ios.js e .android.js. Ao contrário do Webpack, o Metro não usa um cache de grafo de módulos de longa duração — em vez disso, ele reconstrói o grafo cada vez que os arquivos mudam, fornecendo Hot Reload instantâneo durante o desenvolvimento.

Pontos principais

  • Metro Bundler — o agrupador oficial JavaScript do React Native com suporte para extensões específicas de plataforma
  • Fast Refresh — recarga a quente preservando o estado dos componentes ao alterar o código
  • Haste Module System — sistema de IDs de módulos estáveis para compilações incrementais
  • Extensões de plataforma — .native.js, .ios.js, .android.js para separação de código por plataforma
  • Hermes bytecode — modo de compilação diretamente em bytecode para o motor Hermes

O que é Metro Bundler

Metro Bundler é um agrupador JavaScript de código aberto desenvolvido pela Meta para React Native e usado por padrão em todos os projetos do framework. A tarefa do Metro é pegar o código JavaScript do projeto junto com as dependências e agrupá-lo em um ou vários bundles que são executados no dispositivo. Ao contrário dos agrupadores universais (Webpack, Rollup, Parcel), o Metro é otimizado para as especificidades do desenvolvimento móvel: tempo mínimo de compilação, atualizações incrementais durante o desenvolvimento e manuseio correto de módulos de plataforma (módulos nativos Objective-C, Swift, Java, Kotlin). O Metro é incluído no React Native CLI e não requer instalação separada. A partir do React Native 0.72, o Metro versão 0.80+ suporta transpilação paralela de módulos, acelerando as compilações em processadores multicore em até 40%.

Arquitetura do Metro: Resolver, Transformer e Bundler

A arquitetura do Metro é dividida em três componentes independentes: Resolver, Transformer e Bundler. O Resolver é responsável por encontrar e resolver módulos — ele lê expressões import/require, encontra os arquivos correspondentes considerando as extensões de plataforma e retorna caminhos absolutos. O Transformer realiza a transpilação: aplica Babel com presets e plugins, transforma JSX, TypeScript ou Flow em JavaScript puro. O Bundler é o estágio final: ele pega o grafo de dependências do Resolver e os arquivos transformados do Transformer, depois os serializa em um ou vários bundles (module bundles). A separação em três etapas permite ao Metro armazenar em cache os resultados de cada estágio: se apenas um arquivo mudou, o Resolver e o Bundler podem usar o cache para os módulos restantes, fornecendo um aumento de velocidade de compilação de até 10 vezes no modo de desenvolvimento.

Resolver: resolução de módulos e busca com ciência de plataforma

O Resolver no Metro implementa um algoritmo de resolução de módulos parcialmente compatível com a resolução de módulos do Node.js. A diferença chave do Node.js é o suporte para extensões de plataforma: require(‘./Component’) procura por Component.native.js, Component.ios.js, Component.android.js na ordem de prioridade especificada. O Resolver também suporta o campo package.json “react-native” para mapear módulos para implementações alternativas — este é o mecanismo padrão para bibliotecas com código específico de plataforma. Se um arquivo não for encontrado, o Resolver lança um erro com a pilha de busca completa.

Transformer: Babel e transpilação

O Transformer dentro do Metro usa Babel com o preset metro-react-native-babel-preset. A configuração padrão inclui: transformação de JSX em React.createElement, suporte a TypeScript (remoção de tipos), suporte a Flow e polyfills para padrões modernos de JavaScript (async/await, optional chaining, nullish coalescing). O Transformer funciona em modo paralelo: cada módulo é transpilado independentemente, usando um pool de processos worker (por padrão, o número corresponde ao número de CPUs). A partir do Metro 0.80, o Granular Transformer Cache é suportado — invalidação de cache no nível de arquivo individual.

Extensões específicas de plataforma no Metro

Uma das principais características do Metro é o suporte para extensões de arquivo de plataforma. Um projeto React Native pode conter três versões do mesmo módulo: Component.ios.js (iOS), Component.android.js (Android) e Component.native.js (ambas as plataformas). Ao importar require(‘./Component’), o Resolver seleciona automaticamente a versão correta dependendo da plataforma de compilação alvo. Isso permite escrever código dependente de plataforma sem construções condicionais Platform.OS. Ordem de prioridade: nome.plataforma.js > nome.native.js > nome.js. A extensão .native.js é usada para código comum que funciona em ambas as plataformas mas é incompatível com a web. As extensões .ios.js e .android.js servem para implementar funcionalidades específicas — navegação, gestos, operações de sistema de arquivos. O Metro suporta extensões personalizadas através da configuração resolver.sourceExts.

js
// metro.config.js — configuração de sourceExts e watchFolders
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')],
};

Hot Reload e Fast Refresh no Metro

Fast Refresh é um mecanismo de recarga a quente para React Native construído sobre o Metro. Quando um desenvolvedor altera um arquivo, o Metro re-transpila apenas o módulo alterado e envia a atualização para o aplicativo via WebSocket. O Fast Refresh atualiza a interface sem recarregar todo o aplicativo e preserva o estado dos componentes React se apenas JSX ou estilos foram alterados. Se o código com hooks ou estado for alterado, o Fast Refresh remonta apenas o componente alterado. O Metro suporta dois modos: Hot Module Replacement (HMR) para substituição de módulos em tempo real e Live Reload para recarga completa do aplicativo quando módulos nativos ou configuração mudam. O Fast Refresh está habilitado por padrão no React Native 0.76 e não requer configuração adicional — basta executar npx react-native start.

ModoVelocidadePreserva estadoGatilho
Fast Refresh200-500msSimAlteração em arquivos JS/TS
HMR100-300msSimAlteração em CSS/estilos
Live Reload1-3sNãoAlteração em config nativa
Full Rebuild10-60sNãoAlteração em podspec/build.gradle

Configuração do Metro: metro.config.js

O arquivo metro.config.js é o arquivo de configuração do Metro localizado na raiz de um projeto React Native. Nele são configurados: resolver (sourceExts, platformExtensions, extraNodeModules), transformer (babelTransformerPath, minifierConfig), server (port, host, enableFastRefresh) e watcher (watchFolders, healthCheck). A configuração padrão do Metro herda do pacote @react-native/metro-config (React Native 0.76+). Para projetos com monorepositório, adicione watchFolders — isso permite ao Metro rastrear mudanças em pacotes fora da raiz do projeto. Para configurar sourceExts, adicione ‘svg’, ‘png’, ‘gql’ para transformadores personalizados. O Metro suporta configurações assíncronas através de async function — útil para geração dinâmica de configuração baseada no ambiente.

Otimização de compilação através da configuração

A otimização das compilações do Metro começa com uma configuração adequada de cache. Defina maxWorkers como o número de CPUs menos 1. Para distribuições, use resetCache no CI. Minimize sourceExts — extensões extras retardam a resolução de módulos. Para grandes projetos, configure watchFolders apenas para os diretórios necessários. O Metro suporta minificação Hermes bytecode, que produz um tamanho de bundle menor que o Terser padrão — use minifierPath: ‘metro-minify-terser’.

Hermes bundling: compilação em bytecode

O Metro suporta um modo de compilação diretamente em Hermes bytecode — pulando o estágio AST do JavaScript. Ao compilar com HermesTransformer, os módulos são compilados em HBC (Hermes ByteCode) em vez de JavaScript comum. Isso proporciona: tamanho de bundle menor (30-40%), inicialização de aplicativo mais rápida (20-30%) e menor consumo de memória. Para habilitar, defina hermesCommand no metro.config.js e ative a flag Hermes no build.gradle (Android) ou Podfile (iOS). A compilação de bundles Hermes é feita em dois estágios: primeiro o Metro compila o bundle JavaScript, depois o Hermes CLI o converte para HBC. A partir do React Native 0.70, o Hermes é o motor padrão no Android, no iOS requer ativação explícita.

Metro vs Webpack: comparação de abordagens

A diferença entre Metro e Webpack se deve a diferentes objetivos. Webpack é um agrupador universal para a web com um enorme ecossistema de plugins e loaders. Metro é um agrupador especializado para React Native onde a prioridade é a velocidade de compilação incremental e o funcionamento correto com módulos nativos. Webpack usa um grafo de módulos persistente com invalidação inteligente de cache — isso fornece reconstruções rápidas na web mas cria problemas com extensões de plataforma. Metro não armazena o grafo em cache entre compilações, mas o constrói cada vez — isso simplifica o manuseio de extensões de plataforma e módulos Haste. Webpack suporta importações dinâmicas com chunks, Metro também — através de React.lazy() e Suspense, mas com a limitação de uma requisição ativa. O ecossistema do Metro é significativamente menor: não há substituto para style-loader, css-loader, file-loader — essas tarefas são resolvidas de forma diferente no React Native.

Quando escolher Metro

Metro é a única escolha correta para projetos React Native. Webpack não suporta resolução com ciência de plataforma nativamente, e configurar React Native com Webpack requer esforço significativo (haul bundler, expo web packager). Metro está integrado ao React Native CLI, é suportado pela equipe oficial do Meta e recebe atualizações a cada versão do React Native. Para projetos React Native Web, você pode usar Webpack para compilações web enquanto mantém Metro para bundles móveis.

Perguntas frequentes

Como limpar o cache do Metro Bundler?

Execute npx react-native start --reset-cache ou exclua a pasta $TMPDIR/metro-* e o diretório .metro-health-check* na raiz do projeto. Alternativamente: npx react-native clean — este comando limpa todos os arquivos temporários do Metro, incluindo cache Babel e mapa Haste. Após a limpeza, a primeira compilação será completa (60-120 segundos), mas as compilações incrementais subsequentes retornarão à velocidade normal.

Por que o Metro não vê um módulo do node_modules?

Verifique se o pacote está nas dependencies do package.json (não devDependencies). Se o módulo estiver em um monorepositório, adicione o caminho a watchFolders no metro.config.js. O Metro não segue symlinks por padrão — use resolver.extraNodeModules para mapeamento explícito. Para Yarn PnM, defina resolver.useWatchman: false. Se o módulo usar extensões de plataforma, certifique-se de que os arquivos .ios.js ou .android.js existam no caminho especificado.

Como acelerar a compilação do Metro em um projeto grande?

Aumente maxWorkers no metro.config.js para o número de CPUs menos 1. Configure watchFolders apenas para os diretórios necessários. Use Hermes bytecode para compilações de produção — acelera a compilação final ao pular a minificação JS. Para desenvolvimento, habilite Fast Refresh (está habilitado por padrão). Limite sourceExts apenas às extensões necessárias. Considere dividir o bundle em chunks através de lazy loading.

O Metro pode ser usado para projetos web?

Tecnicamente sim, mas não é recomendado. O Metro não é otimizado para compilações web: não há suporte para CSS, HTML, imagens como módulos, nem code splitting com importações dinâmicas no nível do navegador. Para a web, use Webpack, Vite ou Parcel. O Metro é uma solução especializada para React Native, e tentar adaptá-lo para a web levará a perda de desempenho e falta de ecossistema de loaders.

Como o Metro difere do Re.Pack?

Re.Pack é uma ferramenta comunitária para substituir o Metro pelo Webpack em projetos React Native. Ela fornece acesso ao ecossistema de loaders do Webpack (css-loader, svg-loader) e code splitting avançado. No entanto, o Re.Pack é mais complexo de configurar, não é oficialmente suportado pelo Meta e não garante compatibilidade com novas versões do React Native. O Metro continua sendo o único agrupador oficialmente suportado, oferecendo estabilidade e compatibilidade garantida com cada versão.

Resumo

  • Metro Bundler — o agrupador oficial JavaScript do React Native com arquitetura Resolver-Transformer-Bundler
  • Extensões de plataforma (.ios.js, .android.js, .native.js) — característica chave para separação de código por plataforma
  • Fast Refresh — recarga a quente preservando o estado dos componentes, funciona via WebSocket
  • Configuração via metro.config.js: sourceExts, watchFolders, maxWorkers para otimização de compilação
  • Hermes bytecode — modo de compilação para bytecode para inicialização mais rápida e tamanho de bundle menor
  • Resolver usa Haste Module System e resolução com ciência de plataforma — incompatível com Webpack
  • Transformer funciona em paralelo via Babel com um pool de processos worker
  • O Metro é incluído no React Native CLI e não requer instalação ou configuração separada para começar

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também