CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metro-config

Config parser and resolver for Metro bundler with support for loading, merging, and validating configuration files.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

default-config.mddocs/

Default Configuration

Generate sensible default configuration for Metro bundler with all required options and platform-specific settings.

Capabilities

Get Default Configuration

Returns a complete Metro configuration with sensible defaults for all components.

/**
 * Gets default Metro configuration with sensible defaults
 * @param rootPath - Project root directory (optional, defaults to auto-detected)
 * @returns Promise resolving to complete default Metro configuration
 */
function getDefaultConfig(rootPath?: string): Promise<ConfigT>;

Usage Examples:

import { getDefaultConfig } from "metro-config";

// Get default config with auto-detected project root
const defaultConfig = await getDefaultConfig();

// Get default config with specific project root
const defaultConfig = await getDefaultConfig('/path/to/project');

// Use as base for custom configuration
const customConfig = {
  ...await getDefaultConfig(),
  server: {
    ...defaultConfig.server,
    port: 3000 // Override port
  }
};

Get Default Values (Synchronous)

Access default configuration values synchronously (useful for testing or advanced scenarios).

/**
 * Gets default configuration values synchronously
 * @param rootPath - Project root directory (optional)
 * @returns Complete default Metro configuration object
 */
getDefaultConfig.getDefaultValues(rootPath?: string): ConfigT;

Usage Examples:

import { getDefaultConfig } from "metro-config";

// Get default values synchronously
const defaults = getDefaultConfig.getDefaultValues();

// With specific root path
const defaults = getDefaultConfig.getDefaultValues('/path/to/project');

Default Configuration Structure

Resolver Configuration

Module resolution settings for finding and processing files:

{
  resolver: {
    // Supported asset file extensions
    assetExts: ['bmp', 'gif', 'jpg', 'jpeg', 'png', 'psd', 'svg', 'webp', 'm4v', 'mov', 'mp4', 'mpeg', 'mpg', 'webm', 'aac', 'aiff', 'caf', 'm4a', 'mp3', 'wav', 'html', 'pdf', 'yaml', 'yml', 'otf', 'ttf', 'zip'],
    
    // Supported asset resolutions (for @2x, @3x assets)
    assetResolutions: ['1x', '1.5x', '2x', '3x', '4x'],
    
    // Supported platforms
    platforms: ['ios', 'android', 'native', 'web'],
    
    // Source file extensions
    sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx'],
    
    // Files/directories to exclude
    blockList: [/(^|\/|\\)node_modules($|\/|\\)/],
    
    // Module resolution settings
    disableHierarchicalLookup: false,
    enableGlobalPackages: false,
    resolverMainFields: ['browser', 'main'],
    useWatchman: true,
    
    // Package exports support
    unstable_enablePackageExports: true,
    unstable_conditionNames: [],
    unstable_conditionsByPlatform: {
      web: ['browser']
    }
  }
}

Serializer Configuration

Bundle serialization and output settings:

{
  serializer: {
    // Module ID generation
    createModuleIdFactory: () => (path) => hash(path),
    
    // Bundle execution statements
    getRunModuleStatement: (moduleId, globalPrefix) => `__r(${JSON.stringify(moduleId)});`,
    
    // Polyfills and initialization
    getPolyfills: () => [],
    getModulesRunBeforeMainModule: () => [],
    polyfillModuleNames: [],
    
    // Module filtering
    processModuleFilter: (module) => true,
    isThirdPartyModule: (module) => /(?:^|[/\\])node_modules[/\\]/.test(module.path),
    
    // Custom serialization
    customSerializer: null,
    experimentalSerializerHook: () => {}
  }
}

Server Configuration

Development server settings:

{
  server: {
    // Server configuration
    port: 8081,
    forwardClientLogs: true,
    useGlobalHotkey: true,
    verifyConnections: false,
    
    // URL rewriting
    rewriteRequestUrl: (url) => url,
    
    // Middleware enhancement (deprecated)
    enhanceMiddleware: (middleware, server) => middleware,
    
    // Server root (experimental)
    unstable_serverRoot: null
  }
}

Transformer Configuration

Code transformation settings:

{
  transformer: {
    // Babel transformer
    babelTransformerPath: 'metro-babel-transformer',
    enableBabelRCLookup: true,
    enableBabelRuntime: true,
    
    // Asset handling
    assetRegistryPath: 'missing-asset-registry-path',
    assetPlugins: [],
    
    // Transform options
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false,
        unstable_disableES6Transforms: false
      },
      preloadedModules: false,
      ramGroups: []
    }),
    
    // Minification
    minifierPath: 'metro-minify-terser',
    minifierConfig: {
      mangle: { toplevel: false },
      output: { 
        ascii_only: true,
        quote_style: 3,
        wrap_iife: true 
      },
      compress: { reduce_funcs: false }
    },
    
    // Performance settings
    optimizationSizeLimit: 150 * 1024, // 150 KiB
    unstable_workerThreads: false,
    
    // Module handling
    dynamicDepsInPackages: 'throwAtRuntime',
    allowOptionalDependencies: false,
    
    // Experimental features
    unstable_allowRequireContext: false,
    unstable_disableModuleWrapping: false,
    unstable_compactOutput: false
  }
}

Watcher Configuration

File watching and health check settings:

{
  watcher: {
    // Additional file extensions to watch
    additionalExts: ['cjs', 'mjs'],
    
    // Health check system
    healthCheck: {
      enabled: false,
      filePrefix: '.metro-health-check',
      interval: 30000, // 30 seconds
      timeout: 5000    // 5 seconds
    },
    
    // Auto-save cache
    unstable_autoSaveCache: {
      enabled: true,
      debounceMs: 5000
    },
    
    // Performance optimizations
    unstable_lazySha1: true,
    unstable_workerThreads: false,
    
    // Watchman integration
    watchman: {
      deferStates: ['hg.update']
    }
  }
}

Core Configuration

Core Metro settings:

{
  // Project settings
  projectRoot: '/path/to/project',
  watchFolders: [],
  
  // Caching
  cacheVersion: '1.0',
  cacheStores: [
    new FileStore({
      root: path.join(os.tmpdir(), 'metro-cache')
    })
  ],
  
  // Worker processes
  maxWorkers: require('os').cpus().length,
  stickyWorkers: true,
  
  // Transformer worker
  transformerPath: 'metro-transform-worker',
  
  // Development
  resetCache: false,
  reporter: new TerminalReporter(new Terminal(process.stdout)),
  
  // Performance logging
  unstable_perfLoggerFactory: () => ({
    point: () => {},
    annotate: () => {},
    subSpan: () => this
  })
}

Platform-Specific Defaults

Web Platform

When building for web, additional defaults are applied:

{
  resolver: {
    unstable_conditionsByPlatform: {
      web: ['browser']
    }
  }
}

React Native

Default configuration is optimized for React Native development:

  • Asset extensions include native image and video formats
  • Platforms include 'ios', 'android', 'native'
  • Resolver configured for React Native module resolution
  • Transform options optimized for mobile performance

Customizing Defaults

Override Specific Options

import { getDefaultConfig } from "metro-config";

const config = {
  ...await getDefaultConfig(),
  server: {
    ...defaultConfig.server,
    port: 3000 // Custom port
  },
  resolver: {
    ...defaultConfig.resolver,
    sourceExts: [...defaultConfig.resolver.sourceExts, 'svg'] // Add SVG support
  }
};

Environment-Specific Defaults

import { getDefaultConfig } from "metro-config";

async function createConfig() {
  const baseConfig = await getDefaultConfig();
  
  if (process.env.NODE_ENV === 'production') {
    return {
      ...baseConfig,
      transformer: {
        ...baseConfig.transformer,
        minifierConfig: {
          ...baseConfig.transformer.minifierConfig,
          compress: {
            ...baseConfig.transformer.minifierConfig.compress,
            drop_console: true // Remove console.log in production
          }
        }
      }
    };
  }
  
  return baseConfig;
}

Project Root Detection

If no rootPath is provided, Metro Config automatically detects the project root:

  1. Looks for the nearest package.json file
  2. Defaults to two levels up from node_modules/metro/
  3. Falls back to current working directory
// These are equivalent if run from project root
const config1 = await getDefaultConfig();
const config2 = await getDefaultConfig(process.cwd());
const config3 = await getDefaultConfig('./');

docs

config-loading.md

config-merging.md

default-config.md

index.md

tile.json