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 |
| 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: fuel, current and rotation as flows, 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 cabs, six floors: a terminal UI sends button presses in, the mesh sends the building's state back out |
| Life | A step simulation of human physiology inside a habitat |
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 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.