Skip to content
Frameworks Article

Go Finally Commits to Standard Library Collections

A working group of Go's most senior engineers targets generic sets, ordered maps, and a sane heap for Go 1.28.

Rachel Goldstein
Rachel Goldstein
Dev Tools Editor · Jul 31, 2026 · 4 min read
Go Finally Commits to Standard Library Collections

Four years after generics shipped, the Go team has finally said the quiet part out loud: the standard library is getting real collection types. An umbrella proposal filed this week by Alan Donovan — golang/go#80590 — lays out the roadmap from the Go Collections working group, a late-2025 assembly of some of the most senior names in the project: Donovan, Jonathan Amsterdam, Robert Griesemer, Daniel Martí, Roger Peppe, Keith Randall, and Ian Lance Taylor. The target is Go 1.28, which puts generic sets, ordered maps, and a usable heap in the standard library around February 2027.

That's a long runway, but the direction is now unambiguous. If you maintain a third-party set library, start writing your deprecation notice.

Why it took this long

Go 1.18 landed generics in March 2022, and the obvious question — "so where's set.Set?" — has been open ever since. A community proposal for a generic set type has been sitting in the issue tracker since September 2024, and discussions go back to 2021. The official answer was always some variant of "wait": first for experience with generics in golang.org/x/exp, then for iterators.

That second wait turned out to be the load-bearing one. Go 1.23's range-over-func iterators (August 2024) gave library-defined types something they never had before: a way to participate in for range like built-in maps and slices do. The proposal is explicit that this is what changed the calculus — with iter.Seq[E] and iter.Seq2[K,V], a stdlib Set can feel native rather than bolted on. Anyone who used container/list in anger knows what bolted-on feels like.

The last prerequisite ships next month. Go 1.27, due in August 2026, adds maphash.Hasher[T] — a small interface pairing a Hash method with an Equal method, plus a ComparableHasher default for types where == does the right thing. It's the contract every future hash-based structure in the stdlib will build on.

What's actually in the box

The Go 1.28 slate, per the umbrella issue:

  • container/set.Set[E] — the canonical set for comparable types, and the piece with the cleverest design decision: it's transparently defined in terms of map[E]struct{}. You can assign between set.Set[string] and a plain map[string]struct{}, call len() on it, range over it, even do _, ok := s[elem]. Every codebase carrying hand-rolled map[string]struct{} boilerplate gets a migration path that's assignment-compatible, not rewrite-the-world.
  • container/hash.Map[K,V] and hash.Set[E] — hash tables that take a custom maphash.Hasher, for keys that aren't comparable (slices, say) or where == is wrong. The motivating example is go/types, where two types.Type values need types.Identical semantics, not pointer equality. Case-insensitive string keys are the everyday version of the same problem.
  • container/ordered.Map[K,V] — a sorted map backed by a binary tree.
  • container/heap/v2.Heap — a generic replacement for the current container/heap, whose implement-five-methods-including-sort.Interface API has been a rite of passage nobody enjoys. This alone will delete a lot of ceremonial Push/Pop code from priority-queue implementations.
  • container/mapset — helper functions for code staying on raw map-based sets.

Insertion-ordered maps and stacks are named as likely follow-ups. Amusingly, the working group says it prefers the term "collection" over "container" to avoid Linux-container confusion — but the packages live in container/ anyway, because that tree already exists.

The restraint is the feature

Two design calls stand out as very Go. First, mutation methods report what happened: Set and Delete return the previous value and a boolean, so you can distinguish "was absent" from "was the zero value" without a second lookup. Second, set operations come in both functional flavors (Union returns a fresh set) and allocation-conscious mutating variants (UnionWith modifies the receiver) — a concession to the reality that convenience APIs get banned from hot paths.

The most consequential decision, though, is a deferral. The group sketched abstract constraint interfaces — the machinery that would let you write one generic function over any set implementation — and then declined to export them until there's real-world experience. That's the lesson of a decade of premature abstraction in other languages' collection hierarchies, applied preemptively. Java's Collection interface is 28 years of accumulated regret; Go is opting to ship concrete types first and unify later, if ever.

The group is also explicit that it's prioritizing correctness and simplicity over constant-factor performance. Read that as a survival notice for the ecosystem's specialized structures: if you're on google/btree or a Swiss-table variant for throughput reasons, the stdlib's ordered.Map probably won't dethrone it. What dies is the long tail of general-purpose set libraries — deckarep/golang-set and its many cousins — whose entire reason to exist was a gap that's now closing.

What to do with this now

Nothing ships tomorrow, and that's fine. The practical sequence: when Go 1.27 lands in August, look at maphash.Hasher if you maintain any custom hashed structure — implementing it now means you're compatible with container/hash the day it exists. Hold off on adopting new third-party collection dependencies; the switching cost in eighteen months isn't worth it. And if you have opinions about API details — method naming, what ordered.Map should guarantee about iteration cost — the constituent proposals are open and this working group has a track record of actually incorporating feedback.

The slices and maps packages followed exactly this arc: x/exp incubation, proposal review, stdlib promotion, and near-universal adoption within two release cycles. Collections are a bigger surface area, but the process and the people are the same. This isn't a trial balloon. It's the standard library Go should have had in 2022, arriving on Go time — late, deliberate, and probably right.

Sources & further reading

  1. proposal: container/...: generic collection types — github.com
  2. proposal: container/set: new package to provide a generic set type — github.com
  3. Go 1.27 Release Notes (draft) — go.dev
  4. A plan to bring generic collections to Go 1.28 — golangweekly.com
Rachel Goldstein
Written by
Rachel Goldstein · Dev Tools Editor

Rachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.

Discussion 5

Join the discussion

Sign in or create an account to comment and vote.

Priya Nair @k8s_whisperer · 5 hours ago

finally, no more rolling my own sorted map helpers. 1.28 is forever away but at least it's official

Emma Lindgren @excited_emma · 11 hours ago

okay this is actually huge, but i'm skeptical about the 1.28 timeline. two years for sets, ordered maps, and a heap feels wildly optimistic given how long it took just to get generics stabilized. feels like they're setting themselves up for another delay cycle.

Greg Tanaka @golang_greg · 13 hours ago

honestly the fact this took four years after generics is funny. anyway, finally won't have to vendor a map library

Dana Reyes @hypewatch_dana · 7 hours ago

yeah, the wait was rough, but i'm cautious about the 1.28 timeline. we migrated off a vendored ordered map last year when we thought this was coming sooner, and the performance characteristics ended up being totally different from what we expected in our hot path. really hoping they nail the api so we're not doing this dance again.

Noor Haddad @indiehacker_noor · 1 hour ago

yeah four years is wild but honestly shipping standard collection types that everyone agrees on is harder than it looks. curious if this finally kills off the three competing third-party map libs i've got pinned

Related Reading