This repository contains practical examples demonstrating F-Mesh - a Flow-Based Programming framework for Go. Each example shows how to model real-world systems as computational graphs with interconnected components.
What is F-Mesh?
F-Mesh is an FBP-inspired framework that lets you express your program as a mesh of components connected by pipes. Instead of writing imperative code, you describe how data flows through your system, making complex interactions more natural and maintainable. Learn more in the wiki.
Examples are grouped by what they teach, not by what they compute. Start at the top.
| Example | Description |
|---|---|
| String Processing | Two components and one pipe: the smallest useful mesh |
| Filter | Routing signals to different outputs by metadata |
| Pipeline | A multi-stage chain that reads stdin and files |
| Example | Description |
|---|---|
| Fibonacci | Cycles: a component's outputs piped back into its own inputs |
| Auto-diff | The mesh is the computation graph: a neural network learns XOR with values flowing forward and gradients flowing back through reverse pipes |
| Nesting | Composition: a component whose activation runs a whole inner mesh |
| FPGA | A board of generic logic cells flashed at runtime from a Verilog-like file: the same mesh becomes an adder, then a counter |
| Hypergraph | Edges that join many nodes to many: a chemical plant where every reaction is one component with one input for all its reactants and one output for all its products, firing only when every reactant is there |
| Load Balancer | Indexed ports and component state: round-robin across N workers |
| Tree Search | A generated tree, one component per node: a search goes down as a wave, one level per cycle, and the answers merge on the way back up |
| Async Input | Driving a mesh from outside: signals injected on a ticker, results drained into a channel |
| Retry | Retrying a failing activation: temporary errors get another attempt with backoff, permanent ones do not |
| State Machine | An FSM out of nothing but fmesh: states are components, transitions are pipes, the current state is a mesh metadata entry — the mesh graph is the state diagram |
| Unix Pipes | A shell job as a mesh: unix commands as components, one log analysed three ways at once and joined into one report |
| Rule Engine | Rules from a config file compiled into a mesh: shared conditions, all/any rules, actions, rebuilt from the file on every run |
| Example | Description |
|---|---|
| Electric Circuit | A supply/demand feedback loop with degrading state |
| Combustion Engine | A four-cylinder engine you drive from the browser, part by part: 39 components from the valves to the fuse box, with the crankshaft driving the next stroke |
| Basic CAN Bus | One bus fanning every frame out to all connected ECUs |
| Advanced CAN Bus | Full CAN protocol with ISO-TP, arbitration and diagnostics |
| Elevator | Two elevators down to the last button, LED, door lock and brake: 119 components, played in the browser, every click a signal into the mesh |
| Life | A step simulation of human physiology inside a habitat |
| Restaurant | One day in a restaurant, one mesh run per minute: parties arrive, wait, eat and leave; swap the host or add tables and run the day again to see what the owner's choices are worth |
These share simulation/sim — a small library for building simulations on an f-mesh (engines, simulated time, commands, scheduling, telemetry). It is a library, not an example.
| Example | Description |
|---|---|
| Graphviz | Exporting mesh topology to DOT/SVG, with activated components highlighted |
| Ray Tracer | Wavefront 3D ray tracer: parallel tile bands and a reflection cycle |
go test ./... runs every example's tests, including the elevator's and the engine's HTTP servers (fast: no browser, no real time). The two browser demos also have end-to-end tests in e2e/, a separate module that builds each demo, runs it on a free port and drives it in the Google Chrome installed on your machine through playwright-go (the Playwright driver is downloaded once, into your cache). They are meant to be run one suite at a time:
make e2e-elevator
make e2e-engine
E2E_HEADFUL=1 make e2e-engine # watch the browser- Go 1.27 or later
- Git
# Clone
git clone https://github.com/hovsep/fmesh-examples.git
cd fmesh-examples
# Run any example, from the repo root...
go run ./patterns/fibonacci
go run ./simulation/electric_circuit
go run ./graphics/ray_tracer
# ...or from the example's own directory
cd patterns/fibonacci && go run .
# Build all examples
make build
# Generate visualization graphs
make graphfmesh-examples/
├── basics/ # everyday meshes
├── patterns/ # how a mesh is wired and driven
│ └── fibonacci/
│ ├── main.go # example code
│ ├── *-graph.dot # graphviz source (generated)
│ └── *-graph.svg # visual diagram (generated)
├── simulation/ # systems evolving over time
│ ├── sim/ # shared simulation library — not an example
│ ├── electric_circuit/
│ ├── can_bus/
│ │ ├── basic/main.go
│ │ └── advanced/
│ │ ├── main.go
│ │ └── can/ # reusable CAN components
│ └── life/
├── graphics/ # pixels
└── internal/ # FMESH_GRAPH helper, shared by every example
Each example is a standalone Go program, runnable either from the repo root (go run ./patterns/fibonacci) or from its own directory (cd patterns/fibonacci && go run .). Visualization files (*-graph.dot and *-graph.svg) are generated using make graph, and land in the example's own directory.
We welcome new examples from any domain: simulations, data processing, protocols, algorithms, or real-world systems.
-
Fork this repository
-
Create a new directory under the category that fits what your example teaches (
basics,patterns,simulationorgraphics— add a new category if none fit):mkdir patterns/my_example cd patterns/my_example -
Write your example in
main.go:- Follow existing patterns
- Add comments explaining the scenario and concepts
- Keep it focused on one concept
-
Generate visualization (optional):
FMESH_GRAPH=1 go run . -
Test your example:
go run . -
Update README.md:
- Add your example to its category's table with a brief description
-
Submit a pull request
package main
import (
"context"
"fmt"
"os"
"github.com/hovsep/fmesh"
"github.com/hovsep/fmesh-examples/internal"
"github.com/hovsep/fmesh/component"
"github.com/hovsep/fmesh/signal"
)
// Description of what this example demonstrates.
// Run: go run .
func main() {
fm, err := getMesh()
if err != nil {
fmt.Println("Failed to build mesh:", err)
os.Exit(1)
}
handled, err := internal.HandleGraphFlag(fm)
if err != nil {
fmt.Println("Failed to generate graph:", err)
os.Exit(1)
}
if handled {
return
}
fm.ComponentByName("processor").InputByName("in").PutSignals(signal.New("hello"))
if _, err := fm.Run(context.Background()); err != nil {
fmt.Println("Mesh finished with error:", err)
os.Exit(1)
}
result := fm.ComponentByName("processor").OutputByName("out").Signals().FirstPayloadOrNil()
fmt.Println("Result:", result)
}
func getMesh() (*fmesh.FMesh, error) {
processor, err := component.New("processor",
component.WithInputs("in"),
component.WithOutputs("out"),
component.WithActivationFunc(func(_ context.Context, this *component.Component) error {
input := this.InputByName("in").Signals().FirstPayloadOrDefault("")
// Your logic here
return this.OutputByName("out").PutSignals(signal.New(input))
}),
)
if err != nil {
return nil, fmt.Errorf("processor component: %w", err)
}
fm, err := fmesh.New("example")
if err != nil {
return nil, fmt.Errorf("new mesh: %w", err)
}
if err := fm.AddComponents(processor); err != nil {
return nil, fmt.Errorf("add components: %w", err)
}
// Connect components with PipeTo here
return fm, nil
}- One concept per example
- Well-commented code explaining the "why"
- Real-world scenarios preferred
- Self-contained and tested
- F-Mesh Repository - Main framework
- F-Mesh Wiki - Complete documentation
- F-Mesh Export - Exports meshes to DOT and other formats
- Flow-Based Programming - Learn about FBP (by J. Paul Morrison)
MIT License - see LICENSE file for details.