{"id":30579531,"url":"https://github.com/ddrcode/maiko","last_synced_at":"2026-02-16T00:14:41.975Z","repository":{"id":309806987,"uuid":"1037617135","full_name":"ddrcode/maiko","owner":"ddrcode","description":"Actor framework for Tokio","archived":false,"fork":false,"pushed_at":"2026-02-13T01:53:27.000Z","size":254,"stargazers_count":10,"open_issues_count":11,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-13T07:04:36.097Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ddrcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2025-08-13T21:15:52.000Z","updated_at":"2026-02-12T23:56:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"5adaf5a6-291a-44a1-9811-c09560578f1f","html_url":"https://github.com/ddrcode/maiko","commit_stats":null,"previous_names":["ddrcode/maiko"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/ddrcode/maiko","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Fmaiko","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Fmaiko/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Fmaiko/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Fmaiko/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ddrcode","download_url":"https://codeload.github.com/ddrcode/maiko/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Fmaiko/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29491998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T19:29:10.908Z","status":"ssl_error","status_checked_at":"2026-02-15T19:29:10.419Z","response_time":118,"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":[],"created_at":"2025-08-29T04:11:50.150Z","updated_at":"2026-02-16T00:14:41.964Z","avatar_url":"https://github.com/ddrcode.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Maiko\n\n\u003cdiv align=\"center\"\u003e\n\n**Structure your Tokio app as actors, not channels and spawns**\n\n[![Crates.io](https://img.shields.io/crates/v/maiko.svg)](https://crates.io/crates/maiko)\n[![Documentation](https://docs.rs/maiko/badge.svg)](https://docs.rs/maiko)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n\u003c/div\u003e\n\n---\n\n## What is Maiko?\n\n**Maiko** lets you build concurrent Tokio applications without a single `spawn` or manual channel. Declare actors, declare subscriptions, and Maiko handles the routing. It is a topology-aware event router with actor lifecycle management for [Tokio](https://tokio.rs/).\n\nActors are named components with their own state and lifecycle. They communicate through events routed by topic, without knowing who's listening. Think Kafka-style pub/sub, but embedded in your Tokio application.\n\nMaiko comes with a built-in [test harness](docs/testing.md) for asserting on event flow, correlation tracking for tracing event propagation, and monitoring hooks for observability — all without external infrastructure.\n\n### No more channel spaghetti\n\nBuilding concurrent Tokio applications often means manually creating, cloning, and wiring channels between tasks:\n\n```rust\n// Without Maiko: manual channel wiring\nlet (tx1, rx1) = mpsc::channel(32);\nlet (tx2, rx2) = mpsc::channel(32);\nlet (tx3, rx3) = mpsc::channel(32);\n// Clone tx1 for task B, clone tx2 for task C, wire rx1 to...\n```\n\n```rust\n// With Maiko: declare subscriptions, routing happens automatically\nsup.add_actor(\"sensor\",    |ctx| Sensor::new(ctx),    Subscribe::none())?;      // produces events\nsup.add_actor(\"processor\", |ctx| Processor::new(ctx), \u0026[Topic::SensorData])?;   // handles sensor data\nsup.add_actor(\"logger\",    |ctx| Logger::new(ctx),    Subscribe::all())?;       // observes everything\n```\n\n### How it compares\n\n| | Maiko | Raw Tokio | Actix/Ractor | Kafka |\n|---|-------|-----------|--------------|-------|\n| Routing | Topic-based pub/sub | Manual channels | Direct addressing | Topic-based pub/sub |\n| Coupling | Loose (actors don't know each other) | Explicit wiring | Tight (need actor addresses) | Loose |\n| Communication | Events | Channels | Request-response | Events |\n| Lifecycle | Managed (start, stop, hooks) | Manual spawns | Managed | Managed |\n| Testing | Built-in harness, spies, event chains | Roll your own | None built-in | External tools |\n| Correlation | First-class (correlation IDs, chain tracing) | Manual | Manual | Headers |\n| Scope | In-process | In-process | In-process | Distributed |\n\nMaiko sits between raw Tokio and full actor frameworks. Think of it as moving from breadboard to PCB — same components, reliable traces, testable as a whole.\n\n### Where it fits\n\nEvent-centric systems: processing stock ticks, device signals, telemetry pipelines, handling system\nevents, data transformation.\n\nNot ideal for request-response APIs or RPC patterns.\n\n---\n\n## Quick Start\n\n```sh\ncargo add maiko\n```\n\n```rust\nuse maiko::*;\n\n#[derive(Event, Clone, Debug)]\nenum MyEvent {\n    Hello(String),\n}\n\nstruct Greeter;\n\nimpl Actor for Greeter {\n    type Event = MyEvent;\n\n    async fn handle_event(\u0026mut self, envelope: \u0026Envelope\u003cSelf::Event\u003e) -\u003e Result\u003c()\u003e {\n        if let MyEvent::Hello(name) = envelope.event() {\n            println!(\"Hello, {}!\", name);\n        }\n        Ok(())\n    }\n}\n\n#[tokio::main]\nasync fn main() -\u003e Result\u003c()\u003e {\n    let mut sup = Supervisor::\u003cMyEvent\u003e::default();\n    sup.add_actor(\"greeter\", |_ctx| Greeter, \u0026[DefaultTopic])?;\n\n    sup.start().await?;\n    sup.send(MyEvent::Hello(\"World\".into())).await?;\n    sup.stop().await\n}\n```\n\n### Examples\n\nSee the [`examples/`](maiko/examples/) directory:\n\n- **[`pingpong.rs`](maiko/examples/pingpong.rs)** - Event exchange between actors\n- **[`guesser.rs`](maiko/examples/guesser.rs)** - Multi-actor game with topics and timing\n- **[`monitoring.rs`](maiko/examples/monitoring.rs)** - Observing event flow\n\n```bash\ncargo run --example pingpong\ncargo run --example guesser\n```\n\n---\n\n## Core Concepts\n\n| Concept | Description |\n|---------|-------------|\n| **Event** | Messages that flow through the system (`#[derive(Event)]`) |\n| **Topic** | Routes events to interested actors |\n| **Actor** | Processes events via `handle_event()` and produces events via `step()` |\n| **Context** | Provides actors with `send()`, `stop()`, and metadata access |\n| **Supervisor** | Manages actor lifecycles and the runtime |\n| **Envelope** | Wraps events with metadata (sender, correlation ID) |\n\nFor detailed documentation, see **[Core Concepts](docs/concepts.md)**.\n\n---\n\n## Test Harness\n\nMaiko includes a test harness (built on the monitoring API) for observing and asserting on event flow:\n\n```rust\n#[tokio::test]\nasync fn test_event_delivery() -\u003e Result\u003c()\u003e {\n    let mut sup = Supervisor::\u003cMyEvent\u003e::default();\n    let producer = sup.add_actor(\"producer\", |ctx| Producer::new(ctx), \u0026[DefaultTopic])?;\n    let consumer = sup.add_actor(\"consumer\", |ctx| Consumer::new(ctx), \u0026[DefaultTopic])?;\n\n    let mut test = Harness::new(\u0026mut sup).await;\n    sup.start().await?;\n\n    test.start_recording().await;\n    let id = test.send_as(\u0026producer, MyEvent::Data(42)).await?;\n    test.stop_recording().await;\n\n    assert!(test.event(id).was_delivered_to(\u0026consumer));\n    assert_eq!(1, test.actor(\u0026consumer).events_received());\n\n    sup.stop().await\n}\n```\n\nEnable with `features = [\"test-harness\"]`. See **[Test Harness Documentation](docs/testing.md)** for details.\n\n---\n\n## Monitoring\n\nThe monitoring API provides hooks into the event lifecycle - useful for debugging, metrics, and logging:\n\n```rust\nuse maiko::monitoring::Monitor;\n\nstruct EventLogger;\n\nimpl\u003cE: Event, T: Topic\u003cE\u003e\u003e Monitor\u003cE, T\u003e for EventLogger {\n    fn on_event_handled(\u0026self, envelope: \u0026Envelope\u003cE\u003e, topic: \u0026T, receiver: \u0026ActorId) {\n        println!(\"[handled] {} by {}\", envelope.id(), receiver.name());\n    }\n}\n\nlet handle = sup.monitors().add(EventLogger).await;\n```\n\nEnable with `features = [\"monitoring\"]`. See **[Monitoring Documentation](docs/monitoring.md)** for details.\n\n---\n\n## Documentation\n\n- **[Core Concepts](docs/concepts.md)** - Events, Topics, Actors, Context, Supervisor\n- **[Monitoring](docs/monitoring.md)** - Event lifecycle hooks, metrics collection\n- **[Test Harness](docs/testing.md)** - Recording, spies, queries, assertions\n- **[Advanced Topics](docs/advanced.md)** - Error handling, configuration, design philosophy\n- **[FAQ](docs/faq.md)** - Common questions answered\n- **[API Reference](https://docs.rs/maiko)** - Complete API documentation\n\n---\n\n## Roadmap\n\n**Near-term:**\n- Dynamic actor spawning/removal at runtime\n- Improved supervision and error handling strategies\n\n**Future:**\n- `maiko-actors` crate with reusable actors (IPC bridges, WebSocket, OpenTelemetry)\n- Cross-process communication via bridge actors\n\n---\n\n## Used In\n\nMaiko powers the daemon in [**Charon**](https://github.com/ddrcode/charon) - a USB keyboard pass-through device built on Raspberry Pi. The daemon uses Maiko actors to read input from multiple keyboards, map and translate key events, output USB HID to the host, and coordinate telemetry, IPC, and power management.\n\n---\n\n## Current State\n\nMaiko is battle-tested in the [Charon](https://github.com/ddrcode/charon) project, where it runs continuously, but it's not yet production-grade. I'd describe it as solid for happy-path scenarios and insufficient for rainy days. Supervision is minimal, backpressure isn't handled, and improved error handling and recovery strategies are planned for 0.3.0.\n\nFor now, Maiko demonstrates what it wants to be. That's the state I wanted to reach before sharing it with a wider audience. Want to help shape what comes next? See below.\n\n---\n\n## Contributing\n\nContributions welcome! Whether it's a bug report, feature idea, or pull request - all input is appreciated.\n\n- **Try it out** and let us know what you think\n- **Report issues** via [GitHub Issues](https://github.com/ddrcode/maiko/issues)\n- **Looking to contribute code?** Check out [good first issues](https://github.com/ddrcode/maiko/issues?q=is%3Aissue+state%3Aopen+label%3A%22good+first+issue%22)\n\n---\n\n## Acknowledgments\n\nInspired by [Kafka](https://kafka.apache.org/) (topic-based routing) and built on [Tokio](https://tokio.rs/) (async runtime).\n\n---\n\n## License\n\nLicensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddrcode%2Fmaiko","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fddrcode%2Fmaiko","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddrcode%2Fmaiko/lists"}