The public JavaScript Runtime Kit API has one request function and one React read hook. Everything else stays outside app code.
Use this page when you need exact names, shapes, and failure boundaries. If you want to build a first feature, start with Package to screen. If you want copyable recipes, start with Runtime Kit Cookbook.Public imports
import {
sendRequestToBitfieldTarget,
type BitfieldTargetReply,
type BitfieldTargetRequest,
} from '@bitfield/runtime-kit';
import { useBitfieldData } from '@bitfield/runtime-kit/react';
| Import path | Public value | Use it for | Not public from that path |
|---|
@bitfield/runtime-kit | sendRequestToBitfieldTarget(...) | User actions that call a named target. | Read hooks, package parsing, target implementations, connection setup. |
@bitfield/runtime-kit | BitfieldTargetRequest, BitfieldTargetReply | TypeScript request/reply annotation. | Target-specific payload/reply schemas. |
@bitfield/runtime-kit/react | useBitfieldData(...) | React surfaces that read named data. | Providers, scopes, selector factories, subscriptions, address readers. |
The source guard is packages/js/src/public-surface.test.ts: the root package exports only sendRequestToBitfieldTarget, and the React subpath exports only useBitfieldData.sendRequestToBitfieldTarget(...)
function sendRequestToBitfieldTarget(
request: BitfieldTargetRequest,
signal?: AbortSignal,
): Promise<BitfieldTargetReply>;
This function sends one payload to one named target and returns reply bytes.Request type
type BitfieldTargetRequest = {
readonly target: string;
readonly payload?: unknown;
};
| Field | Type | Required | Constraints | Example | Common error |
|---|
target | string | yes | Must be a non-empty public action name. | "help.search" | Empty or non-string targets fail before the request is sent. |
payload | unknown | no | Converted to bytes before dispatch. Use the action reply shape to decide how to encode meaning. | { query: "pricing" } | Sending a shape the target does not understand returns a target-level failure. |
Payload conversion
| Payload value | Bytes sent | Use when | Watch out |
|---|
Uint8Array | Same bytes. | You already own exact bytes. | The target must know the byte format. |
string | UTF-8 text bytes. | The target expects text. | This is not JSON unless the string itself is JSON text. |
| object or array | JSON.stringify(value) as UTF-8 bytes. | The target expects JSON. | Functions, symbols, and unsupported JSON values do not become useful data. |
| number or boolean | JSON.stringify(value) as UTF-8 bytes. | The target expects a JSON scalar. | The target still receives bytes, not a JavaScript value. |
null or omitted | Empty bytes. | The target needs no payload. | If the target needs JSON null, wrap it, for example { value: null }. |
Reply type
type BitfieldTargetReply = {
readonly payload: Uint8Array;
};
| Field | Type | Meaning | Decode rule |
|---|
payload | Uint8Array | Opaque reply bytes from the target. | Decode according to the action reply shape, not according to Runtime Kit guesses. |
Cancellation
Pass an AbortSignal as the second argument when the request is tied to a UI lifetime or a changing user input.const controller = new AbortController();
const replyPromise = sendRequestToBitfieldTarget(
{
target: 'help.search',
payload: { query: 'activate device' },
},
controller.signal,
);
controller.abort();
Runtime Kit passes the signal to the target transport. App code should still render a recoverable state because the user action may already have left the screen.Complete valid example
import { sendRequestToBitfieldTarget } from '@bitfield/runtime-kit';
type SearchReply = {
results: { title: string; url: string }[];
};
export async function searchHelp(query: string): Promise<SearchReply> {
const reply = await sendRequestToBitfieldTarget({
target: 'help.search',
payload: { query },
});
return JSON.parse(new TextDecoder().decode(reply.payload)) as SearchReply;
}
This is valid because the app calls the public action name, sends a target-owned JSON payload, and decodes the reply according to the target’s documented contract.Invalid example
import { runSearchDirectly } from '../slots/help-search';
export async function searchHelp(query: string) {
return runSearchDirectly({ query });
}
This is invalid because the app imports the target implementation. The public files and names is the action name plus bytes. Direct implementation imports make the app depend on how the target is built.Error categories
| Symptom | Public category | What app code should do |
|---|
sendRequestToBitfieldTarget(...) requires a non-empty target | Bad request shape | Fix the caller. This is not a retry problem. |
| Runtime Kit says it is not booted or not connected | App surface is mounted without the Runtime Kit owner wiring | Show a setup/support state. Do not import setup machinery into app components. |
| Request fails after dispatch | Target or transport failure | Render failure state, keep the user action retryable, and log the action name plus safe payload shape. |
| Reply cannot be decoded | Caller and target disagree on reply shape | Fix the action reply shape or caller decoder together. |
useBitfieldData(...)
function useBitfieldData<T>(
selector?:
| string
| {
input?: string;
params?: Record<string, unknown>;
},
): {
data: T | null;
loading: boolean;
error: Error | null;
};
This hook reads named data for a React surface. A data name is a public name that Runtime Kit already resolved behind the surface. It is not a storage path.| Selector | Meaning | Example | Use when |
|---|
| omitted | Read the default data name for the current surface. | useBitfieldData<WelcomeCopy>() | The surface owns one main data input. |
| string | Read a named data name. | useBitfieldData<Checklist>('launch-checklist') | The surface has multiple named inputs. |
object with input | Read a named data name. | useBitfieldData({ input: 'welcome-copy' }) | You want object form for clarity or future params. |
object with input and params | Read a parameterized data name. | useBitfieldData({ input: 'help-results', params: { query } }) | Runtime Kit owns a data name that accepts local selection params. |
Return state
| Field | Type | Meaning | Render obligation | |
|---|
data | `T | null` | Current prepared value, or no ready value yet. | Render empty/loading state instead of assuming data exists. |
loading | boolean | Runtime Kit is preparing or waiting for the value. | Show a loading state that can coexist with stale or empty UI. | |
error | `Error | null` | The read failed. | Show a recoverable error state and keep the component mounted safely. |
Complete valid example
import { useBitfieldData } from '@bitfield/runtime-kit/react';
type WelcomeCopy = {
headline: string;
body: string;
};
export function WelcomePanel() {
const welcome = useBitfieldData<WelcomeCopy>('welcome-copy');
if (welcome.loading) return <p>Loading welcome copy...</p>;
if (welcome.error) return <p>Could not load welcome copy.</p>;
if (!welcome.data) return <p>No welcome copy yet.</p>;
return (
<section>
<h2>{welcome.data.headline}</h2>
<p>{welcome.data.body}</p>
</section>
);
}
This is valid because the component asks for a data name by name and renders every public state: loading, error, empty, and ready.Invalid example
import { readPackageRecord } from '@bitfield/runtime-kit/internal/records';
export function WelcomePanel() {
const welcome = readPackageRecord('package::launch-product::welcome-copy');
return <h2>{welcome.headline}</h2>;
}
This is invalid because React code imports private machinery and guesses a storage address. The surface should ask for the data name.Boundary summary
| Public app code may do | Public app code must not do |
|---|
Import sendRequestToBitfieldTarget from @bitfield/runtime-kit. | Import connection setup, transport, target implementation, package parser, or address helpers. |
Import useBitfieldData from @bitfield/runtime-kit/react. | Import read scopes, providers, selector factories, subscription lanes, or address readers. |
| Send action names and payload bytes/data. | Call target implementation files directly. |
| Read data names. | Build storage addresses or parse package files inside components. |
| Decode replies according to the action reply shape. | Assume Runtime Kit understands target-specific JSON fields. |
Related pages
| Need | Page |
|---|
| First end-to-end feature | Package to screen |
| Read-hook guide | Read data in React |
| Request guide | Send a request |
| Package fields | Package file |
| Complete recipes | Runtime Kit Cookbook |
| AI-agent guardrails | Build with AI agents |