Skip to main content
This guide gets you from a fresh install to a working Stoffel project. You will create a project, inspect its structure, build Stoffel bytecode, and run the program through local MPC on your machine. Stoffel development loop from writing source through check, build, local MPC run, and Rust SDK integration.

Copy-paste path

Use this block when you want the fastest verified default app, or when you are asking an AI coding agent to do the setup for you:
Success means the CLI creates the project, stoffel check validates src/main.stfl, stoffel build writes .stflb bytecode under target/, the local MPC run completes, and the Rust wrapper builds and runs. If any command fails, keep its exact output and use the troubleshooting section before changing the app.

Create a Stoffel project

After installing the stoffel CLI, create and enter a new project:
The default template creates a Rust-backed Stoffel project:
There are four important files to start with:
  • src/main.stfl: the StoffelLang program that compiles to .stflb bytecode.
  • Stoffel.toml: package, build, and MPC topology settings such as parties and threshold.
  • src/main.rs: a Rust SDK wrapper that calls the same Stoffel program from Rust application code.
  • src/stoffel_bindings.rs: generated program metadata used by the Rust wrapper.

Check and build

Validate the Stoffel source and project configuration:
Expected output includes the checked source path and the functions found in the program:
Build bytecode under target/:
Expected output includes the generated .stflb file:
Inspect the generated bytecode before running local MPC:
This prints the functions, inferred register classes, and instructions in the compiled program. If your project name produces a different bytecode file name, use the .stflb file that stoffel build wrote under target/debug/.

Run local MPC during development

Run the generated example through local MPC:
Local MPC testing runs the compiled program by spawning several MPC nodes/processes locally on your machine. The default project uses five parties with threshold one unless you override those settings. For one-shot development runs, use stoffel dev --once:
For watch mode, remove --once:
stoffel dev watches Stoffel.toml and your source tree, rebuilds after changes, and reruns through local MPC.
Template programs can differ. Use the generated README.md and src/main.stfl to confirm whether the program expects named function inputs with --input or client share inputs with --client-input.

Run the Rust SDK wrapper

The default template also includes src/main.rs, a Rust application wrapper around the Stoffel program. It lets you call the same src/main.stfl program from Rust code instead of only from the CLI. The generated wrapper currently:
  • imports stoffel::prelude::*;
  • loads src/stoffel_bindings.rs with mod stoffel_bindings;;
  • creates an async tokio main function;
  • references stoffel_bindings::ProgramManifest, the generated manifest for the compiled program shape;
  • compiles src/main.stfl with Stoffel::compile_file("src/main.stfl")?;
  • applies the local MPC topology with .parties(5) and .threshold(1);
  • runs the program with .execute_local().await?, which is for local testing where several MPC nodes are spawned locally on your machine;
  • prints the first returned value.
Build and run the wrapper with Cargo:
If you change the program’s ClientStore input or output shape, regenerate or update the generated bindings before relying on the Rust wrapper.

Edit the program

Open src/main.stfl and make a small change. Then rerun the fast check/build loop:
When the program uses client-provided shares, pass local client inputs by slot:
Use named inputs for programs that define ordinary function arguments:

What the quick start covers

The core Stoffel development loop is:
  1. Write the MPC program in src/main.stfl.
  2. Run stoffel check for fast validation.
  3. Run stoffel build to produce .stflb bytecode.
  4. Run stoffel run or stoffel dev for local MPC development.
  5. Use the Rust SDK wrapper when integrating the program into an application.
In local MPC execution:
  • private values are modeled as shares;
  • the program computes over shares instead of exposing raw inputs;
  • outputs are reconstructed only where the program opens or sends them;
  • several MPC nodes/processes run locally on your machine;
  • party and threshold settings come from Stoffel.toml, SDK builder calls, or command-line flags.
Use the fastest command that answers your current question:
GoalCommand
Validate source and settingsstoffel check
Build bytecodestoffel build
Inspect compiled bytecodestoffel compile --disassemble target/debug/hello-mpc.stflb
Run once through local MPCstoffel dev --once
Iterate on an MPC programstoffel dev
Build the Rust app wrappercargo build
Run the Rust app wrappercargo run

Use with AI coding agents

If you want an AI coding agent to help build a Stoffel app, give it the Stoffel skills and live docs access before asking it to write code. See Installation for the copy-paste setup prompt, skills setup, and docs MCP setup. Choose the skill based on the task:
User taskStart with
Create the first app and prove the toolchain worksStoffel App Getting Started
Build a custom private-computation appStoffel Full App Golden Path
Write or modify .stfl sourceStoffel-Lang App Programming
Use ClientStore, secret shares, or client outputsStoffel Secret MPC Programming
Integrate with Rust application codeStoffel Rust App SDK
Run local MPC loops or debug local executionStoffel Local MPC Dev Loop
Prepare network or deployment handoffStoffel Deployment Runbook
When reviewing agent work, ask for the exact command output from stoffel check, stoffel build, a local MPC run, and any Rust build/test command the agent changed. Do not accept a code-only answer for a runnable app task.

Troubleshooting

The program asks for inputs

Check the generated README.md and src/main.stfl:
  • Use --input NAME=VALUE for ordinary named function inputs.
  • Use --client-input SLOT=VALUE for programs that call ClientStore.take_share.

I want the exact flags for my CLI version

Use command-specific help:

Next steps