A 5-minute guide to writing your first Capa program.
You need either a Python 3.10+ install or one of the pre-built binaries. Pick one of the three paths:
Download capa-linux-x86_64, capa-macos-arm64, or
capa-windows-x86_64.exe from the latest
release
and put it on your PATH. The binary bundles Python and the
runtime; nothing else to install. After that, capa <args>
works from any directory.
Clone the repository, then from the project root:
pip install -e .This puts a capa command on your PATH and registers the
package with the Python import system, so both capa <args>
and python -m capa <args> work from any directory.
You can also run python -m capa <args> directly, but only
while your current directory is the repository root. Python
resolves capa by walking the cwd-relative capa/ folder.
From any other directory you get No module named capa. Use
Path 1 or Path 2 if you want to scaffold projects on your
Desktop, in ~/code/, etc.
The examples below assume capa is on your PATH (Path 1 or
Path 2). Substitute python -m capa if you went with Path 3
and are running them from the repo root.
From the project root:
capa --run examples/hello.capaExpected output: Hello, world!
The fastest way to get a working starter:
capa init my-project
cd my-project
capa --run main.capacapa init creates four files: main.capa (a runnable starter
that uses Stdio, so the capability discipline shows up on
line one), README.md, .gitignore, and .capa-version.
Create my_first.capa:
fun main(stdio: Stdio)
stdio.println("Hello!")
let xs = [1, 2, 3, 4, 5]
let total = xs.fold(0, fun (a: Int, x: Int) -> Int => a + x)
stdio.println("total = ${total}")
Run it:
capa --run my_first.capaFor a progressive 10-chapter introduction to the language, open
docs/tutorial.md.
Prefer an interactive session?
capa replstarts a REPL with incremental state and readline history;.capafiles remain the primary execution mode.
| Command | What it does |
|---|---|
capa init [name] |
Scaffold a new project (subcommand). |
capa --run file.capa |
Compile and execute. |
capa --check file.capa |
Type-check only (do not run). |
capa --transpile file.capa |
Print the generated Python code. |
| `capa --ir [--run | --transpile] file.capa` |
capa --wasm --run file.capa |
Compile via CIR -> WAT -> binary .wasm and execute on wasmtime with a Python host bridge. Requires wasm-tools and wasmtime on PATH. The Wasm backend has full generics and trait parity with the Python reference; the main remaining limits are a few stdlib surface gaps and a loud error if a trait is used as a Map key / Set element. See examples/wasm/. |
capa --wasm --transpile file.capa |
Print the WAT (WebAssembly text format) the Wasm backend would compile. |
capa --wasm -o X.wasm file.capa |
Save the assembled core module to X.wasm. Add --component to wrap it in a Component Model component (via wasm-tools component new). |
capa --wit file.capa |
Emit the WIT spec describing the program's capability imports. Useful for inspecting what a Wasm component would request from its host. |
capa --parse file.capa |
Print the AST (for debugging). |
capa --fmt file.capa |
Rewrite the file in canonical Capa style (line-level). |
capa --fmt-check file.capa |
Verify canonical style without rewriting. |
capa --doc file.capa |
Emit a self-contained HTML doc page from /// and /** */ doc comments. |
capa --manifest file.capa |
Emit a JSON capability manifest. |
capa --cyclonedx file.capa |
Emit a CycloneDX 1.5 SBOM with the manifest embedded. |
capa lsp |
Start the language server on stdio (requires pip install -e '.[lsp]'). |
--no-color |
Disable ANSI colors in the output. |
--stdin |
Read from stdin instead of a file. |
Every command above also works as python -m capa <args> if the
capa shim is not on your PATH.
fun main(stdio: Stdio)
// your code here
The stdio parameter is a capability, only functions that receive
it can perform I/O. Other available capabilities: fs (filesystem),
env (environment variables), clock (time), random (random
numbers).
fun classify(n: Int) -> String
return match n
0 -> "zero"
n if n > 0 -> "positive"
_ -> "negative"
fun main(stdio: Stdio)
let nums = [-3, 0, 7, -1, 42]
for n in nums
stdio.println("${n}: ${classify(n)}")
Output:
-3: negative
0: zero
7: positive
-1: negative
42: positive
docs/tutorial.md, guided 10-chapter tutorialdocs/reference.md, full language specificationdocs/stdlib.md, standard library referenceexamples/, 25 real programs to inspect (hello,tasks,grades,generics,closures,io,patterns,interactive,json,python_interop,documented_demo,demo_event_stream, the*_attenuationfiles for each capability, thestdlib_*files for each builtin API, and a few more)
| Symptom | Likely cause |
|---|---|
expected top-level declaration |
You forgot the surrounding fun main(stdio: Stdio) around your statements |
capability parameter not used |
You declared stdio: Stdio but didn't use it, prefix with _stdio or remove it |
expects Bool, got Int |
You wrote if 1 then ... instead of if x > 0 then ... |
non-exhaustive match |
A match on a sum type is missing cases, add _ -> ... |
Errors are reported with precise positions and explanatory messages.