[RFC] Native Go support #14033
Replies: 2 comments 10 replies
|
First impression: nice! One thing I need to figure out first before I can adopt it more widely for testing is that I now need a Docker image that has both node and go installed for all steps since Turbo will always need both. Second thought: A migration/best practice guide/skill would be nice, like currently I have dummy package.jsons everywhere. What should we do instead/with makefiles? |
|
Tried this on a mixed npm and Enabling the flag makes the toolchain a hard requirement for every runAny $ env PATH=/path/without/go turbo run build --filter=web
x Go is required for experimental Go workspaces, but `go` was not found
| while running `go work edit -json`. Install Go 1.22 or newer and ensure
| `go` is on PATH.
Nothing inside Turborepo opts out. This reads like a property of all three language flags. Reading The synthesized
|

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Turborepo now experimentally supports Go: https://turborepo.dev/docs/guides/tools/go
Motivation
One of the longest-standing, open requests in Turborepo is to support more language toolchains than JavaScript: #683
This RFC introduces Go as a natively supported language in Turborepo, using Go’s built-in module and workspace tooling.
What drives this ask?
Monorepos can be large, and don’t have to contain just one language. It is common to run a monorepo with many languages and language toolchains in it. However, this comes with the complexity of managing workflows across all of these toolchains. Each language creates its own partition within the monorepo, and it becomes complicated to manage the interactions between each language’s domain.
Turborepo users see what Turborepo offers for simplifying their JavaScript/TypeScript workflows, and want the same for all languages in their repository. The canonical ask becomes “How do I make
turbo run lintrun all the linters for all my languages?”Without native support, taking Turborepo across toolchains meant porting conventions of JavaScript toolchains onto your other languages. You’d have to put a
package.jsoninto your Go modules for Turborepo to add them to your Package Graph, for example. A more verbose description of this approach can be found in our multi-language support documentation.With this new experimental support, those JavaScript wrappers are no longer necessary for Go workspaces. Turborepo discovers modules from a repository-root
go.work, reads their module dependencies, and adds them to the same Package Graph as your JavaScript/TypeScript packages.Why Go?
Go is a natural next step in expanding Turborepo’s native language support beyond JavaScript/TypeScript and Rust.
A repository might contain a TypeScript frontend, Go services, and shared Go libraries. These projects use different toolchains, but developers still need a consistent way to build, test, and check their work.
Go already provides module management, workspaces, and standard commands for common tasks. Turborepo can build on those conventions rather than asking users to recreate them through JavaScript tooling.
The goal is not to replace Go’s tooling. It is to make Go projects participate naturally in repository-wide workflows.
What about standalone Go workspaces?
Standalone Go workspaces are supported, too. A repository does not need JavaScript application code to benefit from native Go workspace support.
Go already has strong build and test caching. Turborepo should complement those capabilities, not replace them. Its value is in coordinating tasks across modules, selecting affected modules and their dependents, and sharing cacheable task results across developer and CI machines.
Go’s internal build and module caches remain Go’s responsibility.
Enabling for your Turborepo
1 . Install a Turborepo release that includes experimental Go workspace support.
2. Make Go 1.22 or newer available as
goon your PATH.3. Add a
go.workat the repository root if you do not have one already, with use directives identifying your Go modules. Each member must have ago.modwith a module path.4. Enable the feature using its Future Flag in turbo.json:
{ "futureFlags": { "experimentalGoWorkspaces": true } }For more information on getting started, please see the Go guide.
Usage
Using Turborepo for Go should feel familiar to using it for JavaScript/TypeScript.
• Run
turbo run buildto build your Go modules. Modules with exactly one runnable main package produce a binary in dist/.• Run
turbo run testto rungo test ./...in your modules.• Run
turbo run lintto rungo vet ./....• Run
turbo run formatto rungo fmt ./....• Run
turbo run devto run modules with exactly one runnable main package.You can also filter tasks using a module’s path:
turbo run test --filter=example.com/acme/apiTo learn more about built-in tasks, command overrides, caching, and
workspace-wide execution, please see the Go guide.
What feedback is the Turborepo team looking for?
In short, everything. We want to hear about:
• UX improvements
• Your experience in a standalone Go workspace
• Your experience in a mixed-language repository, such as a TypeScript frontend with Go services
• Whether the built-in tasks match your Go workflows
• Caching concerns, including cross-compilation and CGO
• Anything else?
All reactions