Flow-based and dataflow programming library for Go (golang)
Go
1,674
279 commits
updated Jun 5, 2026
Dataflow and Flow-based programming library for Go.
GoFlow is a lean and opinionated implementation of Flow-based programming (FBP) that lets you design applications as graphs of components reacting to data as it flows through the graph.
Flow-based programming is a programming paradigm that defines applications as networks of black-box processes that exchange data across predefined connections by message passing, where the connections are specified externally to the processes.
GoFlow requires Go 1.23 or later.
go get github.com/trustmaster/goflow
Then import it in your code:
import "github.com/trustmaster/goflow"
Below is a complete program that builds a simple two-component network: one greets names, the other prints the result.

package main
import (
"fmt"
"github.com/trustmaster/goflow"
)
// Greeter sends greetings.
type Greeter struct {
Name <-chan string // input port
Res chan<- string // output port
}
// Process reads incoming names and sends back greetings.
func (c *Greeter) Process() {
for name := range c.Name {
c.Res <- fmt.Sprintf("Hello, %s!", name)
}
}
// Printer prints its input on screen.
type Printer struct {
Line <-chan string // input port
}
// Process reads lines and prints them.
func (c *Printer) Process() {
for line := range c.Line {
fmt.Println(line)
}
}
// NewGreetingApp defines the application graph.
func NewGreetingApp() *goflow.Graph {
n := goflow.NewGraph()
n.Add("greeter", new(Greeter))
n.Add("printer", new(Printer))
n.Connect("greeter", "Res", "printer", "Line")
n.MapInPort("In", "greeter", "Name")
return n
}
func main() {
net := NewGreetingApp()
in := make(chan string)
net.SetInPort("In", in)
wait := goflow.Run(net)
in <- "John"
in <- "Boris"
in <- "Hanna"
close(in)
<-wait
}
Why the
waitchannel? The flow-based world is asynchronous — events don't necessarily happen in the order they were sent. Thewaitchannel signals when the network has fully completed, preventing premature program termination.
| Term | Description |
|---|---|
| Component | The basic processing element. Its structure consists of input/output ports and state fields; its behavior is defined by event handlers. Analogous to a Class. |
| Connection | A link between two ports in the graph. In GoFlow this is a typed channel. |
| Graph | A higher-level entity composed of components and connections. Can represent composite components or entire applications. Analogous to a Class. |
| Network | A running instance of a Graph. Analogous to an Object. |
| Port | A property through which a Component or Graph communicates with the outside world (input/output). In GoFlow this is a channel field. |
| Process | A running instance of a Component. Analogous to an Object. |
More terms can be found in the Flowbased.org Terminology and the FBP wiki.
GoFlow includes a built-in dsl package that lets you define application graphs using standard Flow-Based Programming (FBP) syntax in .fbp files instead of writing Go code.
import "github.com/trustmaster/goflow/dsl"
A minimal .fbp file looks like this:
# Declare the sender's input as a graph port
INPORT=Sender.IN:IN
# Declare the receiver's output as a graph port
OUTPORT=Receiver.OUT:OUT
# Declare two processes and connect them
Sender(test/sender) OUT -> IN Receiver(test/receiver)
Load and run it with:
g, err := dsl.LoadFile("graph.fbp", factory)
The dsl package supports process declarations, connections, array ports, IIPs (initial information packets), and port exports. See the dsl package README for the full syntax guide and API reference.
go doc github.com/trustmaster/goflow
Or view the online reference.
Contributions are welcome! Please open an issue or pull request on GitHub.
Before submitting changes, make sure your code passes the linter and tests:
make test
1,510 followers · starred Sep 2014
806 followers · starred Feb 2012
244 followers · starred Dec 2015
35 followers · starred Feb 2015
Flow-based and dataflow programming library for Go (golang)
Go
1,674
279 commits
updated Jun 5, 2026
Dataflow and Flow-based programming library for Go.
GoFlow is a lean and opinionated implementation of Flow-based programming (FBP) that lets you design applications as graphs of components reacting to data as it flows through the graph.
Flow-based programming is a programming paradigm that defines applications as networks of black-box processes that exchange data across predefined connections by message passing, where the connections are specified externally to the processes.
GoFlow requires Go 1.23 or later.
go get github.com/trustmaster/goflow
Then import it in your code:
import "github.com/trustmaster/goflow"
Below is a complete program that builds a simple two-component network: one greets names, the other prints the result.

package main
import (
"fmt"
"github.com/trustmaster/goflow"
)
// Greeter sends greetings.
type Greeter struct {
Name <-chan string // input port
Res chan<- string // output port
}
// Process reads incoming names and sends back greetings.
func (c *Greeter) Process() {
for name := range c.Name {
c.Res <- fmt.Sprintf("Hello, %s!", name)
}
}
// Printer prints its input on screen.
type Printer struct {
Line <-chan string // input port
}
// Process reads lines and prints them.
func (c *Printer) Process() {
for line := range c.Line {
fmt.Println(line)
}
}
// NewGreetingApp defines the application graph.
func NewGreetingApp() *goflow.Graph {
n := goflow.NewGraph()
n.Add("greeter", new(Greeter))
n.Add("printer", new(Printer))
n.Connect("greeter", "Res", "printer", "Line")
n.MapInPort("In", "greeter", "Name")
return n
}
func main() {
net := NewGreetingApp()
in := make(chan string)
net.SetInPort("In", in)
wait := goflow.Run(net)
in <- "John"
in <- "Boris"
in <- "Hanna"
close(in)
<-wait
}
Why the
waitchannel? The flow-based world is asynchronous — events don't necessarily happen in the order they were sent. Thewaitchannel signals when the network has fully completed, preventing premature program termination.
| Term | Description |
|---|---|
| Component | The basic processing element. Its structure consists of input/output ports and state fields; its behavior is defined by event handlers. Analogous to a Class. |
| Connection | A link between two ports in the graph. In GoFlow this is a typed channel. |
| Graph | A higher-level entity composed of components and connections. Can represent composite components or entire applications. Analogous to a Class. |
| Network | A running instance of a Graph. Analogous to an Object. |
| Port | A property through which a Component or Graph communicates with the outside world (input/output). In GoFlow this is a channel field. |
| Process | A running instance of a Component. Analogous to an Object. |
More terms can be found in the Flowbased.org Terminology and the FBP wiki.
GoFlow includes a built-in dsl package that lets you define application graphs using standard Flow-Based Programming (FBP) syntax in .fbp files instead of writing Go code.
import "github.com/trustmaster/goflow/dsl"
A minimal .fbp file looks like this:
# Declare the sender's input as a graph port
INPORT=Sender.IN:IN
# Declare the receiver's output as a graph port
OUTPORT=Receiver.OUT:OUT
# Declare two processes and connect them
Sender(test/sender) OUT -> IN Receiver(test/receiver)
Load and run it with:
g, err := dsl.LoadFile("graph.fbp", factory)
The dsl package supports process declarations, connections, array ports, IIPs (initial information packets), and port exports. See the dsl package README for the full syntax guide and API reference.
go doc github.com/trustmaster/goflow
Or view the online reference.
Contributions are welcome! Please open an issue or pull request on GitHub.
Before submitting changes, make sure your code passes the linter and tests:
make test
1,510 followers · starred Sep 2014
806 followers · starred Feb 2012
244 followers · starred Dec 2015
35 followers · starred Feb 2015