WDK logoWDK documentation

Worklet Bundler Configuration

Configure wdk.config.js and generate Bare worklet bundles with @tetherto/wdk-worklet-bundler

This page shows how to install @tetherto/wdk-worklet-bundler and its Pear runtime, shape wdk.config.js, and generate a Bare worklet bundle for your WDK modules.

Install the packages

Install the bundler as a development dependency and Pear Worklet as a runtime dependency in the host project:

Install The Bundler And Runtime
npm install @tetherto/pear-wrk-wdk@1.0.0-beta.10
npm install --save-dev @tetherto/wdk-worklet-bundler@1.0.0-beta.7

Worklet Bundler beta.7 generates entrypoints that import Pear Worklet, but generate --install does not add that package. Pear Worklet beta.10 provides the JSON-RPC, HRPC generic-module, and Swidge protocol behavior documented here.

Create wdk.config.js

Use init to create a starter config, or write the file yourself:

Initialize A Starter Config
npx wdk-worklet-bundler init

The published config surface accepts networks, optional protocols, HRPC-only generic modules, transport, preloadModules, output, and options:

Example wdk.config.js
module.exports = {
  networks: {
    ethereum: {
      package: '@tetherto/wdk-wallet-evm-erc-4337'
    },
    bitcoin: {
      package: '@tetherto/wdk-wallet-btc'
    }
  },

  protocols: {
    moonpay: {
      package: '@tetherto/wdk-protocol-fiat-moonpay'
    }
  },

  modules: {
    preferences: {
      package: '@your-org/wdk-module-preferences',
      factory: 'createModule',
      events: ['changed']
    }
  },

  transport: 'hrpc',

  preloadModules: [
    'spark-frost-bare-addon'
  ],

  output: {
    bundle: './.wdk-bundle/wdk-worklet.bundle.js'
  },

  options: {
    targets: ['ios-arm64', 'android-arm64']
  }
}

Required fields

networks

networks is required. Each key is a logical network name, and each value must provide a package string for the wallet module to bundle.

The loader also accepts local paths that resolve relative to the config file’s directory:

Use A Local Wallet Package
module.exports = {
  networks: {
    local_dev: {
      package: './local-packages/my-custom-wallet'
    }
  }
}

Optional fields

protocols (optional)

Use protocols when the worklet should preload WDK protocol packages alongside wallet modules.

modules (optional, HRPC only)

Use modules for named generic packages that expose a module factory. Each entry supports:

  • package (string, required): Package name or local path.
  • factory (string, optional): Named factory export. When omitted, the package's callable default export is used.
  • events (string[], optional): Event names forwarded from the worklet to the host.

The factory receives { seed, config, capabilities, emit } and can return the module instance or a promise for it. A module that needs the seed must consume it synchronously rather than retain it. The build-time name, such as preferences, must match the key in the host's runtime module config.

Through beta.7, generic modules are included only in generated HRPC entrypoints. Do not configure modules with transport: 'jsonrpc'; the current schema accepts the field, but JSON-RPC generation ignores it.

transport (optional)

Choose hrpc or jsonrpc. HRPC is the default and is the transport used by React Native Core. JSON-RPC produces a length-prefixed bundle for a native host and enables addon linking and ESM-to-CJS conversion by default.

preloadModules (optional)

Use preloadModules for native addons or other modules that must be required before the generated worklet starts.

output (optional)

Supported output fields are:

  • bundle: Bundle path. Defaults to ./.wdk-bundle/wdk-worklet.bundle.js for HRPC and ./.wdk-bundle/wdk-worklet.bundle for JSON-RPC.
  • types: Declared in the beta.7 config type, but the generator does not honor a custom value and always writes declarations to ./.wdk/index.d.ts.
  • addons.ios, addons.macos, addons.android: Platform addon directories. Defaults are ./ios-addons, ./mac-addons, and ./android-addons.
  • addonsYml: BareKit Swift dependency file. Defaults to ./ios-addons/addons.yml and is generated when iOS addons are linked.

options (optional)

The published config type supports these build options:

  • minify (boolean): Declared in the beta.7 config type but not read by the bundle path. JSON-RPC ESM-to-CJS conversion minifies independently of this field.
  • sourceMaps (boolean): Declared in the beta.7 config type but not read by the bundle path, so it does not produce source maps.
  • targets (string[]): Override the default Bare build hosts. The shipped defaults cover iOS arm64 and simulator targets plus Android arm, arm64, ia32, and x64 hosts.
  • linkAddons (boolean): Link native addons with bare-link. Defaults to true for JSON-RPC and false for HRPC.
  • platforms (('ios' | 'macos' | 'android')[]): Addon platforms. Defaults to all three when addon linking is active.
  • swiftTarget (string): Xcode target written to addons.yml. Defaults to app.
  • convertEsmToCjs (boolean): Convert the bundle for JSC runtimes. Defaults to true for JSON-RPC and false for HRPC. Android uses V8, so Android-only JSON-RPC builds can set this to false.

Configure JSON-RPC and native addons

Use JSON-RPC when a native host will implement Pear Worklet's length-prefixed JSON-RPC protocol:

JSON-RPC wdk.config.js
module.exports = {
  networks: {
    ethereum: {
      package: '@tetherto/wdk-wallet-evm'
    }
  },
  transport: 'jsonrpc',
  output: {
    addons: {
      ios: './ios-addons',
      macos: './mac-addons',
      android: './android-addons'
    },
    addonsYml: './ios-addons/addons.yml'
  },
  options: {
    platforms: ['ios', 'android'],
    swiftTarget: 'app'
  }
}

JSON-RPC generation defaults to a bundle without a .js suffix, ESM-to-CJS conversion, and addon linking. It links bare-posix with the other required Bare modules automatically. See the Pear Worklet API reference for framing and supported methods.

Validate dependencies

Use validate to check the config and dependency resolution before you generate the bundle:

Validate wdk.config.js
npx wdk-worklet-bundler validate

Handle peer dependencies

Worklet Bundler beta.7 separates required peers from peers explicitly marked optional through peerDependenciesMeta:

  • During bundle generation, missing required peers are offered for installation. In a non-interactive environment without --install, the CLI prints the exact manual install command and continues; bare-pack can still fail if the bundle needs that peer. The peer scan is skipped by --source-only.
  • Missing optional peers are not prompted for or installed. By default, the bundler passes each one to bare-pack --defer, so an unused optional feature does not block the build.
  • Optional peers detected anywhere in the scanned package tree are not deferred. Beta.7 matches package names across root, nested, scoped, and symlinked package trees; install a peer in an ancestor node_modules visible to the package that imports it, because the same package name elsewhere in the tree can suppress deferral without making that import resolvable. A peer that is required anywhere else in the scanned dependency tree is treated as required and is not deferred.

Use --no-defer-optional-peers when the app uses an optional feature and you want a missing peer to fail during the build:

Require Optional Peers At Build Time
npx wdk-worklet-bundler generate --no-defer-optional-peers

For example, a bundle can build while a missing @ledgerhq/ledger-bitcoin peer is deferred, then fail at runtime if the app uses the corresponding Ledger feature. Install the peer explicitly, or use --no-defer-optional-peers to surface the missing import during bundling.

This behavior is a per-run setting. wdk.config.js has no deferOptionalPeers field. Programmatic callers can set GenerateBundleOptions.deferOptionalPeers to false; omitting it or setting it to true keeps the default deferral behavior.

If a core configured dependency is missing, a non-interactive generate run that will invoke bare-pack exits with status 1 and tells you to install it manually or rerun with --install. A --source-only run can still emit the generated source files.

Generate the bundle

Use generate to build the worklet artifact:

Generate The Worklet Bundle
npx wdk-worklet-bundler generate --install

generate --install can auto-install missing configured wallet, protocol, generic, and preload modules after the package manager is detected from the project root. In beta.7 it does not install the Pear Worklet runtime imported by generated entrypoints; install Pear explicitly as shown above. Use --source-only when you want the generated .wdk/wdk-worklet.generated.js entrypoint and related artifacts without running bare-pack.

The generate command also accepts --transport hrpc|jsonrpc, --link-addons, --skip-link-addons, --platforms ios,macos,android, --no-esm-to-cjs, and --no-defer-optional-peers. Set transport in wdk.config.js when you rely on its transport-specific default bundle path. In beta.7, --transport changes the generated transport after output paths have already been resolved, so it does not switch .js HRPC output to the extensionless JSON-RPC default, or vice versa. If you use the flag, set output.bundle explicitly to the intended path.

Suspend and resume behavior

Generated HRPC worklet entrypoints register Bare lifecycle handlers for suspend and resume, then apply those handlers to both the bare-http1 and bare-https global agents. No config flag is required for this behavior.

This matters when a generated HRPC worklet performs HTTPS-backed fetches. Starting in beta.3, those generated entrypoints suspend and resume both agents together.

Troubleshooting

  • If loadConfig() cannot find a config file, run npx wdk-worklet-bundler init or pass --config \<path\>.
  • If validate or generate reports missing modules, use generate --install or inspect the install command from the exported helper APIs in the API Reference.
  • If you need to inspect generated source before bundling, use generate --source-only and review the files in .wdk/.

Need Help?

On this page