Targets: interpreter, native, web
You can run a program in the interpreter, build it to a native executable, or build it to a WebAssembly package. After this page you can pick one and fix the usual failures.
One checked meaning feeds every target. A safe program behaves the same on each backend that admits the features it uses.
Run it
semaprax check examples/meaning.spx
semaprax run examples/meaning.spx # interpreter, prints 42
semaprax run examples/meaning.spx --native # generated C11, needs Clang
semaprax run . # a project: runs its entry
The interpreter is bounded: --max-steps N limits work, --max-bytes N limits
the output envelope, and call depth stops at 256 frames. --json gives a
machine-readable result. A single file needs a fn main() -> i64
(SPX-T105 otherwise). If the interpreter refuses a program (SPX-F102), try
--native.
Build it
semaprax build examples/meaning.spx --target native -o meaning-native
semaprax build . --target web -o dist/web
| Input | --target | You get |
|---|---|---|
| File | native (default) | Executable file. Needs Clang. |
| File | native-callable | Bundle for a function with a direct own resource parameter (SPX-B105 otherwise). Add --function <id>. |
| File | web, wasm | Package directory with app.wasm. --export <id> picks exported functions. |
| Project | web (default), wasm | Package directory: app.wasm, index.html, package.json, semaprax.js, bindings and a boundary description. wasm is an alias for web. |
| Project | native | Native executable of the project. Needs Clang. |
| Project | npm | Owned-data npm package. Needs a profile that admits it (SPX-W120 for the scalar profile). |
| Project | oci | Offline OCI Image Layout (oci-layout, index.json, blobs/). Scalar and Useful Data profiles only. Not signed, not pushed anywhere. |
| Project | rust | Generated Rust SDK. Only in the full toolchain built from source. Read semaprax help build first. |
Rules that save time:
-oand--outputare the same. The path must be new: an existing one fails withSPX-I307, a bad parent withSPX-I301.--jsonreportsstatus,target,productandoutput.[targets] matrixin the manifest can forbid a target (SPX-J122).web,wasmandnpmneedwasm32; the rest neednative64.- Run
semaprax help buildfor the exact list on your binary.
Strings in a standalone web module
A source file that passes string values between its own functions needs the
internal String profile. Name each exported function:
semaprax build app.spx --target web --profile internal-strings-v1 \
--export app.length -o app-web
It needs a source file, --target web or wasm, and 1 to 32 --export ids.
A project, another target or a missing export is a usage error (exit 2).
Strings never cross the exported boundary. Spec:
Standalone internal String Web package v1.
Check a web package
semaprax test examples/calculator-project
semaprax build examples/calculator-project --target web -o dist/calculator-web
node scripts/verify-wasm-scalar-exports.mjs dist/calculator-web # source checkout
semaprax.scalar-exports.json lists the exported functions. A build only
writes files. Serving them and loading the module is your app’s job; follow the
calculator browser consumer.
Edit and re-run (hot reload)
semaprax dev semaprax.toml --human
dev keeps one checked interpreter session open. It starts only after you send
a start frame on stdin, then reads one JSON control frame per line
(semaprax.hot-reload-control.v1). Operations are start, status, plan,
activate, invoke and stop. Saving a file never runs code; invoke does.
A broken revision is rejected and the previous one stays usable.
What must stay compatible before a swap
activate replaces the code only if everything reachable from the entry and
test roots still agrees with the running revision:
- entry points and the permit set;
- type and interface records;
- the set of reachable functions, with the same parameter and return types and ownership;
- declared effects;
- pre- and postconditions, and the cleanup and loan plans.
Otherwise the swap is refused (incompatible_closure, policy_changed,
identical_revision or unsupported_target) and the old revision keeps
running. Functions no entry or test reaches are not compared.
plan only reports what activate would do. Its output says
authority: none, and activate rebuilds the plan itself, so a plan you saved
cannot be replayed. If a worker panics or an acknowledgement is lost, the
session enters terminal_uncertainty: the status shows the flag (a JSONL
boolean, or a line in --human), every later operation is refused, and nothing
is retried or rolled back. Start a new session.
Frame limits: 64 frames per session, 4 KiB per input frame, 8 KiB per response.
printf '%s\n' \
'{"schema":"semaprax.hot-reload-control.v1","id":1,"op":"start"}' \
'{"schema":"semaprax.hot-reload-control.v1","id":2,"op":"invoke"}' \
'{"schema":"semaprax.hot-reload-control.v1","id":3,"op":"stop"}' |
semaprax dev semaprax.toml --human
Use --jsonl for tools. The VS Code extension drives this for you
(editor setup). Native and Wasm swapping are
not supported; --source-agent is refused by the public binary.
Specs: Hot Reload Watcher v1,
Hot Reload Session v1.
Check the environment
semaprax doctor # versions and OS
semaprax doctor --profile <id> # probe tools through an admitted offline profile
semaprax doctor --target native|web|all --json
doctor never discovers tools on PATH. Without --profile it reports
failed profile: an explicit offline profile is required and lists tools
(clang, node, rust) as not probed. That is expected. If a native build
fails with SPX-B101 failed to start clang, install Clang and put it on PATH.
Richer data, commands, resources
These use the execution route of their profile. A web scalar
package and an owned-data npm package are different interfaces, even though
both are WebAssembly.
Next: Integrate with another language, or prepare the package for review. References: Interpreter v1, Wasm Scalar Exports v1, OCI Deployable Artifact v1, Native Callable ABI v3.