EventBus — Go event bus library
EventBus — lightweight event bus for Go with async support and cross-process events. Used in siyuan, evcc, guppy, shinkro. 2k+ stars, 1k+ dependents. MIT.
Lightweight event bus for Go — subscribe/publish with sync and async handlers, optional cross-process events via RPC. MIT-licensed, widely used in note-taking, EV charging, and event-driven Go projects.
→ GitHub · → Documentation (pkg.go.dev)
| GitHub Stars | Dependent repos | Dependent packages | Forks |
|---|---|---|---|
| 2k+ | 1k+ | 833+ | 241 |
Used by SiYuan, EVCC, Guppy, Shinkro, Argo CD ecosystem and others. See the list below.
Projects and Companies Using EventBus
A list of notable open-source projects and products that depend on github.com/asaskevich/EventBus.
📊 Overview Statistics
- Total Dependent Repositories: 1k+
- Total Dependent Packages: 833+
- GitHub Stars: 2k+
- Forks: 241
🏢 Notable Dependents
| # | Project | Description | Repository |
|---|---|---|---|
| 1 | SiYuan | Local-first note-taking and knowledge management | siyuan and community forks |
| 2 | EVCC | Electric vehicle charging controller | ownctrl-energy/evcc |
| 3 | Guppy | Game server / tooling | storacha/guppy |
| 4 | HarmonyLite | HarmonyOS-related tooling | wongfei2009/harmonylite |
| 5 | Shinkro | Media / automation | shinkro/shinkro |
| 6 | Props | Configuration / props management | tietang/props |
| 7 | Trendyol go-dcp-bq | Data pipeline (DCP to BigQuery) | Trendyol/go-dcp-bq |
| 8 | Argo CD Operator | GitOps operator ecosystem | argocd-operator and forks |
| 9 | Hollowtrees | Event-driven tooling | kompute/hollowtrees |
| 10 | MCPSpy | MCP / tooling | internauticos/MCPSpy |
API Overview
Core Methods
| Method | Description |
|---|---|
| New() | Returns a new EventBus with empty handlers. |
| Subscribe(topic, fn) | Subscribe to a topic. Returns error if fn is not a function. |
| SubscribeOnce(topic, fn) | Subscribe once; handler is removed after first execution. |
| Unsubscribe(topic, fn) | Remove callback for a topic. |
| HasCallback(topic) | Returns true if any callback is subscribed to the topic. |
| Publish(topic, args…) | Execute callbacks for the topic; extra args are passed to the callback. |
| SubscribeAsync(topic, fn, transactional) | Async callback; transactional controls serial vs concurrent execution. |
| SubscribeOnceAsync(topic, fn) | One-time async subscription. |
| WaitAsync() | Wait for all async callbacks to complete. |
Cross-Process Events
EventBus can work over the network with two RPC services:
- Server — listens for remote subscriptions and publishes events to clients.
- Client — subscribes to topics on a remote server and receives events locally.
Files: server.go, client.go, network_bus.go. See code examples below.
Code Examples
Example 1: Basic Subscribe and Publish
package main
import (
"fmt"
"github.com/asaskevich/EventBus"
)
func calculator(a int, b int) {
fmt.Printf("%d\n", a+b)
}
func main() {
bus := EventBus.New()
bus.Subscribe("main:calculator", calculator)
bus.Publish("main:calculator", 20, 40)
bus.Unsubscribe("main:calculator", calculator)
}
Example 2: Async Subscription
package main
import (
"fmt"
"time"
"github.com/asaskevich/EventBus"
)
func slowCalculator(a, b int) {
time.Sleep(3 * time.Second)
fmt.Printf("%d\n", a+b)
}
func main() {
bus := EventBus.New()
bus.SubscribeAsync("main:slow_calculator", slowCalculator, false)
bus.Publish("main:slow_calculator", 20, 60)
fmt.Println("start: do some stuff while waiting for a result")
fmt.Println("end: do some stuff while waiting for a result")
bus.WaitAsync()
fmt.Println("do some stuff after waiting for result")
}
Example 3: SubscribeOnce
func HelloWorld() { fmt.Println("Hello, World!") }
// ...
bus.SubscribeOnce("topic:handler", HelloWorld)
bus.Publish("topic:handler") // HelloWorld runs once, then is removed
Example 4: Server (Cross-Process)
func main() {
server := NewServer(":2010", "/_server_bus_", New())
server.Start()
// ...
server.EventBus().Publish("main:calculator", 4, 6)
// ...
server.Stop()
}
Example 5: Client (Cross-Process)
func main() {
client := NewClient(":2015", "/_client_bus_", New())
client.Start()
client.Subscribe("main:calculator", calculator, ":2010", "/_server_bus_")
// ...
client.Stop()
}
Use Cases
- In-Process Event-Driven Design — decouple components with topics (e.g. UI ↔ logic, plugins).
- Async Handlers — run subscribers in goroutines; use
WaitAsync()when you need to wait. - One-Shot Handlers —
SubscribeOnce/SubscribeOnceAsyncfor single-use reactions. - Cross-Process Events — Server/Client RPC for distributing events across processes or machines.
Resources
| Resource | Link |
|---|---|
| GitHub | github.com/asaskevich/EventBus |
| Go docs | pkg.go.dev/github.com/asaskevich/eventbus |
| Dependents | GitHub dependency graph |
EventBus — lightweight event bus for Go with async and cross-process support. Open source, MIT.
© Aliaksei Saskevich