React Native package.json Dependencies: Runtime, Peer, and Build Tooling Explained
React Native's core package.json declares 30+ runtime dependencies—including Metro, Hermes, and specialized @react-native tooling—and peer dependencies on React, forming the architectural backbone of the cross-platform framework.
The facebook/react-native repository organizes its core JavaScript layer inside packages/react-native/package.json, where every runtime capability, build tool, and platform integration is explicitly versioned and declared. Understanding these React Native package.json dependencies reveals how the framework bridges JavaScript code to native Android and iOS modules, manages assets, and bundles application code through Metro.
Runtime Dependencies in React Native
React Native bundles essential capabilities directly into its runtime. These dependencies are installed automatically when you add react-native to a project and provide everything from JavaScript engine support to Gradle build integration.
Metro Bundler and Build Tooling
The framework relies heavily on Metro for JavaScript bundling. The package.json lists:
metro-runtime– Provides the runtime helpers that injected modules use to communicate with the Metro bundler during development and production builds.metro-source-map– Handles source map generation for debugging transformed JavaScript code.babel-plugin-syntax-hermes-parser– Enables Babel to parse Hermes-specific JavaScript syntax during the transformation pipeline.
According to the source code in packages/react-native/package.json (lines 64–97), these packages work together to transform JSX and TypeScript into bytecode consumable by the Hermes engine.
React Native Core Packages
The @react-native scope contains first-party utilities that ship with every React Native app:
@react-native/assets-registry– Manages static assets like images and fonts, mapping logical names to native platform resources.@react-native/codegen– Generates native module boilerplate for TurboModules and Fabric components, bridging JavaScript to C++ and platform-specific code.@react-native/community-cli-plugin– Integrates the React Native CLI with community tooling.@react-native/gradle-plugin– Provides Gradle build logic for Android projects, referenced inpackages/react-native/scripts/react_native_pods.rbfor CocoaPods parity.@react-native/js-polyfills– Injects essential JavaScript APIs missing in older Hermes or JSC runtimes.@react-native/virtualized-lists– Implements performant list components (FlatList,SectionList) using native view recycling.
JavaScript Engine and Polyfills
React Native supports multiple JavaScript engines, with Hermes as the default:
hermes-compiler– The Hermes bytecode compiler used during the Metro bundling process.abort-controller,whatwg-fetch,promise– Polyfills bringing modern Web APIs to the React Native environment.regenerator-runtime– Enables generator and async/await syntax in older runtime targets.scheduler– React's cooperative scheduling package, synchronized with the React Native render loop.
Development and Debugging Utilities
Several dependencies support the developer experience:
react-devtools-core– Backend integration for the standalone React DevTools profiler and component inspector.react-refresh– Implements Fast Refresh, allowing hot reloading of components without losing state.ws– WebSocket client used for the development server connection and debugging protocol.
Peer Dependencies and Optional Tooling
React Native uses peer dependencies to avoid bundling packages that must align with the consuming application's versions. As declared in packages/react-native/package.json (lines 51–55), these include:
react– The core UI library. React Native requires a matching React version to ensure hooks, context, and concurrent features work correctly across the renderer boundary.@react-native/jest-preset– Configures Jest for React Native testing environments. Marked as optional, so projects using other test runners can skip it.@types/react– TypeScript definitions for React. Also marked optional for JavaScript-only projects.
This peer-dependency structure prevents version mismatches between the React reconciler inside React Native and the React package provided by the application developer.
Practical Implementation of Key Dependencies
Registering Assets with @react-native/assets-registry
The asset registry dependency handles static resource mapping at runtime:
import { AssetRegistry } from '@react-native/assets-registry';
// Register a new image asset at runtime
AssetRegistry.registerAsset({
__packager_asset: true,
httpServerLocation: 'assets/images',
width: 256,
height: 256,
scales: [1, 2, 3],
name: 'logo',
type: 'png',
});
This code executes the AssetRegistry module referenced in packages/react-native/package.json, allowing the Metro bundler to link native drawable and asset catalog resources on Android and iOS.
High-Performance Lists with @react-native/virtualized-lists
For long scrolling lists, React Native re-exports components from its virtualized lists package:
import { FlatList } from '@react-native/virtualized-lists';
import React from 'react';
import { Text, View } from 'react-native';
const DATA = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);
export default function HugeList() {
return (
<FlatList
data={DATA}
keyExtractor={item => item}
renderItem={({ item }) => (
<View style={{ padding: 8 }}>
<Text>{item}</Text>
</View>
)}
/>
);
}
The FlatList component imported here comes directly from the @react-native/virtualized-lists dependency, which implements view recycling and windowing in native code.
Configuring Metro with metro-runtime
The Metro bundler's runtime support enables module resolution and hot reloading:
// metro.config.js (top-level project file)
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts },
} = await getDefaultConfig();
return {
transformer: {
// Enables the Metro runtime helpers used by React Native
babelTransformerPath: require.resolve('metro-react-native-babel-transformer'),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg'],
},
};
})();
This configuration leverages metro-runtime (declared in the core dependencies) to handle module loading and source mapping during development.
Where Dependencies Are Declared
The canonical list of React Native package.json dependencies lives in packages/react-native/package.json in the facebook/react-native repository:
- Dependencies section (lines 64–97): Declares runtime requirements including Metro, Hermes, and React Native internal packages.
- Peer dependencies section (lines 51–55): Specifies React and optional testing/TypeScript packages.
Additional architectural files that consume these dependencies include:
packages/react-native/index.js– Main entry point that re-exports the public API, importing from the dependency tree.packages/react-native/cli.js– CLI entry point that relies oncommanderandyargsfor command parsing.packages/react-native/scripts/prepack.js– Pre-publish script that prepares code-generation artifacts using@react-native/codegen.packages/react-native/scripts/react_native_pods.rb– Ruby script for iOS CocoaPods integration that references the Gradle plugin dependency for build consistency.
Summary
- React Native's
package.jsondeclares over 30 runtime dependencies—including Metro, Hermes compiler, and@react-nativescoped packages—that provide bundling, JavaScript engine support, and native module bridging. - Peer dependencies on
react,@react-native/jest-preset, and@types/reactensure version alignment with the consuming application while keeping optional tooling out of mandatory installs. - Key architectural files like
packages/react-native/package.json(lines 64–97 for dependencies, lines 51–55 for peer dependencies) andscripts/prepack.jswire these packages into the build pipeline. - Practical usage of dependencies includes asset registration via
@react-native/assets-registry, high-performance lists via@react-native/virtualized-lists, and Metro configuration throughmetro-runtime.
Frequently Asked Questions
What is the difference between runtime and peer dependencies in React Native?
Runtime dependencies are installed automatically when you add react-native to a project and include essential packages like metro-runtime, hermes-compiler, and @react-native/codegen. Peer dependencies—specifically react and optional packages like @react-native/jest-preset—must be provided by the consuming application to ensure version compatibility between React's reconciler and React Native's renderer.
Why is @types/react listed as an optional peer dependency?
The @types/react package provides TypeScript type definitions for React's APIs. It is marked optional in packages/react-native/package.json because many React Native projects use JavaScript rather than TypeScript. Making it optional prevents installation errors for JavaScript-only projects while allowing TypeScript users to install matching type definitions alongside their React version.
How does @react-native/codegen integrate with the build process?
The @react-native/codegen dependency generates C++ and platform-specific boilerplate for TurboModules and Fabric components. During the pre-publish phase, packages/react-native/scripts/prepack.js invokes this package to parse JavaScript/TypeScript interface definitions and generate native code that bridges JavaScript logic to Android (Java/Kotlin) and iOS (Objective-C/Swift) implementations.
Can I exclude specific React Native dependencies to reduce bundle size?
Most core dependencies like metro-runtime and @react-native/js-polyfills are required for the framework to function and cannot be safely removed. However, optional peer dependencies such as @react-native/jest-preset can be omitted if your project does not use Jest for testing. Custom Metro configurations can also tree-shake unused polyfills during production builds, though this requires careful testing to avoid runtime errors.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →