Bare Docs

Embed Bare in a React Native app

Run a Bare worklet from a React Native or Expo app and exchange messages with it over the bare-kit IPC channel.

This guide runs a Bare core inside a React Native app using react-native-bare-kit, and wires a two-way message channel between the UI and the core. This is the practical version of the pattern described in One core, many platforms: your peer-to-peer logic lives in the worklet, your UI stays native.

You'll need an existing React Native or Expo project to add this to.

Install the kit

Install react-native-bare-kit, and bare-stow to link Bare Kit into the app. bare-stow wraps the worklet entry in code that imports bare-stow-runtime, so install that too:

npm i react-native-bare-kit b4a bare-stow-runtime
npm i -D bare-stow

From 0.17.0, react-native-bare-kit doesn't include Bare Kit itself, so the app links it in the next steps. For Expo, use the config plugin of expo-bare-kit 0.3.0 or later, which links Bare Kit and the workers you list in its workers option. The worklet code below is identical. Upgrading an app from 0.16 or earlier? See Migrate to Bare Kit 3.

Write the Bare core

The worklet entry script runs on its own thread. It reaches the host through Bare.IPC, a duplex stream. Here it echoes back whatever it receives:

// app.js—runs inside the worklet
const IPC = Bare.IPC

IPC.on('data', (data) => {
  const message = data.toString()
  IPC.write(Buffer.from(`echo: ${message}`))
})

This is ordinary Bare code: it can require any bare-* module and open a Hyperswarm or Corestore just as it would on the desktop.

Pass the worklet's entry point to bare-stow link. It writes a Swift package and a Gradle module that bring in Bare Kit, through bare-kit-swift and bare-kit-kotlin, along with any native addons and assets that the core loads:

npx bare-stow link --target bare-kit --language swift --out ios/BareKitResources app.js
npx bare-stow link --target bare-kit --language kotlin --language-option package=com.example.addons --out android/bare-kit-resources app.js

Add the Swift package to the app target in Xcode, together with its bare-stow folder if the core references assets. Include the Gradle module in the Android app. bare-kit-kotlin is published on JitPack and needs Kotlin 2.4 or later and Android 10 (API level 29) or later, so add maven { url "https://jitpack.io" } to the app's repositories and raise kotlinVersion and minSdkVersion if they're lower. Run the commands again whenever the core's dependencies change. Without Bare Kit in the app, new Worklet() throws. See Linking addons and assets.

On iOS, also sign the app with the com.apple.developer.kernel.extended-virtual-addressing entitlement, which Bare Kit 3.1.0 and later need on a device. See iOS entitlement.

Start the worklet from React Native

In your React Native component—for example App.tsx, not the worklet's /app.js—create a Worklet, start it with the core's source, and read and write the IPC object it exposes:

import { Worklet } from 'react-native-bare-kit'
import b4a from 'b4a'

const source = `
const IPC = Bare.IPC
IPC.on('data', (data) => IPC.write(Buffer.from('echo: ' + data.toString())))
`

const worklet = new Worklet()
worklet.start('/app.js', source)

const { IPC } = worklet
IPC.on('data', (data) => console.log(b4a.toString(data)))
IPC.write(b4a.from('Hello from React Native!'))

The worklet honours the Bare lifecycle, so call worklet.suspend() and worklet.resume() from your app's background/foreground handlers to keep the core in step with the OS.

Run it

Build and run on a simulator or device with your usual React Native toolchain. Worklet console.* output is written to the system log under the bare identifier—view it with the platform's native logging tools (Console.app on iOS, logcat on Android).

echo: Hello from React Native!

The worklet must stop all active I/O when backgrounded or the OS will force-terminate it. See Handle app suspension for patterns covering TCP servers, Hyperswarm, timers, and IPC handles.

Next steps

  • Inlining source is fine for a snippet, but real apps ship a prebuilt bundle. See Bundle a Bare app to produce a .bundle and load it with worklet.start('/app.bundle', bundle).
  • Passing raw bytes gets unwieldy fast. See Type a native RPC bridge to put typed, schema-generated methods on top of this IPC channel.
  • For the full Worklet and IPC API, see the bare-kit reference.

Last updated on

Was this helpful?

On this page