Metro: o que é, principais recursos e princípio de funcionamento

Autor: IT Sectr Publicado: 2026-05-19 Tempo de leitura: 8 min

Metro é um bundler JavaScript desenvolvido especificamente para React Native e usado por padrão para compilar aplicativos móveis nesta plataforma. Ao contrário dos bundlers universais, o Metro é otimizado para os recursos limitados de dispositivos móveis e fornece integração com o motor Hermes e Fast Refresh. De acordo com Metro Documentation (2026), o bundler lida com mais de 90% dos projetos React Native no mundo.

Principais pontos

  • Metro é o bundler padrão para React Native, otimizado para desenvolvimento móvel em iOS e Android.
  • Arquitetura de três fases do Metro inclui resolução de módulos, transformação e serialização no bundle de saída.
  • Fast Refresh é um mecanismo de recarga a quente de componentes sem perda de estado da aplicação.
  • Inline Requires adiam o carregamento de módulos até sua primeira chamada, reduzindo o bundle inicial.
  • Hermes é um motor JavaScript da Meta que usa o Metro para gerar bytecode pré-compilado.

O que é Metro?

Metro é um bundler JavaScript de código aberto criado pela equipe da Meta para React Native. Ele substituiu o Packager das versões anteriores do React Native e se tornou a ferramenta de compilação padrão para esta plataforma. O Metro não foi projetado para desenvolvimento web: sua arquitetura é focada exclusivamente em aplicativos móveis executados nos motores JavaScript JSC (JavaScriptCore) ou Hermes.

História e posicionamento

Metro surgiu em 2018 como substituto do antigo React Native Packager. A principal razão para sua criação foi a necessidade de um bundler que funcionasse eficientemente com milhões de módulos em grandes aplicativos móveis. Ao contrário do Webpack, o Metro não suporta CSS, HTML ou imagens como módulos — esses recursos são tratados por ferramentas separadas do React Native. O Facebook usa o Metro para compilar seu aplicativo principal, que contém mais de 100 mil arquivos.

O Metro é distribuído via npm como pacote metro e é instalado automaticamente com o React Native CLI. A versão do Metro está vinculada à versão do React Native, portanto, a atualização do bundler ocorre junto com a atualização da plataforma.

Como funciona o bundler Metro?

Metro recebe como entrada o ponto de entrada da aplicação, constrói um grafo de dependências, transforma cada módulo e serializa o resultado em um único bundle. O processo passa por três fases: Resolve (resolução de módulos), Transform (transformação) e Serialize (serialização).

Processo de compilação no Metro

js
// Exemplo de configuração do Metro para transformação personalizada
const metroConfig = {
  transformer: {
    babelTransformerPath: require('metro-babel-transformer'),
    async transform({ src, filename, options }) {
      const result = await babelTransform({ src, filename, options });
      return {
        ast: result.ast,
        code: result.code,
        map: result.map,
        dependencies: [],
      };
    },
  },
  serializer: {
    createModuleIdFactory() {
      let nextId = 0;
      const moduleIds = new Map();
      return ({ path }) => {
        if (!moduleIds.has(path)) {
          moduleIds.set(path, nextId++);
        }
        return moduleIds.get(path);
      };
    },
  },
};

Na fase Resolve, o Metro determina a localização de cada módulo importado, levando em conta aliases e node_modules. Na fase Transform, cada arquivo passa por um transformador Babel para converter JSX, TypeScript e outras extensões em JavaScript puro. A fase final Serialize coleta todos os módulos transformados em um ou mais arquivos bundle.

Arquitetura do Metro

Metro é construído sobre uma arquitetura modular onde cada etapa de compilação é implementada como um componente independente. Isso permite substituir módulos padrão por personalizados sem alterar o núcleo do bundler. A arquitetura do Metro inclui três pacotes principais: metro, metro-config e metro-resolver.

Componentes chave do Metro

Metro Server — um servidor de desenvolvimento que inicia com o comando npx react-native start. Ele atende solicitações de transformação de módulos em tempo real, fornecendo Fast Refresh. Module Store — um cache que armazena módulos transformados em memória para acelerar recompilações. Dependency Graph — um grafo de dependências que é atualizado incrementalmente quando os arquivos mudam.

Watchman — um observador de arquivos da Meta que o Metro usa para detectar alterações no sistema de arquivos. Sem o Watchman, o Metro precisa escanear toda a estrutura de arquivos a cada mudança, o que retarda significativamente o desenvolvimento. A instalação do Watchman é obrigatória para trabalhar confortavelmente com o Metro em projetos de qualquer tamanho.

Configuração do Metro em um projeto React Native

A configuração do Metro é definida no arquivo metro.config.js na raiz do projeto. Um arquivo típico define pastas adicionais para busca de módulos, listas de bloqueio para excluir arquivos desnecessários e transformadores personalizados. No React Native 0.72+, é usada a detecção automática de configuração, mas para monorepos a configuração é obrigatória.

Configuração básica do Metro para React Native

js
// metro.config.js
const config = {
  resolver: {
    sourceExts: ['js', 'jsx', 'ts', 'tsx', 'json'],
    nodeModulesPaths: ['node_modules'],
    blockList: [/\.test\.js$/, /__tests__\/.*/],
    extraNodeModules: {
      'shared-components': path.resolve(__dirname, '../shared/src'),
    },
  },
  transformer: {
    minifierConfig: {
      keep_classnames: true,
      keep_fnames: true,
      mangle: { reserved: ['React', 'Component'] },
    },
  },
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

blockList exclui arquivos de teste da compilação, reduzindo o tamanho do bundle. nodeModulesPaths especifica caminhos adicionais para busca de pacotes — crítico para monorepos. extraNodeModules cria aliases para pacotes compartilhados usados em diferentes projetos do monorepo.

Otimização de compilação do Metro

Metro fornece vários mecanismos para otimizar o tamanho do bundle e a velocidade de compilação. Inline Requires — a técnica mais eficaz, que converte importações de nível superior em chamadas require locais dentro de funções. RAM bundles permitem carregar módulos incrementalmente. Hermes compila JavaScript em bytecode, reduzindo o tamanho da aplicação em 20–30%.

Habilitando Inline Requires e Hermes

js
// metro.config.js — otimização para produção
const config = {
  transformer: {
    async transform({ src, filename, options }) {
      const inlineRequires = options.dev ? false : true;
      return await defaultTransform({ src, filename, options: { ...options, inlineRequires } });
    },
  },
  serializer: {
    polyfillModuleNames: [],
  },
};

// Para habilitar o Hermes — no build.gradle (Android):
// project.ext.react = [enableHermes: true, bundleInRelease: true]
// Para iOS — no Podfile: :hermes_enabled => true

Para diagnóstico do tamanho do bundle, o Metro fornece a flag --bundle-output com saída de estatísticas. Use bundle-visualizer para analisar a composição do bundle e encontrar módulos grandes que podem ser carregados de forma preguiçosa. A verificação regular do tamanho do bundle deve fazer parte do pipeline CI/CD do projeto React Native.

Delta Bundles e compilação incremental

Metro suporta delta bundles — um mecanismo onde, após a primeira compilação completa, o servidor envia apenas as alterações (delta) entre as versões antiga e nova do bundle. Isso acelera radicalmente as compilações subsequentes: o tempo de atualização cai de segundos para dezenas de milissegundos. Delta bundles são especialmente eficazes durante o desenvolvimento, quando o desenvolvedor salva alterações com frequência e recarrega a aplicação.

Para habilitar delta bundles no React Native, usa-se a flag --delta no comando npx react-native bundle. No lado do cliente, delta bundles são suportados a partir do React Native 0.64. Em compilações de produção, delta bundles não são usados — em vez disso, é usado um bundle completo com bytecode Hermes para máximo desempenho de inicialização. Isso é alcançado porque o ganho de velocidade no desenvolvimento compensa o custo da primeira compilação completa.

Hermes e Metro: trabalho conjunto

Hermes é um motor JavaScript desenvolvido pela Meta especificamente para React Native. O Metro gera bytecode Hermes durante a compilação, permitindo que a aplicação inicie sem uma compilação JavaScript cara no dispositivo. Para habilitar o Hermes, basta adicionar enableHermes: true no metro.config.js e configurar o build.gradle ou Podfile. O Hermes reduz o tempo de inicialização da aplicação em 30–50% e reduz o tamanho do APK em 20–30% em comparação com o JavaScriptCore.

Ao usar o Hermes, é importante lembrar das limitações: o motor não suporta Proxy, Reflect e alguns recursos do ES6. A maioria das aplicações React Native não usa esses recursos diretamente, mas algumas bibliotecas podem entrar em conflito. Antes de habilitar o Hermes, verifique a compatibilidade de todas as dependências do projeto através da lista de verificação oficial de compatibilidade. O Metro muda automaticamente para o modo de geração de bytecode quando o Hermes é ativado.

Monitoramento de desempenho do Metro

Para acompanhar a eficiência de compilação do Metro, use as métricas integradas disponíveis através do Flipper — a ferramenta de depuração do React Native. O Metro publica eventos: bundle_request, transform, resolve com tempo de execução de cada etapa. A análise desses dados ajuda a identificar gargalos: se a fase de transformação levar mais de 70% do tempo, o problema está no transformador Babel. Ative o registro de logs do Metro através da flag --verbose para diagnóstico detalhado.

Perguntas frequentes

Pode-se substituir Metro por Webpack no React Native?

Tecnicamente sim — existem projetos experimentais como react-native-webpack, mas eles não são suportados oficialmente. Metro está integrado com a bridge do React Native, Turbo Modules e Hermes em um nível inacessível para o Webpack. Substituir o Metro resultaria na perda do Fast Refresh e do suporte oficial.

Por que o Metro não suporta CSS?

React Native não usa CSS para estilização — em vez disso, a estilização JavaScript é aplicada através de StyleSheet.create. Como o Metro foi criado exclusivamente para React Native, o suporte a CSS não é necessário. Para renderização web através do React Native Web, o CSS é tratado por ferramentas separadas fora do Metro.

Como o Metro lida com imagens e fontes?

Metro não processa imagens ou fontes como módulos. Os recursos são importados via require('./image.png'), mas o Metro apenas os registra como dependências de string. O carregamento real de imagens é realizado pelo código nativo do React Native através do componente Image, e o Metro copia os recursos para o bundle.

Como o Metro difere do Rollup?

Rollup gera módulos ES com tree shaking em nível de módulo, resultando em tamanho mínimo de bundle para bibliotecas. Metro gera um bundle CommonJS com transformação inline e otimização para motores móveis. Rollup não suporta Fast Refresh e não pode trabalhar com módulos nativos do React Native.

Como acelerar a compilação a frio do Metro?

A compilação a frio do Metro é lenta devido à varredura completa de node_modules. Soluções: adicione watchFolders para monorepos, use maxWorkers para transformação paralela e instale Watchman. Para projetos com mais de 10.000 arquivos, considere metro-memory-fs para cache em memória.

Resumo

  • Metro é o bundler padrão do React Native, otimizado para plataformas móveis com recursos limitados.
  • Arquitetura de três fases (Resolve, Transform, Serialize) permite compilações incrementais e Fast Refresh.
  • Fast Refresh — recarga a quente de componentes modificados sem perda de estado da aplicação.
  • Inline Requires adiam o carregamento de módulos até a primeira chamada, reduzindo o bundle inicial em 15–30%.
  • Hermes — um motor JavaScript da Meta que compila JS em bytecode através do Metro para inicialização mais rápida.
  • Watchman — um observador de arquivos obrigatório para trabalhar confortavelmente com o Metro em projetos com grande número de arquivos.
  • Para monorepos, é necessária a configuração de watchFolders e extraNodeModules para resolução correta de módulos.

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