CLI tool
rogpeppe/go-internal avatar
rogpeppe/go-internal

go-internal: the Go toolchain internals you are allowed to import

Selected Go-internal packages factored out from the standard library

993 stars93 forksGoBSD-3-Clause

At a glance

What is it?
go-internal is a BSD-3-Clause Go module that publishes an opinionated selection of internal packages from the Go toolchain, above all testscript, a shell-like test environment for command line tools. It exists because those packages live under internal/ and cannot be imported, and one of its packages is already scheduled to be replaced by an upstream one.
Who is it for?
go-internal suits Go developers who need the script based test harness that the Go project itself uses to test the go command, or the small utilities that came with it, and who want that code with a public import path and a tagged release.
Can I use it commercially?
Yes. BSD-3-Clause 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 18 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why Go tool internals were republished under a public path

Go hides its own implementation packages under internal directories, which means nobody outside the Go project can import them. That rule is deliberate, and it also blocks a large class of tooling that would be useful outside. go-internal exists to move a selected, opinionated subset of that code into a public module. The README describes the contents as mostly packages and testing code from within the Go tool implementation, and the module is primarily maintained by long time Go contributors who also maintain CUE, which is itself written in Go and relies on several of the packages here. That provenance is the point. A vendored copy of the same code would drift; a module maintained by people who work on the Go project and on a downstream consumer of it has a maintenance model. The audience is Go developers building command line tools, module tooling and test harnesses, who need pieces the standard library keeps to itself.

testscript runs shell-like scripts and checks their output

testscript is the package most people come for. It provides a shell-like test environment tuned for testing Go command line programs, and it was extracted from the core Go team's own internal testscript package, the one at cmd/go/internal/script, which is used heavily to test the go command itself. The model is simple: a test is a script with a set of files, the script runs commands, and the harness asserts on what happened. The package supports patterns for checking stderr and stdout, command pass and fail assertions, and it integrates with go test including coverage support. Inputs and expected output files use the txtar text archive format, the same format the Go playground uses. Two features make it pleasant in practice. Golden files can be updated automatically through the package's parameters, so an expected-output change is a flag rather than a manual edit, and there is built-in support for Go concepts such as build tags, which matters when the behaviour under test depends on the build configuration. A companion command under cmd/testscript runs standalone scripts with files embedded in txtar format.

txtar is scheduled to be replaced by the upstream copy

One entry in the package list carries a warning, and it is the kind of warning that should influence an adoption decision. The README says that most users of txtar should use golang.org/x/tools/txtar instead, and that the package in this module will be replaced by it once golang/go issue 59264 is fixed. In other words, the txtar package here is a stopgap that is scheduled to disappear, not a package to build a long lived dependency on. The archive format itself is not going anywhere, since the Go playground and the testscript format both use it, but the implementation is expected to move to the x/tools tree where it lives alongside other Go tooling. The migration targets are:

text
https://pkg.go.dev/golang.org/x/tools/txtar
https://github.com/golang/go/issues/59264

The other packages in the list are not marked for replacement. goproxytest is a GOPROXY implementation built for test use, gotooltest lets a test script use the Go tool itself, imports lists known architectures and operating systems and supports reading import statements, par does work in parallel, and testenv reports information about the current testing environment. If your dependency on this module is txtar alone, the advice is simple: take the upstream package instead.

A module with Go 1.25 and three golang.org/x dependencies

The module definition is short and states the floor plainly. Its go.mod names the module path, declares the Go language version and requires three dependencies from the golang.org/x trees:

go
module github.com/rogpeppe/go-internal

go 1.25

require (
	golang.org/x/mod v0.21.0
	golang.org/x/sys v0.26.0
	golang.org/x/tools v0.26.0
)

That means a project importing this module also pulls in those three, which is a real cost to weigh for a library that some people adopt for a single helper function. The repository directory listing is also wider than the seven packages the README names. Alongside goproxytest, gotooltest, imports, par, testenv, testscript and txtar, the tree contains cache, diff, dirhash, fmtsort, lockedfile, modfile, module, renameio, semver, an internal directory, a cmd directory and a top level diff directory. The naming pattern is worth noticing, since several of those names collide with standard library or x/tools package names, which is another reason to import them under the full module path rather than assuming an unqualified name is unambiguous.

The alternative to testscript is writing the assertions yourself

The obvious alternative to a script based harness is plain Go test code that runs a command with os/exec and compares the output to a string. That approach has one advantage, which is that it needs no dependency, and several costs that show up as soon as a test has more than one case. Setting up a temporary directory, writing input files, setting environment variables and asserting on the exit status all have to be written by hand, and the assertions become brittle string comparisons unless care is taken. The testscript approach moves the setup into the script, where the same file layout is described in the archive and reused across cases, and where checking output is a pattern match rather than a hand written equality on a captured buffer. The golden file support closes the loop, since expected output is a file that the harness can rewrite. For a team already using go test and comfortable with a text format, the switch is mostly a matter of rewriting the test body, and the upstream note in the README about an introduction to test scripts points to a blog series for that transition.

Tagged releases and a discuss-first contribution rule

The project publishes tagged semantic versions, and the recent history shows a steady but not fast cadence: v1.15.0 on 2026-05-28, v1.14.1 on 2025-02-25 and v1.14.0 on 2025-02-24. The last push to the repository was on 2026-10-05, which is more recent than the newest release tag, so development continues between releases rather than stopping at a tag. Imports are pinned by module version in the usual way, and a v1 path means the v1 API is stable in the way Go modules define stability. The contribution rule is worth noting for anyone planning to send a patch: contributions are welcome, but the project asks you to open an issue for discussion first. The licence is BSD-3-Clause, which is the permissive three clause form, and the LICENSE file in the repository holds the full text. Both testscript and txtar were originally created by Russ Cox, which explains why the code carries the Go project's style and testing conventions.

Editorial conclusion

go-internal suits Go developers who need the script based test harness that the Go project itself uses to test the go command, or the small utilities that came with it, and who want that code with a public import path and a tagged release. It does not suit a project that wants txtar, since that package is scheduled to be replaced once the upstream issue is fixed, and it is a poor fit for a team that would rather own a hundred lines of os/exec code than depend on a module maintained outside the Go project. Verify three things before you import it: that the module still targets the Go version your toolchain has, that you are using the version tag you intend since the newest release is v1.15.0 from 2026-05-28, and that the upstream txtar migration has not already landed in your dependency graph. The last push was on 2026-10-05 and the licence is BSD-3-Clause.

Frequently asked questions

What is testscript in the go-internal module?

testscript provides a shell-like test environment tuned for testing Go command line programs, extracted from the core Go team's internal testscript package used to test the go command. It supports patterns for checking stdout and stderr, pass and fail assertions, automatic golden file updates, and it integrates with go test including coverage.

Should I use the txtar package from go-internal or from golang.org/x/tools?

The project states that most users of txtar should use golang.org/x/tools/txtar, and that the copy in this module will be replaced by it once golang/go issue 59264 is fixed. The archive format stays the same, since it is also used by the Go playground.

What Go version does go-internal require?

The go.mod of the module declares go 1.25 and requires golang.org/x/mod v0.21.0, golang.org/x/sys v0.26.0 and golang.org/x/tools v0.26.0, so those three dependencies come with it.

How do I contribute a change to go-internal?

Contributions are welcome, but the project asks that you open an issue for discussion first before sending a patch. The module is primarily maintained by long time Go contributors who also maintain CUE.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. README
  4. Releases
  5. rogpeppe/go-internal on GitHub
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/rogpeppe-go-internal.svg)](https://hysenlabs.com/projects/rogpeppe-go-internal)

Was this useful?