What’s New in Go 1.27
What’s New in Go 1.27
Go 1.27 shipped in August 2026 (release notes). The compatibility promise still holds: almost all existing programs compile and run. This chapter is the map of what actually changed—language, go command, runtime, and the standard library—so the rest of this book can assume 1.27 as the baseline.
Pin new modules with go 1.27 (and toolchain go1.27.1 or later when you want a specific compiler). Go 1.25 is out of support as of this release.
Language
Generic methods
A method may declare its own type parameters. That is different from a method on a generic type (func (s *Stack[T]) Push(T)), which has existed since 1.18.
The standard library uses this on math/rand/v2: (*Rand).N[Int intType](n Int) Int.
Save as main.go:
package main
import (
"fmt"
"math/rand/v2"
)
func main() {
r := rand.New(rand.NewPCG(1, 2))
fmt.Println(r.N(10))
fmt.Println(r.N(int64(1_000)))
}go run .Output is deterministic for this PCG seed:
7
616
Limits: interface methods cannot declare type parameters, and a generic method cannot implement an interface method. Prefer a package-level generic function when the operation is not namespaced on a type. See Methods and Receivers and Why Generics Matter.
Promoted field keys in struct literals
A key in a composite literal may be any valid field selector, not only a top-level field name. You can set a promoted embedded field without nesting another literal.
package main
import "fmt"
type Address struct {
City string
}
type Employee struct {
Address
Title string
}
func main() {
e := Employee{
City: "Lisbon",
Title: "engineer",
}
fmt.Println(e.City, e.Title)
}Lisbon engineer
Ambiguous promotions still need the nested form. Details: Structs.
Function type inference
Inference now applies in every assignment-shaped context: composite literals, conversions, and channel sends, not only direct calls. See Generic Functions.
go command and tools
| Change | What you do |
|---|---|
go test runs the stdversion vet check by default |
Using a stdlib symbol newer than your go directive is now a test failure |
go test -json |
"Action":"output" events may include "OutputType" (error, error-continue, frame) |
go doc pkg@version |
Docs for a specific module version |
go doc -ex |
List executable examples; go doc bytes.ExampleBuffer prints the example source |
go fix modernizers |
New: atomictypes, embedlit, slicesbackward, unsafefuncs. waitgroup is now waitgroupgo. fmtappendf was removed |
go mod tidy (go 1.27+) |
Merges extra require blocks into the standard direct then indirect layout |
bzr |
The go command no longer fetches Bazaar-hosted modules |
GODEBUG in go.mod / //go:debug |
Removed settings are accepted only at their final default; an old value fails the build |
go tool trace -http=:6060 |
Listens on localhost only (same as pprof). Use -http=0.0.0.0:6060 to bind all interfaces |
Response files (@file) |
compile, link, asm, cgo, cover, pack accept GCC-compatible response files |
go test ./... # includes stdversion
go doc encoding/json/v2
go doc -ex bytes.Buffer
go fix -modernize ./...
go mod tidyRuntime
- Size-specialized malloc for some objects under 80 bytes (up to ~30% cheaper those allocs, ~1% in allocation-heavy programs, ~60 KB extra binary). Opt out:
GOEXPERIMENT=nosizespecializedmalloc(expected gone in 1.28). goroutineleakpprof profile is generally available (/debug/pprof/goroutineleak). Thegoroutineleakprofileexperiment flag is deleted. See Goroutine leaks.- Tracebacks for
go 1.27modules include pprof goroutine labels in the header. Disable withGODEBUG=tracebacklabels=0. asynctimerchanis gone. Channels from packagetimeare always unbuffered. See Time.- Closures get simpler symbol names; do not compare function pointers for identity.
Standard library
encoding/json/v2 (GA)
encoding/json is now backed by the v2 engine. Behavior of the v1 API is preserved; error text may differ; unmarshal is faster. New code that wants stricter defaults (reject invalid UTF-8, reject duplicate names) should import encoding/json/v2. Emergency rollback: GOEXPERIMENT=nojsonv2 (temporary). See JSON.
uuid
Stdlib uuid generates and parses UUIDs. Prefer it over github.com/google/uuid for new IDs.
package main
import (
"fmt"
"uuid"
)
func main() {
id := uuid.New()
fmt.Println(id)
parsed, err := uuid.Parse(id.String())
if err != nil {
panic(err)
}
fmt.Println(parsed == id)
}crypto/mldsa
Post-quantum ML-DSA (FIPS 204), with crypto/x509 and crypto/tls (MLDSA44 / 65 / 87). Opt-in for new PKI, not a silent swap for existing ECDSA certs.
Experimental simd / simd/archsimd
Portable vector types (Int8s, Float32s, …) plus architecture-specific ops (amd64, arm64 Neon, Wasm). Enable with GOEXPERIMENT=simd. Not production-stable.
Other library notes
| Package | 1.27 |
|---|---|
bytes / strings |
CutLast |
testing/synctest |
Sleep (sleep + wait) |
net/http/httptest |
NewTestServer (in-memory, synctest-safe) |
net/url |
URL.Clone, Values.Clone |
math/rand/v2 |
(*Rand).N generic method |
net/http |
HTTP/2 client priority (RFC 9218); Server.MaxHeaderValueCount; HTTP/1 body drain on close |
crypto/tls |
ML-DSA; MLKEM1024; ConnectionState.LocalCertificate; several old tls* GODEBUGs removed |
unicode |
Unicode 17 |
compress/flate |
Faster; encoded bytes may differ (also zip/gzip/zlib/png) |
package main
import (
"fmt"
"strings"
)
func main() {
dir, file, ok := strings.CutLast("desk/shift/ticket.txt", "/")
fmt.Println(dir, file, ok)
}desk/shift ticket.txt true
Ports
- macOS: 13 Ventura or later. Support for older releases is gone.
- linux/ppc64 (big-endian): ELFv2 ABI; cgo, PIE, and external linking now work with an ELFv2 runtime.
Compiler / linker
Relative //line filenames resolve against the file that contains the directive. On macOS the linker accepts -macos / -macsdk for LC_BUILD_VERSION.
What to do in this book next
- Learning path — upgrade checklist.
- Installing — 1.27.1 tarball / macOS 13.
- Core commands and vet/docs.
- JSON, uuid/crypto.
Official source: Go 1.27 Release Notes.