F-Mesh is a Flow-Based Programming (FBP) framework that lets you build applications as a graph of independent, reusable components. Think of it as connecting building blocks with pipes - data flows through your program like water through a network of connected components.
Inspired by J. Paul Morrison's FBP, F-Mesh brings the power of dataflow programming to Go with a clean, type-safe API.
go get github.com/hovsep/fmeshHere's a simple mesh that concatenates two strings and converts them to uppercase:
package main
import (
"fmt"
"os"
"strings"
"github.com/hovsep/fmesh"
"github.com/hovsep/fmesh/component"
"github.com/hovsep/fmesh/signal"
)
func main() {
// Create the mesh
fm := fmesh.New("hello world").
AddComponents(
component.New("concat").
AddInputs("i1", "i2").
AddOutputs("res").
WithActivationFunc(func(c *component.Component) error {
word1 := c.InputByName("i1").Signals().FirstPayloadOrDefault("").(string)
word2 := c.InputByName("i2").Signals().FirstPayloadOrDefault("").(string)
c.OutputByName("res").PutSignals(signal.New(word1 + word2))
return nil
}),
component.New("uppercase").
AddInputs("i1").
AddOutputs("res").
WithActivationFunc(func(c *component.Component) error {
str := c.InputByName("i1").Signals().FirstPayloadOrDefault("").(string)
c.OutputByName("res").PutSignals(signal.New(strings.ToUpper(str)))
return nil
}),
)
// Connect components via pipes
fm.ComponentByName("concat").OutputByName("res").
PipeTo(fm.ComponentByName("uppercase").InputByName("i1"))
// Set initial inputs
fm.ComponentByName("concat").InputByName("i1").PutSignals(signal.New("hello "))
fm.ComponentByName("concat").InputByName("i2").PutSignals(signal.New("world!"))
// Run the mesh
_, err := fm.Run()
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
}
// Get results
results := fm.ComponentByName("uppercase").OutputByName("res").Signals().FirstPayloadOrNil()
fmt.Printf("Result: %v\n", results) // Output: HELLO WORLD!
}Build complex workflows from simple, reusable components. Each component is independent and testable.
Extend behavior at any execution point - mesh lifecycle, cycles, component activations, and port operations:
fm.SetupHooks(func(h *fmesh.Hooks) {
h.BeforeRun(func(fm *fmesh.FMesh) error {
fmt.Println("Starting mesh...")
return nil
})
h.CycleEnd(func(ctx *fmesh.CycleContext) error {
fmt.Printf("Cycle #%d complete\n", ctx.Cycle.Number())
return nil
})
})Tag signals and components with labels, then filter and process them with powerful collection APIs.
Components activate in cycles (artificial "time"), allowing multiple components to process simultaneously - like lighting multiple lamps at once.
Fluent interface for building meshes with readable, declarative code.
All components in a single activation cycle run concurrently - no need to manage goroutines or other concurrency primitives yourself.
| Concept | Description |
|---|---|
| Component | The main building block - has inputs, outputs, and an activation function |
| Port | Entry/exit points on components. Unlimited inputs and outputs per component |
| Pipe | Connects an output port to an input port to transfer data |
| Signal | Data packets flowing through pipes. Type-agnostic with optional labels |
| Cycle | One "tick" of execution where all ready components activate |
F-Mesh excels at:
- Data transformation pipelines - ETL, data processing, format conversion
- Workflow automation - Multi-step business processes
- Computational graphs - Scientific computing, simulations
- Game logic - Entity systems, behavior trees
- Stream processing - Event handling, reactive systems
- Experimental architectures - Prototyping dataflow designs
- Wiki - Full documentation
- Examples Repository - Working examples and patterns
- API Reference - Complete API docs
- Flow-Based Programming - Learn about FBP (by J. Paul Morrison)
F-Mesh is not a classical FBP implementation:
- Not suitable for long-running components
- No wall-clock time events (timers, tickers)
- Components execute in discrete cycles, not real-time
For real-time streaming or long-running processes, consider alternatives like traditional FBP systems or message queues.
Contributions are welcome! Please:
- Check existing issues or create a new one
- Fork the repository
- Create a feature branch
- Submit a pull request
MIT License - see LICENSE file for details.
Made by @hovsep
Star us on GitHub if you find F-Mesh useful!
