Rust WASM Nodes
Rust is the recommended language for WASM nodes — it produces the smallest binaries and has the best WASM tooling. The Flow-Like SDK provides macros for zero-boilerplate node development.
Prerequisites
Section titled “Prerequisites”# Install Rust (if not already installed)curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Add WASM targetrustup target add wasm32-wasip1Quick Start with SDK
Section titled “Quick Start with SDK”Project Setup
Section titled “Project Setup”cargo new --lib my-wasm-nodescd my-wasm-nodesUpdate Cargo.toml:
[package]name = "my-wasm-nodes"version = "0.1.0"edition = "2024"
[lib]crate-type = ["cdylib"]
[dependencies]flow-like-wasm-sdk = { git = "https://github.com/TM9657/flow-like", branch = "dev" }serde_json = "1"
[profile.release]opt-level = "s"lto = truestrip = trueSingle Node Example
Section titled “Single Node Example”use flow_like_wasm_sdk::*;
// Define the node using the macronode! { name: "uppercase", friendly_name: "Uppercase", description: "Converts text to uppercase", category: "Custom/Text",
inputs: { exec: Exec, text: String = "", },
outputs: { exec_out: Exec, result: String, },}
// Implement the run logicrun_node!(handle_run);
fn handle_run(mut ctx: Context) -> ExecutionResult { let text = ctx.get_string("text").unwrap_or_default(); ctx.set_output("result", text.to_uppercase()); ctx.success()}Multi-Node Package
Section titled “Multi-Node Package”For packages with multiple related nodes:
use flow_like_wasm_sdk::*;
package! { nodes: [ { name: "add", friendly_name: "Add", description: "Adds two numbers", category: "Custom/Math", inputs: { exec: Exec, a: I64 = 0, b: I64 = 0 }, outputs: { exec_out: Exec, result: I64 }, }, { name: "subtract", friendly_name: "Subtract", description: "Subtracts two numbers", category: "Custom/Math", inputs: { exec: Exec, a: I64 = 0, b: I64 = 0 }, outputs: { exec_out: Exec, result: I64 }, }, { name: "multiply", friendly_name: "Multiply", description: "Multiplies two numbers", category: "Custom/Math", inputs: { exec: Exec, a: I64 = 0, b: I64 = 0 }, outputs: { exec_out: Exec, result: I64 }, } ]}
// Each node needs a run function named run_{node_name}#[no_mangle]pub extern "C" fn run_add(ptr: i32, len: i32) -> i64 { run_with_handler(ptr, len, |mut ctx| { let a = ctx.get_i64("a").unwrap_or(0); let b = ctx.get_i64("b").unwrap_or(0); ctx.set_output("result", a + b); ctx.success() })}
#[no_mangle]pub extern "C" fn run_subtract(ptr: i32, len: i32) -> i64 { run_with_handler(ptr, len, |mut ctx| { let a = ctx.get_i64("a").unwrap_or(0); let b = ctx.get_i64("b").unwrap_or(0); ctx.set_output("result", a - b); ctx.success() })}
#[no_mangle]pub extern "C" fn run_multiply(ptr: i32, len: i32) -> i64 { run_with_handler(ptr, len, |mut ctx| { let a = ctx.get_i64("a").unwrap_or(0); let b = ctx.get_i64("b").unwrap_or(0); ctx.set_output("result", a * b); ctx.success() })}Package Manifest
Section titled “Package Manifest”Create manifest.toml alongside your code:
manifest_version = 1id = "com.example.math-utils"name = "Math Utilities"version = "1.0.0"description = "Common math operations"
[[authors]]name = "Your Name"
[permissions]memory = "minimal"timeout = "quick"
[[nodes]]id = "add"name = "Add"description = "Adds two numbers"category = "Custom/Math"
[[nodes]]id = "subtract"name = "Subtract"description = "Subtracts two numbers"category = "Custom/Math"
[[nodes]]id = "multiply"name = "Multiply"description = "Multiplies two numbers"category = "Custom/Math"SDK API Reference
Section titled “SDK API Reference”Context Methods
Section titled “Context Methods”// Get input valuesctx.get_string("pin_name") -> Option<String>ctx.get_i64("pin_name") -> Option<i64>ctx.get_f64("pin_name") -> Option<f64>ctx.get_bool("pin_name") -> Option<bool>ctx.get_json("pin_name") -> Option<serde_json::Value>ctx.get_bytes("pin_name") -> Option<Vec<u8>>
// Set output valuesctx.set_output("pin_name", value)
// Execution controlctx.success() -> ExecutionResultctx.error(message) -> ExecutionResultLogging
Section titled “Logging”use flow_like_wasm_sdk::log;
log::debug("Debug message");log::info("Info message");log::warn("Warning message");log::error("Error message");Variables
Section titled “Variables”use flow_like_wasm_sdk::var;
// Get/set execution variableslet value = var::get_variable("my_var");var::set_variable("my_var", json!({"key": "value"}));Streaming Output
Section titled “Streaming Output”use flow_like_wasm_sdk::stream;
// Stream progress updatesstream::stream_progress(50, "Processing...");
// Stream textstream::stream_text("Partial output...");
// Stream JSONstream::stream_json(json!({"status": "working"}));Pin Types
Section titled “Pin Types”| Type | Rust Type | Default |
|---|---|---|
Exec | () | - |
String | String | "" |
I64 | i64 | 0 |
F64 | f64 | 0.0 |
Bool | bool | false |
Json | serde_json::Value | null |
Bytes | Vec<u8> | [] |
cargo build --release --target wasm32-wasip1Output: target/wasm32-wasip1/release/my_wasm_nodes.wasm
Optimize (Optional)
Section titled “Optimize (Optional)”Install wasm-opt for smaller binaries:
# macOSbrew install binaryen
# Linuxapt install binaryen
# Optimize (can reduce size by 20-40%)wasm-opt -Os -o optimized.wasm target/wasm32-wasip1/release/my_wasm_nodes.wasmInstall & Test
Section titled “Install & Test”Local Testing
Section titled “Local Testing”# Copy to Flow-Like nodes directorycp target/wasm32-wasip1/release/my_wasm_nodes.wasm ~/.flow-like/nodes/cp manifest.toml ~/.flow-like/nodes/my_wasm_nodes.tomlPublishing
Section titled “Publishing”# Publish to registry (requires API key)flow-like publish ./target/wasm32-wasip1/release/my_wasm_nodes.wasmAdvanced: HTTP Requests
Section titled “Advanced: HTTP Requests”For nodes that need network access, declare it in the manifest:
[permissions.network]http_enabled = trueallowed_hosts = ["api.example.com"]Then use the host functions:
use flow_like_wasm_sdk::http;
fn handle_run(mut ctx: Context) -> ExecutionResult { let response = http::get("https://api.example.com/data")?; ctx.set_output("result", response); ctx.success()}Advanced: OAuth Access
Section titled “Advanced: OAuth Access”For nodes requiring OAuth:
[[permissions.oauth_scopes]]provider = "google"scopes = ["https://www.googleapis.com/auth/drive.readonly"]reason = "Access Google Drive files"required = true
[[nodes]]id = "list_files"oauth_providers = ["google"]use flow_like_wasm_sdk::auth;
fn handle_run(mut ctx: Context) -> ExecutionResult { let token = auth::get_oauth_access_token("google")?; // Use token for API calls... ctx.success()}Related
Section titled “Related”→ Package Manifest — Full manifest reference → WASM Nodes Overview → Writing Native Rust Nodes