{"id":49549109,"url":"https://github.com/scrogson/plasmoid","last_synced_at":"2026-05-02T21:04:17.017Z","repository":{"id":339894711,"uuid":"1163755595","full_name":"scrogson/plasmoid","owner":"scrogson","description":"A distributed WASM actor runtime on iroh mesh networking with WIT interfaces and Cedar authorization","archived":false,"fork":false,"pushed_at":"2026-02-22T05:09:49.000Z","size":232,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-29T21:01:09.795Z","etag":null,"topics":["actor-model","cedar","distributed-systems","iroh","mesh-networking","rust","wasm","webassembly","wit"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scrogson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-22T04:58:44.000Z","updated_at":"2026-02-22T05:12:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/scrogson/plasmoid","commit_stats":null,"previous_names":["scrogson/plasmoid"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/scrogson/plasmoid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scrogson%2Fplasmoid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scrogson%2Fplasmoid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scrogson%2Fplasmoid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scrogson%2Fplasmoid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scrogson","download_url":"https://codeload.github.com/scrogson/plasmoid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scrogson%2Fplasmoid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32549388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T19:18:06.202Z","status":"ssl_error","status_checked_at":"2026-05-02T19:16:21.335Z","response_time":132,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actor-model","cedar","distributed-systems","iroh","mesh-networking","rust","wasm","webassembly","wit"],"created_at":"2026-05-02T21:04:16.316Z","updated_at":"2026-05-02T21:04:17.011Z","avatar_url":"https://github.com/scrogson.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Plasmoid\n\nA distributed WASM actor runtime on [iroh](https://iroh.computer) mesh networking with [WIT](https://component-model.bytecodealliance.org/design/wit.html) interfaces and [Cedar](https://www.cedarpolicy.com/) authorization.\n\nActors (called **particles**) are WebAssembly components that communicate via message passing, run in sandboxed isolation, and can be deployed across a mesh of interconnected nodes.\n\n## Quick Start\n\n```bash\n# Build the runtime\ncargo build --release\n\n# Create a new application\nplasmoid new my-app\ncd my-app\n\n# Create a component\nplasmoid component new greeter\n\n# Build the component\ncargo component build -p greeter --release\n\n# Start a node with the component\nplasmoid start greeter.wasm --spawn greeter --name greeter\n```\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────┐\n│  Plasmoid Node                              │\n│                                             │\n│  ┌──────────────┐  ┌─────────────────────┐  │\n│  │ iroh Endpoint │  │ Particle Registry   │  │\n│  │ (QUIC mesh)   │  │ Component -\u003e WASM   │  │\n│  └──────────────┘  └─────────────────────┘  │\n│                                             │\n│  ┌─────────┐  ┌─────────┐  ┌─────────┐     │\n│  │ WASM    │  │ WASM    │  │ WASM    │     │\n│  │ Particle│  │ Particle│  │ Particle│     │\n│  └─────────┘  └─────────┘  └─────────┘     │\n│                                             │\n│  ┌─────────────────────────────────────┐    │\n│  │ Host Functions (Cedar-gated)        │    │\n│  │ spawn, send, recv, log, link, ...   │    │\n│  └─────────────────────────────────────┘    │\n└─────────────────────────────────────────────┘\n```\n\nParticles communicate through typed messages, can spawn child processes, and support OTP-style links and monitors for fault tolerance.\n\n## Plasmoid SDK\n\nThe `plasmoid-sdk` crate provides a high-level API for writing particles with minimal boilerplate.\n\n### Function-based particles\n\n```rust\nuse plasmoid_sdk::prelude::*;\nuse serde::{Serialize, Deserialize};\n\n#[derive(Serialize, Deserialize)]\nenum MyInit {\n    Leader(u32),\n    Worker,\n}\n\n#[plasmoid_sdk::main]\nfn start(init: MyInit) -\u003e Result\u003c(), String\u003e {\n    match init {\n        MyInit::Leader(n) =\u003e {\n            info!(\"Leading {} workers\", n);\n            for _ in 0..n {\n                let args = to_init_args(\u0026MyInit::Worker);\n                spawn(\"my-component\", None, \u0026args)?;\n            }\n            Ok(())\n        }\n        MyInit::Worker =\u003e {\n            info!(\"Worker started\");\n            while let Some(msg) = recv!(MyMsg, None) {\n                // handle messages\n            }\n            Ok(())\n        }\n    }\n}\n```\n\n### GenServer-style particles\n\n```rust\nuse plasmoid_sdk::prelude::*;\nuse serde::{Serialize, Deserialize};\n\n#[derive(Serialize, Deserialize)]\nenum Request { Get, Increment }\n\n#[derive(Default)]\nstruct Counter { value: u64 }\n\n#[plasmoid_sdk::gen_server]\nimpl Counter {\n    fn handle_call(\u0026mut self, req: Request) -\u003e u64 {\n        match req {\n            Request::Get =\u003e self.value,\n            Request::Increment =\u003e {\n                self.value += 1;\n                self.value\n            }\n        }\n    }\n}\n```\n\nThe `#[gen_server]` macro generates the receive loop, message dispatch, and typed client methods (`Counter::call`, `Counter::cast`) automatically.\n\n### SDK features\n\n| Feature | Description |\n|---|---|\n| `#[plasmoid_sdk::main]` | Entry point macro with optional typed init args (JSON auto-deserialization) |\n| `#[plasmoid_sdk::gen_server]` | GenServer macro with `handle_call`, `handle_cast`, `handle_info` |\n| `send!` / `recv!` | Typed messaging macros using postcard serialization |\n| `info!`, `debug!`, etc. | Structured logging macros |\n| `encode` / `decode` | Postcard serialization helpers |\n| `from_init_args` / `to_init_args` | JSON serialization for init arguments |\n\n## Examples\n\n### Echo (GenServer)\n\nA minimal echo server in 16 lines:\n\n```rust\n#[derive(Default)]\nstruct Echo;\n\n#[plasmoid_sdk::gen_server]\nimpl Echo {\n    fn handle_call(\u0026mut self, req: Vec\u003cu8\u003e) -\u003e Vec\u003cu8\u003e {\n        req\n    }\n\n    fn handle_info(\u0026mut self, data: Vec\u003cu8\u003e) -\u003e plasmoid_sdk::CastResult {\n        if data == b\"stop\" {\n            return plasmoid_sdk::CastResult::Stop;\n        }\n        plasmoid_sdk::CastResult::Continue\n    }\n}\n```\n\n### Ring Benchmark\n\nSpawns N worker processes in a ring, passes M messages around:\n\n```bash\nplasmoid start ring.wasm --spawn ring --init '{\"orchestrator\":[100,1000]}'\n```\n\n## CLI\n\n```\nplasmoid new \u003capp-name\u003e              Create a new application workspace\nplasmoid component new \u003cname\u003e        Create a new component\nplasmoid start [options] [\u003cwasm\u003e...] Boot a node and load components\nplasmoid spawn \u003ccomponent\u003e           Spawn a particle on a running node\nplasmoid send \u003ctarget\u003e \u003cmessage\u003e     Send a message to a particle\n```\n\n## WIT Interface\n\nParticles interact with the runtime through a WIT-defined process interface:\n\n```wit\ninterface process {\n    // Identity\n    self-pid: func() -\u003e pid;\n    spawn: func(component: string, name: option\u003cstring\u003e, init-args: string) -\u003e result\u003cpid, spawn-error\u003e;\n\n    // Messaging\n    send: func(target: borrow\u003cpid\u003e, msg: list\u003cu8\u003e) -\u003e result\u003c_, send-error\u003e;\n    recv: func(timeout-ms: option\u003cu64\u003e) -\u003e option\u003cmessage\u003e;\n\n    // Fault tolerance\n    link: func(target: borrow\u003cpid\u003e) -\u003e result\u003c_, link-error\u003e;\n    monitor: func(target: borrow\u003cpid\u003e) -\u003e u64;\n    trap-exit: func(enabled: bool);\n\n    // Logging\n    log: func(level: log-level, message: string);\n}\n```\n\n## Project Structure\n\n```\n├── Cargo.toml                 # Workspace root\n├── src/                       # Runtime\n│   ├── main.rs                # CLI\n│   ├── runtime/               # WASM engine, actor lifecycle\n│   ├── host/                  # Host functions (logging, database)\n│   ├── registry.rs            # Process registry\n│   ├── mailbox.rs             # Per-process message queue\n│   ├── pid.rs                 # Process identifiers\n│   └── client.rs              # Remote node client\n├── crates/\n│   ├── plasmoid-sdk/          # Component authoring SDK\n│   └── plasmoid-macros/       # Proc macros (#[main], #[gen_server])\n├── components/\n│   ├── echo/                  # Echo example (GenServer)\n│   └── ring/                  # Ring benchmark\n└── wit/                       # WIT interface definitions\n```\n\n## Dependencies\n\n| Component | Crate | Purpose |\n|---|---|---|\n| Networking | `iroh` 0.96 | QUIC mesh with mDNS discovery |\n| WASM Runtime | `wasmtime` 41 | Component model execution |\n| Authorization | `cedar-policy` 4 | Capability-based access control |\n| Serialization | `postcard` 1 | Binary message encoding |\n| Async | `tokio` 1 | Async runtime |\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscrogson%2Fplasmoid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscrogson%2Fplasmoid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscrogson%2Fplasmoid/lists"}