Skip to main content

When a package ships files or bytes, keep them inside the package file. Consumer packages should receive named data or target replies, not random file paths into another package.

A help package ships markdown, a theme package ships images, and a file-preview package ships a small parser. A consumer wants the rendered result. The consumer should not read arbitrary files from the package folder.Package bytes should move with the package. Consumers should use public reads or requests, not private file paths that happen to work today.

Traditional app shape

const helpText = await fetch('/packages/help/content/getting-started.md');
or:
import helpText from '../help/content/getting-started.md?raw';
Now the consumer depends on the help package’s private file path. Rename the folder and consumers break.

Bitfield shape

help package file declares package-owned bytes
Runtime Kit admits the bytes with the package
consumer reads prepared help content or asks a help target
The package decides what bytes it brings. The consumer uses the public name exposed by the package file.

Boundary example

{
  "package": "help-package",
  "things": [
    {
      "type": "stored_bytes",
      "address": "package::help-package::bytes::getting-started",
      "file": "content/getting-started.md",
      "content_type": "text/markdown"
    }
  ]
}
The important part is not the exact content. The important part is the boundary: the package file reference stays inside the package.

Four file situations

Help markdown

Private help path

const help = await fetch('/packages/help/content/getting-started.md').then((r) => r.text());

Prepared help read

const help = readInput('getting-started-help');
The help package owns the file. The consumer reads prepared help content.

Preview HTML

Private preview bundle

import previewHtml from '../project-preview/dist/index.html?raw';

Prepared preview surface

const previewSurface = readInput('project-preview-surface');
The preview package decides how the surface is prepared. The shell receives a public view.

Review template

Private template import

import template from '../review-package/templates/review.md';

Prepared template read

const reviewTemplate = readInput('review-template');
The package can ship the template as package material. The caller should not read the package folder directly.

Search index

Private search index

import index from '../help/search-index.json';

Search through the package target

await sendRequestToBitfieldTarget({
  target: 'help.search',
  payload: { query },
});
The caller asks for search results. The help package can change its index format without breaking the caller.

Consumer rules

RuleMeaning
A consumer may read a public data name.It can use the handle the package exposes.
A consumer may send a public action request.It can ask the package to do work.
A consumer may not import package files directly.Folder structure is not public API.
A consumer may not copy bytes into app code.Package material should stay package material.
A consumer may not assume file format unless the package exposes that format.The public name is the data name or target reply.

What this prevents

Bad shapeWhy it breaksBetter shape
Consumer imports another package’s file.Folder structure becomes public API by accident.Consumer reads named data.
Consumer builds a local filesystem path.It only works on one machine/shell.Package declares package-owned bytes.
Package references files outside itself.The package cannot move cleanly.Keep package file references inside the package folder.
App code copies package bytes into itself.Data and code boundaries blur.Keep bytes in package material and expose a public read/target.
React is one adapter that might render the bytes, but React does not define the package file. A web shell, native shell, terminal shell, or future adapter should receive named data from the same package-owned material.

Review checklist

CheckGood answer
Does consumer code import another package file?No. It reads a data name or sends an action request.
Does the package reference material outside itself?No. Package material stays inside the package file.
Does the consumer assume the file format?Only when the public data name or reply shape says so.
Can the package move without breaking consumers?Yes. Consumers rely on public names, not folders.

Full before and after

Traditional feature request

“Add a help panel that shows package help and lets the user search it.”

Bad implementation

import help from '../help/content/getting-started.md?raw';
import searchIndex from '../help/search-index.json';

export function HelpPanel() {
  return renderHelp(help, searchIndex);
}
This consumer now depends on two package files and one package layout. If the help package changes how it stores content or search data, the consumer breaks.

Public package version

const help = readInput('getting-started-help');

const results = await sendRequestToBitfieldTarget({
  target: 'help.search',
  payload: { query },
});
The consumer gets content and search through public names. The package can keep markdown, JSON, a generated index, or something else behind that boundary.For React, Swift, Kotlin, terminal, or future adapters, the consumer rule stays the same: do not read package files directly.

Good consumer code

const help = readInput('getting-started-help');

React adapter example

const help = useBitfieldData<{ title: string; body: string }>('getting-started-help');
The consumer asks for help content by public input name. It does not import or parse the package file that produced it.

Review check

If consumer code imports ../some-package/content/file.md, stop. Package files are package material. Consumers should read a data name or request a target.

Next

Last modified on May 10, 2026