onflow/flow-go: the Flow node software, where release names are mainnet block heights
Reference implementation of the Flow network in Go. Layer 1 proof-of-stake protocol built for consumer apps, AI Agents, and DeFi at scale
At a glance
- What is it?
- flow-go is the AGPL Go implementation of the Flow Layer 1 blockchain, hosting consensus, execution, verification, access and collection node roles plus the Cadence VM integration. Its release names are dated mainnet upgrade points, its test target reorders itself to hide a straggler tail, and importing the module requires cgo.
- Who is it for?
- flow-go fits a protocol contributor or a node operator who needs the canonical implementation rather than a wrapper, since consensus, the multi-role architecture, the Cadence VM integration and the EVM are all in this one repository under AGPL-3.0. It is a poor fit as a library dependency, because the module requires cgo and the underlying cryptography library, so an importer has to enable cgo and accept that constraint.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Release names are block heights, not feature summaries
The release titles are the first thing to read, because they tell you what a version number means in this repository.
The three most recent are named for coordinated mainnet upgrades, each with a date and a block height. v0.49.0 is the 18 May 2026 height coordinated upgrade on Mainnet28 at block height 151,898,000. v0.50.0 is the 2 July 2026 upgrade at block 156,743,600. v0.51.0 is the 18 August 2026 upgrade at block 161,738,787.
So a tag is a cut of the code taken at a point where the network was already scheduled to change state. That is the opposite of a release whose name lists features, and it has a practical consequence: to find out what a version changed, you diff the blocks, not the release notes.
The arithmetic is also worth noting. Between the first two upgrades the chain advanced 4,845,600 blocks. Between the second and third it advanced 4,995,187, a larger span in less time, since the gaps are 44 days and then 47 days. The cadence is therefore about six weeks and fairly regular, and the block delta is roughly five million each time.
The newest tag is v0.51.0 from 18 August 2026, while the last push to the default branch master is dated 29 September 2026, so main has moved on from the tagged release.
Eleven work streams, and six of them are node roles
Development is organised into work streams, each with a home directory holding its own high-level documentation and links to the components it uses. The readme publishes the full table.
Six are runnable roles: the access node, the collection node, the consensus node, the execution node, the verification node, and the observer service. Those correspond to the roles the opening paragraph names, describing the node software that covers consensus, execution, verification, access and collection.
The remaining five are libraries rather than services: the HotStuff consensus implementation under its own directory, storage, the ledger, networking, and cryptography.
The split explains the repository's shape. The top level carries a directory per stream alongside the build machinery: a Makefile, a module file, a licence, a notice, a changelog, a citation file, a security policy, agent instruction files, lint and mockery configuration, and a third-party licence directory. Directories for access, consensus, crypto, engine, fvm, ledger, model, module, network, state, storage and utils sit beside them.
So a contributor to the ledger and a contributor to the p2p layer are working in the same repository without touching the same code, which is what the work stream table exists to make navigable.
cgo is not optional, and every importer inherits that
There is one constraint in the readme that reaches outside the project, and it is easy to miss until a build fails.
Importing the module into your own Go project may require extra Go flags, because the module requires cgo. Specifically, CGO_ENABLED must be set to 1 if cgo is not enabled by default in your environment. The stated cause is the underlying cryptography library, with a pointer to that repository's own build documentation for detail.
That is a significant line in a blockchain node. It means the cryptographic primitives are reached through cgo rather than being pure Go, which in turn means a cross-compiled build needs a C toolchain and a matching target library, not just a Go toolchain.
The build flags in the Makefile are consistent with that: there is a separate crypto ADX flag file at the top level, which is the hardware acceleration switch for the cryptography layer, and the cryptography work stream has its own home directory for the same reason.
For anyone embedding the module rather than running a node, the practical sequence is that a cross-compiled or statically linked target needs extra setup beyond what the Go documentation implies, and the readme does not enumerate it.
Generated code is committed, so a checkout is not reproducible by itself
Code generation is treated as a repository concern rather than a build step, and the instruction to a contributor is explicit.
Generated code is kept up to date in the repository, so it should be committed whenever it changes. Four targets cover the surface: one target runs all code generators, one generates protobuf stubs, one generates OpenAPI schema models, and one generates the mocks used by unit tests.
The consequence is that a plain clone already contains generated output. That is the right choice for a consensus implementation, where the committed bytes are the audited bytes, and it removes a toolchain dependency from every consumer of the repository.
The cost is that the repository is not reproducible from its own sources alone. Regenerating is a separate, explicit operation, and if a generator's output drifts from what is committed, the difference shows up as a review diff rather than as a build error.
The mocking side is worth a further note, because it has a documented history. Mocks are generated with a third-party mockery tool, configured in a file at the top level. You add packages by fully qualified name, and doing so adds all the interfaces within that package, non-recursively. The readme also records that the tool dropped support for generating function mocks, so functions are handled by a different pattern.
That last item is the kind of note that only appears in a repository where the workflow has been lived in.
Two tag families feed one version variable
One line of the Makefile explains a detail you would otherwise discover only on a security branch.
The version variable is derived from git describe, and it is given two match patterns rather than one: the usual v prefix pattern, and a second pattern matching tags that begin with a security-related prefix for the Cadence component.
So the repository has two tag families, and a build on either one still produces a version string. That is a deliberate accommodation for a chain that tags the language implementation separately from the node.
The same block of the Makefile also carries the short commit hash, the branch name with slashes replaced by hyphens, and the full commit. Those four values are what get stamped into a build, and they are the reason a released binary can be traced back to a commit without a separate manifest.
Everything around it is build plumbing for a large Go module: a variable holding the package pattern for all tests, with a comment explaining that CI overrides it so the suite can be split into smaller parallel jobs.
The test target reorders itself to hide a straggler tail
One variable in the Makefile contains a fourteen-entry list of slow test packages, and the comment above it is the most instructive text in the build file.
The problem is described plainly. By default a test run covers all packages, and go test schedules package test binaries in argument order, which is alphabetical for the recursive pattern. The consequence is that a handful of slow, internally sequential packages would otherwise start last and form a tail that dominates the wall time of a full suite.
The fix is to list those packages first so they begin early and run while the remaining packages occupy the other slots. The list is layered: a first line of the wall-time critical path, then a second line of packages that each take on the order of twenty to thirty-five seconds and would otherwise start only after the short packages drain.
Three conditions keep it safe. The list is only prepended when running the full suite, not for the per-job package subsets that CI uses. Overlapping package patterns are deduplicated by the Go tool so nothing runs twice. And the same comment notes that CI can override the package list dynamically to split the suite into parallel jobs.
So the ordering is a local optimization and the splitting is a CI one, and both are described rather than left as folklore.
Go 1.26, Docker, and three exported variables
The setup section is short and specific, and it says why each piece is needed.
Clone the repository. Install Go, with the requirement stated as version 1.26 and later, which matches the module directive in the module file. Install Docker, which is used for running a local network and for integration tests, and is also the recommended way to build and run Flow for local development.
Then three environment variables, because the tooling installs binaries somewhere the shell has to look:
export GOPATH=$(go env GOPATH)
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBINAdd those to a shell profile to persist them, then run the install target for tools, and you are ready to build, test and run.
The rest of the workflow follows the same shape. Unit tests live inside the module they test and the integration suite lives in one directory, each with its own target. For building, one target produces a Docker image containing all node roles, one produces an image for a single role with the role name substituted, and one produces a bare access node binary for Linux on x86_64 that can be run without Docker, named for the access node.
A local network for manual testing has its own guide, separate from the rest of the documentation.
AGPL with a third-party licence inventory in the tree
The licensing arrangement is more elaborate than a single licence file, and for an AGPL project that is expected rather than surprising.
The licence is AGPL-3.0. The top level carries a licence file, a notice file, a directory of third-party library licences, and a separate document describing the licensing approach itself. There is also a citation file for academic use.
Keeping an inventory of third-party licences in the repository is the compliance surface that the copyleft terms imply. An AGPL project that vendors libraries has to be able to state what those libraries are licensed under, and having that list versioned alongside the code means the answer is reviewable in a diff rather than assembled by hand at release time.
The same applies to the Cadence relationship. The related repositories are named explicitly: the Cadence language, the command line tool, the JavaScript client, and the Go SDK. And the Makefile's second tag family is the reminder that the language implementation is versioned on its own schedule.
The repository's own stated audience is protocol contributors, node operators, and teams building infrastructure on or adjacent to Flow. It has been open source since 2019, and at the time of writing the counters are 574 stars, 217 forks and 261 open issues, with the last push to master dated 29 September 2026 and the repository not archived.
Editorial conclusion
flow-go fits a protocol contributor or a node operator who needs the canonical implementation rather than a wrapper, since consensus, the multi-role architecture, the Cadence VM integration and the EVM are all in this one repository under AGPL-3.0. It is a poor fit as a library dependency, because the module requires cgo and the underlying cryptography library, so an importer has to enable cgo and accept that constraint. Before you build on it, check three things: which tag family you want, since the Makefile derives a version from two different tag patterns, whether you can rebuild the committed generated code, because it is checked in rather than produced on demand, and which node role you actually need, since five of the eleven work streams are libraries rather than runnable services.
Frequently asked questions
What is flow-go and what does it contain?
It is the Go reference implementation of the Flow network, a Layer 1 proof-of-stake blockchain, licensed AGPL-3.0 and open source since 2019. It hosts the node software for the consensus, execution, verification, access and collection roles along with the Cadence VM integration used on mainnet, testnet and local networks.
What Go version does flow-go require?
Go 1.26 and later. The setup section states the requirement and the module file declares the same version in its go directive.
Why does importing flow-go require CGO_ENABLED=1?
Because the module requires cgo, and the stated cause is the underlying cryptography library. If cgo is not enabled by default in your environment you must set CGO_ENABLED to 1, which also means a cross-compiled build needs a C toolchain rather than only a Go one.
What do the flow-go release names mean?
They are coordinated mainnet upgrade points rather than feature summaries. v0.51.0 names the 18 August 2026 height coordinated upgrade on Mainnet28 at block height 161738787, with v0.50.0 and v0.49.0 naming the July and May upgrades at blocks 156743600 and 151898000.
How do I build a single node role with flow-go?
Use the Docker target with the role substituted, for example the collection or consensus role, to get an image containing just that role. There is also a target that builds an access node binary for Linux on x86_64 which runs on the machine without Docker and is named flow_access_node.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/onflow-flow-go)