lo
A Lodash-style Go library built on Go 1.18+ generics for working with slices, maps, channels, and functions.
Repository Health
Technical Analysis
samber/lo brings Lodash-style ergonomics to Go through Go 1.18+ generics, filling a gap the standard library’s slices and maps packages leave open. It packages dozens of type-safe helpers for filtering, mapping, grouping, and transforming slices, maps, and channels, plus utilities for tuples, retries, debouncing, and safe error handling, all without pulling in any dependency outside the Go standard library.
Beyond the core package, lo ships companion subpackages (parallel, mutable, it) for parallel execution, in-place slice mutation, and Go 1.23+ iterator-based helpers, letting teams opt into more advanced patterns without bloating the base API.
What You Get
- Dozens of generic slice functions (Filter, Map, Reduce, GroupBy, Chunk, Uniq, Flatten, and more) that work on any named slice type.
- Map utilities (KeyBy, PickBy, MapValues, Entries) and Tuple2-Tuple9 types with Unpack() for structured returns.
- Error-safe transform variants (FilterErr, MapErr) and a Try/TryOr/Attempt/Must family for controlled error handling.
- Retry-with-backoff, Debounce, and Async helpers for common resilience and concurrency patterns.
- Companion subpackages (parallel, mutable, it) for parallel execution, in-place mutation, and Go 1.23+ range-over-func iterators.
Common Use Cases
- Replacing manual for-loops with declarative slice and map transformations.
- Propagating the first error from a batch transform instead of silently continuing past it.
- Wrapping flaky network or database calls with retry-and-backoff logic.
- Choosing parallel, in-place, or iterator-based variants of the same operation to tune performance.
Under The Hood
Architecture
lo is a flat, single-package library organized by domain-of-function across files (slice.go, map.go, find.go, tuples.go, errors.go, retry.go, concurrency.go, channel.go, condition.go, math.go, string.go, time.go, type_manipulation.go) rather than by internal layering — each file groups related generic functions that operate directly on caller-supplied slices/maps with no shared internal state, so every exported function is a pure, stateless transform taking a collection and a callback and returning a new collection. Supplementary concerns are split into separate importable subpackages under the same module (parallel/ for goroutine-per-element parallel Map, mutable/ for in-place slice ops that mutate the input instead of allocating, it/ for Go 1.23+ range-over-func iterator variants, exp/simd/ gated behind Go 1.26 SIMD build tags), which keeps the core package’s API surface small while letting callers opt into different performance and mutation tradeoffs; internal/ hosts constraints and small helpers not part of the public contract. If a core convention like the Tuple2..Tuple9 types or the predicate signature func(item T, index int) bool changed, essentially every file in the package would need updating since it’s applied uniformly.
Tech Stack
Pure Go 1.18+ using generics, with zero runtime dependencies. The only dependencies declared in go.mod are dev/test-only — testify for assertions and go.uber.org/goleak for goroutine-leak detection, with golang.org/x/text and go-funk excluded from releases per the module’s own comment. Build/test runs through a Makefile wrapping go build and go test -race; CI (.github/workflows/test.yml) runs the full Go version matrix from 1.18 through “stable” plus a 1.26 SIMD experiment, and .golangci.yml enables an extensive linter set (govet, staticcheck, errcheck, gocritic, gocyclo, revive, exhaustive, forcetypeassert, nestif, and more). A separate Docusaurus/TypeScript documentation site lives under docs/, independent of the Go library itself.
Code Quality
Every source file has a matching *_test.go with table/subtest structure using testify’s assert and t.Parallel() throughout, plus _example_test.go files providing runnable godoc examples referenced by “Play:” links in doc comments — extensive test coverage rather than a token suite. Error handling is explicit and typed: functions that can fail return (T, error) instead of panicking (MapErr, FilterErr, the Try/TryOr/Attempt family), reserving panics for the opt-in Must variants. Naming is consistent, idiomatic Go, and types.go/constraints.go centralize generic constraints reused across files. CI enforces the version matrix plus a strict golangci-lint ruleset, and goleak checks catch leaked goroutines in concurrency-related tests.
What Makes It Unique
lo’s core value is bringing Lodash-equivalent ergonomics to Go through generics in a way the standard library’s slices/maps packages don’t fully cover — grouping, chunking, sliding windows, partitioning, tuple types with Unpack(), typed Try/Must error helpers, and a debounce implementation aren’t in stdlib. It’s a well-executed adaptation of an established pattern rather than a novel abstraction: every function is documented with a Go Playground link for low-friction trial, and the split subpackages (parallel/mutable/it) let adopters choose eager-parallel, in-place, or lazy-iterator variants of the same operations without forking the API — a thoughtful but incremental developer-experience choice rather than groundbreaking innovation.
Used by 11 apps in this directory
SpiceDB
Authentication · Databases · Security
An open source, Google Zanzibar-inspired authorization database that models permissions as relationships and evaluates fine-grained access checks at massive scale with single-digit millisecond latency.
Tyk API Gateway
Developer Tools · Devops
Cloud-native, high-performance open-source API gateway for REST, GraphQL, gRPC, and TCP — built in Go since 2014 with no feature lockout.