Bidirectional & typed
RN → native and native → RN. The same four markers — async, fire, stream, state — work in both directions over one transport.
React Native ↔ Native · Fully typed
One contract in TypeScript drives everything — JS types, runtime metadata, and generated Kotlin and Swift. No bridge boilerplate, no event-emitter bugs, no render-gating dance.
pnpm add @malopezr7/bridgekit pnpm bridgekit generate You write a contract once. BridgeKit gives you a typed proxy on the JS side, a typed interface to implement on the native side — a Kotlin interface on Android, a Swift protocol on iOS — reactive streams, observable state, and the code generator keeps them in lockstep through a contract hash.
// app-host.contract.ts — provided by NATIVE, consumed by RNimport { defineContract, t } from '@malopezr7/bridgekit/contract';
export const AppHost = defineContract('app.host', { methods: { showLogin: t.fire(), // fire-and-forget isLoggedIn: t.query(t.boolean()), // async request/response saveFile: t.query( t.object({ url: t.string(), name: t.string() }), t.literals('success', 'already-exists', 'cancelled', 'error'), { timeoutMs: null }, // interactive: never times out ), }, streams: { notifications: t.stream(t.string()), // lossless buffered by default }, state: { connectivity: t.state(t.object({ online: t.boolean() }), { online: false }), },});Bidirectional & typed
RN → native and native → RN. The same four markers — async, fire, stream, state — work in both directions over one transport.
Contract-first codegen
bridgekit generate reads your .contract.ts and emits committed, readable
Kotlin and Swift from the same source. Nitrogen never runs for feature code.
Reactive streams
Lossless-by-default flows replace event emitters and polling. Backpressure, sharing and cancellation are handled for you.
Observable state
Provider-owned, single-writer, synchronously readable. Initial values make every read total — the render-gating dance dies here.
Local-first resolution
A JS-provided contract resolves inside the runtime with zero native crossing — web target, standalone mode and tests work without Kotlin.
Testable & observable
In-memory loopback transport for plain Jest. Every op carries a correlation id;
BridgeKit.dump() prints bindings, streams, state and epoch.