or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-metro-runtime

Module required for evaluating Metro bundles with async loading and HMR support.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/metro-runtime@0.83.x

To install, run

npx @tessl/cli install tessl/npm-metro-runtime@0.83.0

0

# Metro Runtime

1

2

Metro Runtime provides essential runtime modules required for evaluating and executing Metro bundles in React Native applications. It enables asynchronous module loading, Hot Module Replacement (HMR), and includes necessary runtime polyfills for cross-platform development.

3

4

## Package Information

5

6

- **Package Name**: metro-runtime

7

- **Package Type**: npm

8

- **Language**: JavaScript (with Flow types)

9

- **Installation**: Automatically included by Metro bundler (no manual installation required)

10

11

## Core Imports

12

13

Metro Runtime modules are automatically included by Metro bundler and typically not imported manually. When needed for custom implementations:

14

15

```javascript

16

// Async module loading (typically available globally as require.importAll)

17

const asyncRequire = require("metro-runtime/modules/asyncRequire");

18

19

// Hot Module Replacement client (development only)

20

const HMRClient = require("metro-runtime/modules/HMRClient");

21

22

// Module stubs for optimization

23

const emptyModule = require("metro-runtime/modules/empty-module"); // exports {}

24

const nullModule = require("metro-runtime/modules/null-module"); // exports null

25

26

// Core require polyfill (injected globally by Metro bundler)

27

// Available as global.__r, global.__d, etc.

28

require("metro-runtime/polyfills/require");

29

30

// Package metadata access

31

const packageInfo = require("metro-runtime/package.json");

32

```

33

34

## Package Metadata Access

35

36

The package.json file is exposed as a direct export for accessing package metadata:

37

38

```javascript { .api }

39

// Package metadata access

40

const packageInfo = require("metro-runtime/package.json");

41

```

42

43

## Private Module Access

44

45

Metro Runtime exposes private modules for internal Metro bundler usage via wildcard patterns:

46

47

- `./private/*` - Maps to `./src/*.js`

48

- `./src/*.js` - Direct access to source files

49

- `./src/*` - Alternative access pattern

50

51

These are typically used by Metro bundler itself and not intended for direct application usage.

52

53

## Basic Usage

54

55

Metro Runtime is typically used automatically by Metro bundler, but can be used directly for custom bundling scenarios:

56

57

```javascript

58

const asyncRequire = require("metro-runtime/modules/asyncRequire");

59

const HMRClient = require("metro-runtime/modules/HMRClient");

60

61

// Load a module asynchronously with bundle splitting support

62

const loadFeature = async () => {

63

const featureModule = await asyncRequire(

64

42, // module ID

65

{ 42: "/bundles/feature.bundle.js" } // path mapping

66

);

67

return featureModule;

68

};

69

70

// Set up HMR client for development

71

const client = new HMRClient("ws://localhost:8081/hot");

72

client.enable();

73

74

client.on("update", (update) => {

75

console.log("Hot update received:", update);

76

});

77

```

78

79

## Architecture

80

81

Metro Runtime is built around several key components:

82

83

- **Async Loading System**: Handles dynamic imports and bundle splitting with support for lazy loading

84

- **HMR Client**: WebSocket-based client for receiving and applying hot updates during development

85

- **Module System Polyfills**: Cross-platform require implementation with React Native compatibility

86

- **Module Stubs**: Empty and null modules for build optimization and conditional loading

87

- **React Fast Refresh Integration**: Component-level hot reloading with state preservation

88

89

## Capabilities

90

91

### Asynchronous Module Loading

92

93

Core functionality for loading modules asynchronously with bundle splitting support. Enables dynamic imports and code splitting in Metro bundles.

94

95

```javascript { .api }

96

// Async module loading with bundle splitting support

97

function asyncRequire(moduleID: number, paths: ?DependencyMapPaths, moduleName?: string): Promise<any>;

98

99

// Synchronous version that may return promise if bundle loading required

100

asyncRequire.unstable_importMaybeSync = function(moduleID: number, paths: ?DependencyMapPaths): Promise<any> | any;

101

102

// Pre-loads bundle without executing module

103

asyncRequire.prefetch = function(moduleID: number, paths: ?DependencyMapPaths, moduleName?: string): void;

104

105

type DependencyMapPaths = ?$ReadOnly<{[moduleID: number | string]: mixed}>;

106

```

107

108

[Async Loading](./async-loading.md)

109

110

### Hot Module Replacement Client

111

112

WebSocket-based client for receiving and applying hot updates during development. Provides real-time code updates without losing application state.

113

114

```javascript { .api }

115

// Hot Module Replacement WebSocket client

116

class HMRClient extends EventEmitter {

117

constructor(url: string);

118

close(): void;

119

send(message: string): void;

120

enable(): void;

121

disable(): void;

122

isEnabled(): boolean;

123

hasPendingUpdates(): boolean;

124

}

125

126

type SocketState = 'opening' | 'open' | 'closed';

127

```

128

129

[HMR Client](./hmr-client.md)

130

131

### Require System Polyfill

132

133

Core Metro require system implementation with module loading, HMR support, and development utilities. Provides cross-platform module resolution and loading.

134

135

```javascript { .api }

136

// Core Metro require function (available as global.__r)

137

function metroRequire(moduleId: ModuleID | VerboseModuleNameForDev, maybeNameForDev?: string): Exports;

138

139

// Module definition function (available as global.__d)

140

function define(factory: FactoryFn, moduleId: number, dependencyMap?: DependencyMap, verboseName?: string, inverseDependencies?: InverseDependencyMap): void;

141

142

// Enhanced import functions

143

metroRequire.importDefault = function(moduleId: ModuleID | VerboseModuleNameForDev): any | Exports;

144

metroRequire.importAll = function(moduleId: ModuleID | VerboseModuleNameForDev): any | Exports | {[string]: any};

145

146

// Module ID utilities for segmented bundles

147

metroRequire.unpackModuleId = function(moduleId: ModuleID): {localId: number, segmentId: number};

148

metroRequire.packModuleId = function(value: {localId: number, segmentId: number}): ModuleID;

149

150

type ModuleID = number;

151

type VerboseModuleNameForDev = string;

152

type Exports = any;

153

```

154

155

[Require Polyfill](./require-polyfill.md)

156

157

### Module Stubs

158

159

Provides empty and null module stubs for build optimization and conditional loading scenarios.

160

161

```javascript { .api }

162

// Empty module stub - exports empty object {}

163

const emptyModule = require("metro-runtime/modules/empty-module");

164

165

// Null module stub - exports null

166

const nullModule = require("metro-runtime/modules/null-module");

167

```

168

169

These stubs are used by Metro bundler for:

170

- **Tree shaking optimization**: Replace unused modules with empty stubs

171

- **Conditional compilation**: Provide placeholder modules for platform-specific code

172

- **Build size reduction**: Replace heavy modules with lightweight stubs in certain contexts

173

174

## Types

175

176

Core type definitions used across Metro Runtime:

177

178

```javascript { .api }

179

type DependencyMapPaths = ?$ReadOnly<{[moduleID: number | string]: mixed}>;

180

181

type ModuleID = number;

182

type VerboseModuleNameForDev = string;

183

type Exports = any;

184

type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;

185

186

type FactoryFn = (

187

global: Object,

188

require: RequireFn,

189

metroImportDefault: RequireFn,

190

metroImportAll: RequireFn,

191

moduleObject: {exports: {...}, ...},

192

exports: {...},

193

dependencyMap: ?DependencyMap,

194

) => void;

195

196

// Module system types

197

type DependencyMap = $ReadOnly<ArrayIndexable<ModuleID> & {paths?: {[id: ModuleID]: string}}>;

198

type InverseDependencyMap = {[key: ModuleID]: Array<ModuleID>, ...};

199

type ArrayIndexable<T> = interface {+[indexer: number]: T};

200

201

// Bundle and module types

202

type ModuleMap = $ReadOnlyArray<[number, string]>;

203

204

type Bundle = {

205

+modules: ModuleMap,

206

+post: string,

207

+pre: string,

208

};

209

210

type DeltaBundle = {

211

+added: ModuleMap,

212

+modified: ModuleMap,

213

+deleted: $ReadOnlyArray<number>,

214

};

215

216

type BundleVariant =

217

| {+base: true, +revisionId: string, ...Bundle}

218

| {+base: false, +revisionId: string, ...DeltaBundle};

219

220

type BundleMetadata = {

221

+pre: number,

222

+post: number,

223

+modules: $ReadOnlyArray<[number, number]>,

224

};

225

226

// HMR types

227

type HmrUpdate = {

228

+added: $ReadOnlyArray<HmrModule>,

229

+deleted: $ReadOnlyArray<number>,

230

+isInitialUpdate: boolean,

231

+modified: $ReadOnlyArray<HmrModule>,

232

+revisionId: string,

233

};

234

235

type HmrModule = {

236

+module: [number, string],

237

+sourceMappingURL: string,

238

+sourceURL: string,

239

};

240

241

type FormattedError = {

242

+type: string,

243

+message: string,

244

+errors: Array<{description: string, ...}>,

245

};

246

247

// HMR message types

248

type HmrMessage =

249

| {+type: 'bundle-registered'}

250

| {+type: 'update-start', +body: {+isInitialUpdate: boolean}}

251

| {+type: 'update-done'}

252

| {+type: 'update', +body: HmrUpdate}

253

| {+type: 'error', +body: FormattedError};

254

255

type HmrClientMessage =

256

| {+type: 'register-entrypoints', +entryPoints: Array<string>}

257

| {+type: 'log', +level: 'trace' | 'info' | 'warn' | 'log' | 'group' | 'groupCollapsed' | 'groupEnd' | 'debug', +data: Array<mixed>, +mode: 'BRIDGE' | 'NOBRIDGE'}

258

| {+type: 'log-opt-in'};

259

260

// Development types (DEV only)

261

type HotModuleReloadingData = {

262

_acceptCallback: ?HotModuleReloadingCallback,

263

_disposeCallback: ?HotModuleReloadingCallback,

264

_didAccept: boolean,

265

accept: (callback?: HotModuleReloadingCallback) => void,

266

dispose: (callback?: HotModuleReloadingCallback) => void,

267

};

268

269

type HotModuleReloadingCallback = () => void;

270

```