CLI tool
nx-go/nx-go avatar
nx-go/nx-go

nx-go, putting a Go monorepo inside an Nx workspace

🍈 Nx plugin to use Go in a Nx Workspace

571 stars53 forksTypeScriptMIT

At a glance

What is it?
nx-go is an Nx plugin that teaches Nx how to build, test, lint and serve Go projects, with zero-config task inference for anything that has a go.mod. It works by running the official Go commands, which keeps it dependency-free, and it ships a matching set of executors and generators for the plugin ecosystem's usual ways of working.
Who is it for?
nx-go suits a team that has committed to Nx as the orchestrator for a polyglot repository and wants Go to participate in the same graph, cache and CI as the TypeScript side, without maintaining a hand-written task configuration for every Go project. It does not suit a Go-only team with no Nx in the picture, and it does not suit a repository that is still deciding on its build tooling.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 25 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the plugin actually adds to Nx

nx-go is an Nx plugin for using Go in an Nx workspace, and the framing in the project documentation is first-class support of Go in an Nx workspace. The package is published to npm as `@nx-go/nx-go`.

The interesting part is what it does not do. The feature list says it is reliable because it uses official Go commands in the background with no external dependency, and that it is community friendly with integration for recognised community projects such as Air, the Go live reload tool.

That is the whole design in one sentence. The plugin does not reimplement a build system, a test runner or a linter. It calls `go build`, `go test` and the rest, and wraps them in Nx's execution model so that the results participate in Nx's caching, its task graph and its affected-based CI logic.

The audience is therefore a team that has already chosen Nx and now has Go in the repository, or a polyglot team where Go and TypeScript share one orchestration layer. The topics list confirms the framing: automation, go, golang, monorepo, nx, nx-plugin and nx-workspace.

The licence is MIT, the last push to the repository was on 2026-09-28, and the recorded releases are 4.1.1 from 2026-06-23, 4.0.0 from 2026-04-23 and 4.0.0-beta.0 from 2026-02-20. The project is under the `nx-go` GitHub organisation, with Bram Borggreve as creator and Maxime Malgorn as maintainer, and there is a separate playground repository for trying the capabilities.

Three ways to get it into a workspace

The getting started section gives three commands, and which one you need depends on whether the workspace exists.

To create a workspace that already has Go support, you use the create-nx-workspace CLI with the plugin's preset.

shell
npx create-nx-workspace go-workspace --preset=@nx-go/nx-go

To add Go to a workspace that already exists, the add command does it.

shell
nx add @nx-go/nx-go

And to move to the newest version of the plugin in an existing setup, the migrate command.

shell
nx migrate @nx-go/nx-go

The prerequisite is stated plainly and it is short: you need to have a stable version of Go installed on your machine, and then you are ready. There is no Node-side Go toolchain to install, no downloaded compiler and no shim, which is the practical consequence of the design decision to drive the official Go commands.

That also has a consequence for CI. A GitHub Actions runner or a GitLab runner image that has Node but not Go will fail at the point the task runs rather than at install time, so the Go toolchain has to be part of your CI image.

The `nx migrate` command is worth calling out separately from a dependency bump, because Nx migrations rewrite your workspace configuration as well as moving the package version. In a workspace where `nx.json` and `project.json` files are checked in, running the migration is a change to those files and it belongs in a branch where somebody can read the diff.

Multi-module Go workspaces and the one-mod escape hatch

The plugin makes a choice for you that has consequences, and it is worth understanding what the choice is before you accept it.

By default the plugin configures a multi-module Go workspace, to simplify project management and improve the quality of the Nx graph. The reasoning is visible in the repository: a Go workspace with one module per project lines up one to one with an Nx project, so the Nx graph and the Go workspace graph describe the same structure.

If you do not want that, there is a generator for it, `convert-to-one-mod`, and the documentation notes that generators will automatically adapt to your configuration afterwards.

shell
nx g @nx-go/nx-go:convert-to-one-mod

That second half is the interesting part. Changing the workspace layout is not just a change of directory structure, it changes what the plugin generates and infers, and the plugin is written to notice. Running this generator and then hand-editing generated files is the path to a workspace where the generators and the checked-in configuration disagree.

The multi-module layout also has a version floor. The documentation notes that multi-module Go workspaces require Go 1.18 or later, which is a mild constraint in 2026 but still worth knowing if you pin an older Go for another reason.

The plugin also has an inverse operation. To convert existing projects from executor-based to inferred task configuration, you need a multi-module Go workspace, and the command is Nx's own.

shell
nx g infer-targets

So the two commands are related. The inferred-task model is the modern one in Nx, where targets are derived from the project files rather than declared in configuration, and the plugin supports it, but only for the multi-module layout. If you have run `convert-to-one-mod` you are on the executor-based path, which is the older model that still works.

Inferred tasks and the executors that sit underneath

The feature list calls out zero-config setup with automatic task inference for projects with `go.mod`, and optimized caching with smart inputs and outputs. That is the part of the plugin that saves the most work, and it is worth understanding what it does.

A project with a `go.mod` is a Go project, and the plugin can infer the targets from that fact alone. The user writes no task configuration, and Nx knows how to build, test and lint it, with the cache inputs and outputs chosen so that a change to an unrelated file does not invalidate the build.

The executor list is the manual counterpart, for the cases inference cannot cover. There is `build` to build a Go project, `generate` to generate code using Go, `lint` to format and lint a Go project, `serve` to run a Go application, `serve-air` to run a Go application with Air live reload, `test` to run the tests of a Go project, and `tidy` which ensures the go.mod file matches a project source code.

The `serve-air` executor is the community integration in the feature list, since Air is the Go live reload tool the project links to. And `tidy` is the one people forget: a Go module's `go.mod` records its dependencies, and if the imports and the manifest drift apart the build fails in a way that is confusing. Making that a first-class task rather than a thing a developer remembers to run is the kind of detail the executor list is there for.

On the generator side there are two, `application` to generate a Go application and `library` to generate a Go library, and each has a documentation page under `docs/generators/`. The `nx list @nx-go/nx-go` command shows the capabilities, and the plugin configuration is documented separately at `docs/options.md` for the cases where the defaults are not what you want.

The combination of inference plus executors is what makes this usable. Inference removes the configuration burden for the common case, and the executors remain for the case where you need to do something the inference rules do not anticipate.

The Nx version is the constraint that decides your upgrade path

The compatibility table is short and specific, and it is the first thing to check.

| nx-go version | Nx version | | ------------- | ---------------- | | 4.x | 20.x to 23.x | | 3.x | 17.x to 20.x | | ~~2.x~~ | ~~13.x to 16.x~~ | | ~~1.x~~ | ~~< 13.x~~ |

Two of the four rows are struck through, so the 2.x and 1.x lines of the plugin are no longer maintained against current Nx. The plugin's own major version therefore tracks the Nx major version range it supports, and a team on Nx 16 has no supported nx-go to install.

That is a normal pattern for an Nx plugin, since the plugin API changes with Nx, but it does mean the plugin's version and the workspace's Nx version are not independent choices. Upgrading Nx past 23 means waiting for or moving to the nx-go line that supports it.

The Go side has its own rule. The documentation states that this plugin is only tested on stable versions of Go, that older versions do not receive support, and that you can expect a fair degree of compatibility anyway. That last clause is a measured one: it tells you the untested path probably works, without promising it.

The build setup in the repository is consistent with a plugin that has to work across many Nx versions. The root package is `@nx-go/source` at version 0.0.0 and marked private, with scripts that all delegate to Nx, including `nx build nx-go`, `nx test nx-go`, `nx lint nx-go` and `nx e2e nx-go-e2e`, and an `affected` script for CI. The dependencies pin `@nx/devkit` at 21.6.10, and the dev dependencies pin the matching Nx packages, `@nx/plugin`, `@nx/workspace`, `@nx/jest` and `@nx/eslint`, all at 21.6.10, with `nx` itself at 21.6.10 and the package manager declared as pnpm. So the repository is developed against Nx 21 even though the published 4.x plugin supports 20 through 23.

There is also a `jest.config.ts`, a `jest.preset.js` and a `tsconfig.base.json`, so the plugin's own tests run under the same Jest setup an Nx workspace would use, and husky with a commitlint config handles the commit conventions.

Editorial conclusion

nx-go suits a team that has committed to Nx as the orchestrator for a polyglot repository and wants Go to participate in the same graph, cache and CI as the TypeScript side, without maintaining a hand-written task configuration for every Go project. It does not suit a Go-only team with no Nx in the picture, and it does not suit a repository that is still deciding on its build tooling. Verify first that the Nx version you run is in the supported range for the nx-go version you take, since the compatibility table is explicit and the plugin tracks Nx releases, and confirm that the Go version on the machine is a stable one, since only stable versions are tested.

Frequently asked questions

How do I add Go support to an Nx workspace?

Run nx add @nx-go/nx-go in an existing workspace, or create a new one with npx create-nx-workspace go-workspace --preset=@nx-go/nx-go. You need a stable version of Go installed on your machine, and there is nothing else to install.

What does nx-go use to build and test Go projects?

The official Go commands, run in the background with no external dependency. The plugin ships executors for build, generate, lint, serve, serve-air, test and tidy, and it also infers tasks automatically for any project that has a go.mod.

What is the convert-to-one-mod generator for?

The plugin configures a multi-module Go workspace by default, so each Nx project maps to a Go module. If you do not want that, the convert-to-one-mod generator switches you to a single module, and the documentation states that generators will automatically adapt to your configuration.

Which Nx versions does nx-go support?

The compatibility table shows nx-go 4.x supporting Nx 20.x to 23.x, and nx-go 3.x supporting Nx 17.x to 20.x, with the 2.x and 1.x rows struck through as no longer maintained.

How do I upgrade nx-go in an existing workspace?

Run nx migrate @nx-go/nx-go, which moves the package version and rewrites the workspace configuration as part of the Nx migration process, so the change to nx.json and project files belongs in a branch where the diff can be read.

Official sources

  1. License: MIT
  2. nx-go/nx-go on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nx-go-nx-go.svg)](https://hysenlabs.com/projects/nx-go-nx-go)

Was this useful?