Use a slot when a package needs named callable code. App code calls the public action and stays out of how that target is built, stored, mounted, or replaced.
This recipe builds product.search, a package-owned target for a search box. The app sends a query. Runtime Kit sends bytes to the target. The target returns reply bytes. The app decodes those bytes according to the public reply shape.When to use this
Use a slot when the user action needs work, not just data display.| Good fit | Not this recipe |
|---|
| Search, summarize, rank, transform, validate, or generate. | Static copy that a component only reads. |
| A package-owned target that can change behind the same name. | A direct React helper imported into one component. |
| Work that should be called by a stable public action name. | A secret account operation that belongs in account infrastructure. |
A slot is package-owned callable code. The package file says the target name and the methods it accepts. The implementation stays inside the package.What you will build
| Contract part | Value |
|---|
| Package | search-package |
| Boundary file | search-package/things-to-store-and-run.json |
| Thing type | slot |
| Action name | product.search |
| Method | query |
| Call shape | envelope-bytes-in-envelope-bytes-out |
| Artifact | slots/search-slot.bin |
| App call | sendRequestToBitfieldTarget({ target: 'product.search', payload }) |
Folder shape
search-package/
things-to-store-and-run.json
slots/
search-slot.bin
The artifact is package-owned bytes. The app does not import this file. The app calls product.search.Boundary file
{
"package": "search-package",
"things": [
{
"type": "slot",
"name": "product.search",
"methods": [
{
"name": "query"
}
],
"boundary": {
"call_shape": "envelope-bytes-in-envelope-bytes-out",
"methods": [
{
"name": "query"
}
]
},
"artifact": {
"source_path": "slots/search-slot.bin"
}
}
]
}
The boundary declares two public ideas:| Field | Meaning |
|---|
name: "product.search" | The target app code calls. |
methods | The named operations the slot exposes. |
boundary.call_shape | The public byte-in/byte-out call contract. |
artifact.source_path | Package-local bytes for the callable target. |
App call
import { sendRequestToBitfieldTarget } from '@bitfield/runtime-kit';
const reply = await sendRequestToBitfieldTarget({
target: 'product.search',
payload: { query: 'blue jacket' },
});
The app owns the request contract:| Contract part | Shape |
|---|
| Target | product.search |
| Payload | { query: string } |
| Reply | Bytes decoded according to the package target’s public reply shape. |
| Error handling | Caller handles failed request or failed decode visibly. |
What should happen
The app asks product.search for work.
The app does not import slots/search-slot.bin.
The action name can stay stable while package-owned bytes change.
What stays stable
Your app keeps calling product.search. The package can change the bytes behind that target without making the React component import implementation code, read a package file, or understand how the slot runs.Verify the recipe
Use this checklist before wiring the target into a real screen:| Check | Pass condition |
|---|
| Boundary exists | search-package/things-to-store-and-run.json exists. |
| Artifact exists | search-package/slots/search-slot.bin exists. |
| Action name | The slot name is non-empty and stable. |
| Method list | methods includes query. |
| Boundary call shape | The boundary says bytes in, bytes out. |
| App import | App code imports sendRequestToBitfieldTarget(...), not the artifact. |
| Payload contract | The caller and target agree on request shape. |
| Reply shape | The caller decodes bytes only according to the promised reply shape. |
Common failures
| Symptom | Cause | Fix |
|---|
| Button throws before work starts. | The action name is empty or not declared. | Use the declared public action name. |
| Package admission fails. | The artifact path is missing or escapes the package. | Put the artifact under slots/ and update source_path. |
| App code imports the slot file. | The component bypassed Runtime Kit. | Replace the import with sendRequestToBitfieldTarget(...). |
| UI cannot parse the reply. | The target returned bytes with a different meaning. | Document and honor the reply shape. |
| Search returns stale results. | Old request finishes after newer input. | Use cancellation when stale work matters. |
Extend it
After this works, you can add:
- A React search surface that calls
product.search from a button or form.
- A
stored_bytes file with package-owned search data.
- A record that gives the surface initial search copy.
- A second method when the same target needs another public operation.
Do not add a second direct app-to-implementation path. Keep the action name as the public target.The public target name and call shape are safe to document. The private implementation, storage layout, and runtime setup stay out of public docs.
Next
Read Send a request for payload conversion, reply bytes, cancellation, and request errors.Read Runtime Kit API for the public function contract.Read Package file for exact slot field rules, method-list rules, artifact path rules, and invalid examples.