PeachConfig
The main configuration object for Peach projects. Import from peachsim/config:
defineConfig is a typed pass-through; the file may also be plain CJS:
Module slots
There are four separate slots because the runtime resolves each differently.
modules
Record<string, ModuleResolution>: overrides for any Metro module by
path fragment. The key is matched against the Metro module name as a path
fragment, not a strict package name. A key like react-native-widgetkit
matches …/node_modules/react-native-widgetkit/index.js; a key like
dist/assets/config.json matches a deep file path inside a module.
Keys are sorted longest-first, so subpath keys can override package-level keys.
turboModules
Record<string, NativeModuleResolution>: modules served via the
TurboModuleRegistry surface. Keyed by the TurboModule name the guest
bundle requests (e.g. RNCAsyncStorage), not by JS module path.
nativeModules
Record<string, NativeModuleResolution>: modules served via the legacy
NativeModules surface and Expo’s requireNativeModule. Keyed by the
native module name the guest bundle requests (e.g. RNKeychainManager,
or an Expo module’s Name).
Replacement files may use the kit primitives through their family subpaths.
nativeViews
Record<string, NativeViewResolution>: the app’s own native views, each
replaced by a React component. Keyed by the native view name the guest
bundle asks for:
| the app calls | key |
|---|---|
requireNativeComponent('RNBalanceLabel') | RNBalanceLabel |
requireNativeView('MyModule', 'ProgressiveBlurView') | MyModule_ProgressiveBlurView |
requireNativeView('MyModule') | MyModule |
'noop' renders an empty view. A replacement file default-exports the component.
It receives exactly the props the app
passes to the native view, and may import react, react-native,
peach-kit and the packages Peach bridges for the app. A name with no
entry keeps Peach’s behavior: its built-in implementation, else an empty view.
See Native View Primitives for a typed progressive-blur replacement.
Module resolution kinds
turboModules and nativeModules additionally accept a direct native-module
object (any shape) for non-URL configs:
env
Record<string, string>: environment variables installed as process.env.*
inside the guest runtime.
Caveat: many React Native projects read env vars at bundle time via
Babel plugins (react-native-dotenv, Expo’s EXPO_PUBLIC_* inliner, …). Those
values are already baked into the bundle that Metro served. env here only
sets process.env.* for code that reads env at runtime; code that already
got its values inlined at bundle time will not see new values. To change
those, rebuild the bundle with the new env and reload.
settings
Partial<SettingsValues>: simulator settings overrides (device model,
appearance, network, locale, chrome). See
settings schema.
initialState
Initial app state passed to the simulator:
How the config reaches the runtime
The config travels as the ?peachConfig=<json> URL query param.
- +
applyPeachConfigToUrl(url, config)serializes into the param. - +
readPeachConfigFromSearchParams(searchParams)deserializes inside the engine. - +The engine preloads any
{ file: '…' }modules by fetching them through the/__sootsim-replacement-moduledev-server middleware (one project-local source file, whose imports are restricted toreact,react-native, and the packages the simulator bridges for this app). - +The bundle loader matches
moduleskeys against every__d()factory registration and serves the configured resolution instead.
mergePeachConfig(base, override) shallowly merges two configs by slot.