Skip to main content

Runtime Kit keeps product code from tangling by turning package material into two app-facing moves: read named data and call named targets.

Picture a founder shipping a launch screen. The screen needs headline copy, a checklist, a help panel, and a button that asks for the next step. Without Runtime Kit, the screen starts importing data files, helper functions, search code, and setup code. With Runtime Kit, those jobs stay separated.

The whole map

01

The package declares records, package-owned bytes, and callable targets.

02

Runtime Kit checks the package and turns source material into active local truth.

03

The app sees data names and action names, not package setup.

04

React reads data, sends requests, renders states, and stays out of setup machinery.

The technical contract is small:
ConceptPlain meaningPublic names
Package fileThe package says what it brings.things-to-store-and-run.json with record, stored_bytes, or slot things.
Named data readThe screen asks for data that Runtime Kit already prepared.useBitfieldData(inputName) returns { data, loading, error }.
Callable targetThe user asks a named target to do work.sendRequestToBitfieldTarget({ target, payload }, signal?) returns reply bytes.
Local stateThe device has active Bitfield material.Customer-visible areas under ~/.bitfield, not hand-edited app data.
Placeable surfaceA shell places UI by descriptor, not by product branches.Surface descriptor names region, component key, data names, and targets.

Package file

You want your welcome copy to ship with a package, not as a hardcoded React string.A package file is the file that says what the package owns. It can declare package-owned records, package-owned bytes, and callable targets.
{
  "package": "launch-product",
  "things": [
    {
      "type": "record",
      "address": "package::launch-product::welcome-copy",
      "payload": {
        "headline": "Your launch stays fast."
      }
    }
  ]
}

Anti-pattern

const copy = await fetch('/packages/launch-product/things-to-store-and-run.json');
That breaks the shape because the app is parsing package source instead of reading named data. The package file is for Runtime Kit admission. It is not a UI data API.

Named data reads

The launch screen wants welcome-copy, but it should not care which package record, file, or derived value produced it.A named data read is a named app-facing value. The component asks for the name and renders the public states.
const welcome = useBitfieldData<WelcomeCopy>('welcome-copy');

if (welcome.loading) return <p>Loading...</p>;
if (welcome.error) return <p>Could not load welcome copy.</p>;
if (!welcome.data) return <p>No welcome copy yet.</p>;

Anti-pattern

const welcome = readAddress('package::launch-product::welcome-copy');
That breaks the shape because the component guessed a storage address. The app should read the data name.

Callable targets

The user clicks “Suggest next step.” The app should call launch.next-step, not import the target implementation.A callable target is a stable public name for work. Runtime Kit sends bytes to that target and gives the app reply bytes.
const reply = await sendRequestToBitfieldTarget({
  target: 'launch.next-step',
  payload: { topic: 'activation' },
});

Anti-pattern

import { nextStep } from '../slots/next-step';
That breaks the shape because the button bypasses the target boundary. The target implementation can change only if the app keeps calling the public target name.

Local state ownership

One customer says the feature works on a laptop but not a phone. You need to know whether the device has the package, activation, and local Runtime Kit material, without telling the customer to edit files.Local state is customer-visible evidence, not a place for manual repair.
~/.bitfield
  account and activation material
  runtime-kit package-set material
  local stored data

Anti-pattern

Open ~/.bitfield and edit the package record by hand.
That breaks the shape because hand edits bypass admission, validation, and device/account rules. Inspect for support; repair through product/account/runtime flows.
NeedPage
GuideLocal state
TroubleshootingTroubleshooting
ReferencePackage file

Placeable surfaces

The product grows from one launch screen to launch, help, support, and settings. The shell should not grow a branch for every business area.A placeable surface descriptor says where a surface can appear and which data names or targets it may use.
{
  id: 'launch.help',
  label: 'Help',
  region: 'panel',
  componentKey: 'surface.launch.help',
  preparedInputs: [],
  targets: ['help.search'],
}

Anti-pattern

if (screen === 'help') return <HelpSearch />;
if (screen === 'support') return <SupportPanel />;
That breaks the shape because the shell imports package-specific UI rules. The shell should render descriptor labels, regions, and active surface ids.

One sentence version

Package declares -> Runtime Kit admits -> app reads data names or calls targets -> shell places surfaces by descriptor.
If a feature does not fit that sentence, stop and find which boundary it crossed.
Last modified on May 10, 2026