Skip to content

Add an example of a plugin using WASI#3

Merged
edolstra merged 2 commits intomainfrom
wasi
Feb 26, 2026
Merged

Add an example of a plugin using WASI#3
edolstra merged 2 commits intomainfrom
wasi

Conversation

@edolstra
Copy link
Collaborator

@edolstra edolstra commented Feb 20, 2026

This shows how to build a Nix Wasm function using WASI, i.e. compiled with system type wasm32-wasip1 instead of wasm32-unknown-unknown.

It depends on DeterminateSystems/nix-src#359.

Example usage:

# nix build ./wasi
# nix eval --impure --expr 'builtins.wasi "/path/to/result/bin/nix-wasi-plugin-fib.wasm" 33'
Greetings from WASI!
Environment size: 0
Date: 1771602666
Current directory: /
Number of files in /: 0
warning: '/nix/store/1j1z8symyqf4iy4a8jpcw5mkiy5v8pw2-rust-workspace-0.0.1/bin/nix-wasi-plugin-fib.wasm': greetings from Wasm!
5702887

Summary by CodeRabbit

  • New Features

    • Added Nix WebAssembly plugin project with WASI support and multi-system build environment.
    • Expanded Value API with new construction and return methods for improved interoperability.
  • Chores

    • Updated CI workflow to run additional Nix flake checks for WASI.
    • Configured workspace and WASI plugin build settings with optimization flags.
    • Added build artifact exclusions to version control.

Flake lock file updates:

• Updated input 'nix':
    'github:DeterminateSystems/nix-src/370987f' (2026-01-23)
  → 'github:DeterminateSystems/nix-src/c9f71f3' (2026-02-06)
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

Introduces WASI plugin infrastructure for nix-wasm-rust by adding a wasi workspace with multi-system Nix flake, a nix-wasi-plugin-fib binary that invokes fib and returns results to the Nix host, extending the Value API with from_id and return_to_nix methods, updating CI to validate the wasi flake, and adding build configuration entries.

Changes

Cohort / File(s) Summary
CI and Build Configuration
.github/workflows/ci.yml, .gitignore
Added wasi flake validation to CI pipeline; added /wasi/target/ to ignored paths.
Rust API Extensions
nix-wasm-rust/src/lib.rs
Added two public Value methods: from_id(id: ValueId) constructor and return_to_nix() that invokes a C FFI function with non-returning control flow.
Cargo Manifest Updates
nix-wasm-plugin-fib/Cargo.toml
Expanded crate-type from ["cdylib"] to ["lib", "cdylib"] to enable both standard library and cdylib build outputs.
WASI Workspace Infrastructure
wasi/Cargo.toml, wasi/flake.nix, wasi/nix-wasi-plugin-fib/Cargo.toml, wasi/nix-wasi-plugin-fib/src/main.rs
Introduces complete wasi workspace with Nix flake for multi-system (aarch64-darwin, x86_64-linux) builds, Rust toolchain setup with wasm32-wasip1 target, wasm-opt post-processing, development shells, and a binary entrypoint that reads argv as ValueId, converts to Value, computes fib result, and returns to host.

Sequence Diagram

sequenceDiagram
    actor Nix Host
    participant nix-wasi-plugin-fib Binary
    participant nix-wasm-plugin-fib Crate
    participant Value API

    Nix Host->>nix-wasi-plugin-fib Binary: Invoke with ValueId argument
    nix-wasi-plugin-fib Binary->>nix-wasi-plugin-fib Binary: Parse argv[1] to ValueId
    nix-wasi-plugin-fib Binary->>Value API: Value::from_id(id)
    Value API-->>nix-wasi-plugin-fib Binary: Return Value
    nix-wasi-plugin-fib Binary->>nix-wasm-plugin-fib Crate: fib(value)
    nix-wasm-plugin-fib Crate-->>nix-wasi-plugin-fib Binary: Return result
    nix-wasi-plugin-fib Binary->>Value API: result.return_to_nix()
    Value API->>Nix Host: return_to_nix(value_id) [never returns]
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • cole-h

Poem

🐰 A WASI tunnel, dug deep and true,
Where Values hop through and fib compute,
The rabbit built bridges 'cross systems grand,
From Linux to Darwin, hand in hand,
Now plugins return with results so neat—
Nix and WebAssembly, a fuzzy feat! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: adding a WASI plugin example across multiple new files and configurations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wasi

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
wasi/flake.nix (2)

75-82: Consider sourcing dev tools from the fenix toolchain for consistency.

The devShell references rust-analyzer, rustfmt, and clippy from pkgs, but the build uses a custom toolchain from fenix. This could lead to version mismatches between the tools used during development and the actual build toolchain.

♻️ Proposed fix to use fenix toolchain components
       devShells = forAllSystems ({ pkgs, system }: rec {
-        default = with pkgs; self.packages.${system}.default.overrideAttrs (attrs: {
+        default = self.packages.${system}.default.overrideAttrs (attrs: {
           nativeBuildInputs = attrs.nativeBuildInputs ++ [
-            rust-analyzer
-            rustfmt
-            clippy
+            inputs.fenix.packages.${system}.latest.rust-analyzer
+            inputs.fenix.packages.${system}.latest.rustfmt
+            inputs.fenix.packages.${system}.latest.clippy
           ];
         });
       });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wasi/flake.nix` around lines 75 - 82, The devShells block adds rust-analyzer,
rustfmt, and clippy from pkgs which can mismatch the fenix toolchain; update the
devShells (forAllSystems / default / nativeBuildInputs override) to source these
tools from the fenix toolchain instead of pkgs (e.g., use the fenix package set
or toolchain attribute you already instantiate) so rust-analyzer, rustfmt, and
clippy come from the same fenix toolchain used for builds.

26-26: supportedSystems excludes aarch64-linux and x86_64-darwin.

The current list only includes aarch64-darwin and x86_64-linux. If this is intentional (e.g., due to toolchain or runtime limitations), consider adding a comment explaining why. Otherwise, expanding coverage would improve cross-platform support.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wasi/flake.nix` at line 26, supportedSystems currently lists only
"aarch64-darwin" and "x86_64-linux", excluding "aarch64-linux" and
"x86_64-darwin"; either add the missing system identifiers to the
supportedSystems array in wasi/flake.nix (include "aarch64-linux" and
"x86_64-darwin") to broaden platform support, or if their exclusion is
intentional, add a brief inline comment next to the supportedSystems declaration
explaining why those platforms are omitted (e.g., toolchain/runtime limitations
or untested targets) so reviewers understand the rationale.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@wasi/nix-wasi-plugin-fib/src/main.rs`:
- Around line 25-30: The code currently indexes args[1] which panics if no CLI
argument is provided; change the logic that builds the Value from argv to safely
access the second argument (use env::args().collect() then args.get(1)) and
return or panic with a descriptive message if it's missing, then parse that &str
to u32 as before and pass into Value::from_id; update the logic around
parse::<u32>() to propagate or format parse errors with a clear message
mentioning the expected ValueId/argument.

---

Nitpick comments:
In `@wasi/flake.nix`:
- Around line 75-82: The devShells block adds rust-analyzer, rustfmt, and clippy
from pkgs which can mismatch the fenix toolchain; update the devShells
(forAllSystems / default / nativeBuildInputs override) to source these tools
from the fenix toolchain instead of pkgs (e.g., use the fenix package set or
toolchain attribute you already instantiate) so rust-analyzer, rustfmt, and
clippy come from the same fenix toolchain used for builds.
- Line 26: supportedSystems currently lists only "aarch64-darwin" and
"x86_64-linux", excluding "aarch64-linux" and "x86_64-darwin"; either add the
missing system identifiers to the supportedSystems array in wasi/flake.nix
(include "aarch64-linux" and "x86_64-darwin") to broaden platform support, or if
their exclusion is intentional, add a brief inline comment next to the
supportedSystems declaration explaining why those platforms are omitted (e.g.,
toolchain/runtime limitations or untested targets) so reviewers understand the
rationale.


inputs = {
nixpkgs.follows = "nix/nixpkgs";
flake-schemas.url = "https://flakehub.com/f/DeterminateSystems/flake-schemas/*.tar.gz";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we generally leave off the .tar.gz and opt for not using * in versions

@edolstra edolstra merged commit 84c2273 into main Feb 26, 2026
3 checks passed
@edolstra edolstra deleted the wasi branch February 26, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants