Cargo.toml, Sifr reads the resolved package graph via cargo metadata and constructs its own Sifr package graph on top of it. This means the full power of Cargo’s ecosystem — version ranges, Git sources, path dependencies, private registries — is available to every Sifr project without Sifr having to reimplement a resolver.
Declaring dependencies
Add dependencies toCargo.toml exactly as you would in any Rust project. Runtime dependencies go in [dependencies]; dependencies used only for tests or development tooling go in [dev-dependencies].
Normal
sifr run, sifr check, sifr package, and sifr publish commands only expose runtime [dependencies] as import roots. Dev dependencies are available only in test contexts. Use sifr tree --edges dev if you want to inspect the dev dependency graph explicitly.Fetching dependencies with sifr fetch
After adding or changing a dependency, run sifr fetch to resolve and download it:
--locked to prevent the lockfile from being updated:
sifr fetch delegates to Cargo under the hood and forwards your lock and network flags automatically through the package session.
Inspecting the dependency tree with sifr tree
Visualize your full dependency graph with sifr tree:
--workspace if needed.
Lock modes
Sifr passes lock and network semantics directly to Cargo. Use these flags consistently across all package commands for reproducible results.
These flags apply uniformly across all Sifr commands that touch the package graph:
Pure Sifr packages
A pure Sifr package contains no non-trivial Rust code — all behavior is expressed in.sifr files. Because Cargo requires at least one build target, Sifr generates a minimal marker file at src/lib.rs:
src/lib.rs but does not declare Rust-backed behavior. Do not add Rust logic to lib.rs in a pure Sifr package.
Trust policy for Rust interop
Some Sifr packages expose Rust crates or local bridge modules through@rust(...) declarations. Sifr enforces trust policy for build scripts, proc macros, native links, unsafe local bridge files, no-panic assertions, and panic-abort opt-ins. This policy is configured in sifr.toml and validated by sifr bridge check, sifr check, sifr package, and sifr publish.
Packages that exceed their declared trust boundary are rejected with SIFR-RUST-TRUST-* diagnostics before the final Rust-backed package build is accepted.
See Rust Interop for direct bindings, local bridges, shared bridge crates, opaque handles, async, zero-copy, callbacks, and trust examples.
Python package requirements
Sifr does not resolve Python dependencies. Python packages are installed by the root application’s uv environment, and Sifr verifies the final interpreter/probe before compile or run. Dependency packages may declare:pyproject.toml,
uv.lock, .venv, and interpreter. The root application must authorize every
required import root, and separately authorize native-extension roots it is
willing to execute in process. Dependencies cannot select or authorize the
environment. See Embedded Python Interop.
Cross-package imports and public APIs
Only names that a dependency exposes through its public namespace are importable from outside that package. A package’s public API is defined bysrc/__init__.sifr and any child namespaces that have their own __init__.sifr. Implementation files such as src/client.sifr are private to the package unless explicitly re-exported.
Keeping Cargo.toml in sync with sifr repair
After manual edits to Cargo.toml or after a merge conflict, the Sifr-managed entries in Cargo.toml may drift from the expected state. Check for drift without making any changes:
Cargo.toml entries and restore a missing pure marker:
