Skip to content

Custom WASM Nodes

Flow-Like supports custom nodes written in any language that compiles to WebAssembly. This allows you to extend Flow-Like with your own logic without modifying the core Rust codebase.

BenefitDescription
Language FreedomWrite nodes in Rust, Go, TypeScript, Python, C++, or any WASM-compatible language
Sandboxed ExecutionWASM runs in a secure sandbox with controlled memory and capabilities
PortableSame WASM module works on desktop, server, and browser
PerformanceNear-native execution speed
Hot ReloadLoad new nodes without restarting Flow-Like
Package RegistryShare and discover community nodes
┌─────────────────────────────────────────────────────────────┐
│ Flow-Like Runtime │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Native Node │ │ Native Node │ │ WASM Node │ │
│ │ (Rust) │ │ (Rust) │ │ (Any Lang) │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ WASM Runtime │ │
│ │ (Wasmtime) │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

WASM nodes are distributed as packages that can contain one or more nodes:

TypeUse Case
Single NodeSimple, focused functionality
Multi-Node PackageRelated nodes that share code (e.g., math operators)

Every package requires a manifest.toml that declares:

  • Package metadata (name, version, author)
  • Permission requirements
  • OAuth scope requirements
  • Node definitions
manifest.toml
manifest_version = 1
id = "com.example.math-utils"
name = "Math Utilities"
version = "1.0.0"
description = "Common math operations"
[permissions]
memory = "standard" # 64 MB
timeout = "standard" # 30 seconds
variables = true
cache = true
[[nodes]]
id = "add"
name = "Add Numbers"
description = "Adds two numbers"
category = "Math/Arithmetic"

See Package Manifest for full documentation.

## Permission System
Packages must declare their required permissions upfront. Users can review these before installing.
### Memory Tiers
| Tier | Memory | Use Case |
|------|--------|----------|
| `minimal` | 16 MB | Simple string processing |
| `light` | 32 MB | Basic data manipulation |
| `standard` | 64 MB | Most nodes (default) |
| `heavy` | 128 MB | Data processing |
| `intensive` | 256 MB | ML inference, large datasets |
### Timeout Tiers
| Tier | Duration | Use Case |
|------|----------|----------|
| `quick` | 5 seconds | Fast operations |
| `standard` | 30 seconds | Most nodes (default) |
| `extended` | 60 seconds | API calls |
| `long_running` | 5 minutes | ML inference |
### OAuth Scopes
Packages can request OAuth access per-provider. Each node declares which providers it needs:
```toml
[[permissions.oauth_scopes]]
provider = "google"
scopes = ["https://www.googleapis.com/auth/drive.readonly"]
reason = "Read files from Google Drive"
required = true
[[nodes]]
id = "list_drive_files"
name = "List Drive Files"
oauth_providers = ["google"] # Only this node gets Google access

WASM nodes can use these pin data types:

TypeDescriptionJSON Representation
ExecutionFlow control triggernull
StringText value"hello"
Integer64-bit signed integer42
Float64-bit floating point3.14
BooleanTrue/falsetrue
DateISO 8601 timestamp"2025-01-01T00:00:00Z"
PathBufStorage path"uploads/file.txt"
StructJSON object{"key": "value"}
ByteRaw bytes (base64)"SGVsbG8gV29ybGQ="
GenericAny type (dynamic)varies

Pins can hold single values or collections:

ValueTypeDescription
NormalSingle value
ArrayOrdered list [...]
HashMapKey-value map {...}
HashSetUnique values set

Set quality metrics (0-10 scale) to help users understand node trade-offs:

ScoreMeaning
privacyData protection level (10 = very private)
securityAttack resistance (10 = very secure)
performanceExecution speed (10 = very slow, expensive)
governanceCompliance level (10 = highly auditable)
reliabilityStability (10 = may fail often)
costResource usage (10 = expensive)

Choose your preferred language to get started:

LanguageStatusTemplate
Rust✅ RecommendedFull support, smallest binaries
Go✅ SupportedTinyGo for smaller binaries
TypeScript✅ SupportedAssemblyScript or Javy
Python🔜 PlannedVia Pyodide or similar
C/C++✅ SupportedEmscripten or wasi-sdk

Packages can be installed from multiple sources:

  1. Registry — Browse and install from the Flow-Like registry
  2. Local file — Load .wasm files from disk
  3. URL — Install from a direct download URL
Terminal window
# From registry (coming soon)
flow-like install com.example.math-utils
# From local file
flow-like install ./my-package.wasm

Installed packages are cached locally, enabling:

  • Full offline functionality
  • Fast startup without network
  • Automatic background updates when online

Share your packages with the community:

Terminal window
# Build your package
cargo build --release --target wasm32-wasip1
# Publish to registry (requires API key)
flow-like publish ./target/wasm32-wasip1/release/my_package.wasm

See the Package Registry documentation for details on the publishing process and governance.

WASM nodes run in a sandboxed environment with:

  • Declared permissions only — Packages can only use permissions they declare
  • Per-node OAuth — Nodes only get OAuth tokens they specifically request
  • Memory limits — Enforced per the declared memory tier
  • Execution timeout — Prevents infinite loops
  • No arbitrary filesystem — Must use Flow-Like’s storage API
  • No arbitrary network — Must use Flow-Like’s HTTP capabilities

Package Manifest — Full manifest reference → Package Registry — Publishing and governance