CLI tool
gookit/goutil avatar
gookit/goutil

gookit/goutil: a 900+ function Go utility toolkit and when to skip it

Project brief: Helper Utils(900+): int, byte, string, array/slice, map, struct, dump, convert/format, error, web/http, cli/flag, OS/ENV, filesystem, system, test/assert, time and more. Go Map .

2,361 stars200 forksGoMIT

At a glance

What is it?
goutil collects small helpers for slices, strings, maps, structs, errors, files, ENV and CLI flags into one MIT-licensed module. The value is convenience; the cost is a large dependency surface in a language that already ships a broad standard library.
Who is it for?
Adopt goutil when you want a single import path for everyday slice, string, map, struct, error and filesystem helpers, and when the transitive dependencies (golang.org/x/sync, golang.org/x/sys, golang.org/x/term, golang.org/x/text) are acceptable in your module graph. Skip it if you only need one or two helpers or if you cannot take new dependencies.
Can I use it commercially?
Yes. MIT 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 17 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 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What goutil actually solves, and for whom

Go's standard library is deliberately small in places. Checking whether a slice contains a value, converting []string to []int64, getting a nested map value by dot path, printing a struct with readable wrapping, formatting a time as Y-m-d H:i:s: each of these is a few lines you end up writing again in every project. goutil is a collection of those few lines, packaged as one module with a stable import path, github.com/gookit/goutil.

The README describes it as a "Useful utils(900+) package for the Go" and lists packages by domain: arrutil, byteutil, maputil, mathutil, reflects, structs, strutil, sysutil, cliutil, envutil, fsutil and jsonutil as the basic set, plus dump, errorx, assert, testutil and fakeobj for debugging and tests, and cflag, ccolor, timex, httpreq and syncs as extras. The audience is Go developers who write application code, services or CLI tools and would rather call arrutil.Contains than maintain their own helper file. It is not a framework, not a web router, and not a replacement for the standard library. It sits underneath your code and does small jobs.

The repository layout matches that claim. Each package is a top-level directory (arrutil/, strutil/, fsutil/, timex/, x/), and the root package goutil.go re-exports a small set of the most common functions such as IsEmpty, IsEqual, Contains, String, Int, Int64 and Uint. So you can import the root for the common cases and drop to a subpackage when you need something specific.

How the packages are organised and how a call flows

There is no runtime engine here. goutil is a library of functions, and the architecture is the directory tree. The root package goutil.go, conv.go and func.go hold the top-level convenience API. Everything else lives in a subpackage named after its data type or concern.

A typical call chain is shallow: your code calls arrutil.IntsHas([]int{2, 4, 5}, 2), which the README documents as returning true. That function is declared in arrutil/check.go as func IntsHas[T comdef.Integer](ints []T, val T) bool. The constraint comdef.Integer comes from the comdef package in the same repository, which exists so that the generic helpers can be shared across packages without circular imports. Similarly SliceHas is constrained by comdef.ScalarType. The README does not print the body of comdef, so the exact set of types behind ScalarType and Integer is something you confirm on pkg.go.dev rather than in the README.

Some packages are stateful rather than pure functions. byteutil/buffer.go exposes NewBuffer() *Buffer, a bytes buffer wrapper. syncs provides synchronization primitives. httpreq wraps http.Client. errorx provides an error type that carries a stack trace and can wrap another error. The dump package prints values and, according to the README, wraps each element of a slice or map and displays the call location, which is why it is useful in tests and debugging rather than in production logging paths.

Installing goutil and a first real use

The README gives one install command. The module requires Go 1.19 per go.mod, so a toolchain at or above that version is the baseline. Run this inside your module directory:

bash
go get github.com/gookit/goutil

After that, the root package is importable as github.com/gookit/goutil. The README's usage example exercises emptiness checks, equality across mixed types, containment across a string, a slice and a map key, and type conversion. The README shows these calls directly:

go
// github.com/gookit/goutil
is.True(goutil.IsEmpty(nil))
is.False(goutil.IsEmpty("abc"))

is.True(goutil.IsEqual("a", "a"))
is.True(goutil.IsEqual([]string{"a"}, []string{"a"}))
is.True(goutil.IsEqual(23, 23))

is.True(goutil.Contains("abc", "a"))
is.True(goutil.Contains([]string{"abc", "def"}, "abc"))
is.True(goutil.Contains(map[int]string{2: "abc", 4: "def"}, 4))

// convert type
str = goutil.String(23) // "23"
iVal = goutil.Int("-2") // 2
i64Val = goutil.Int64("-2") // -2
u64Val = goutil.Uint("2") // 2

When you need a specific helper, import the subpackage directly rather than the root. The README documents arrutil for slice checks and conversions with these examples:

go
arrutil.IntsHas([]int{2, 4, 5}, 2) // True
arrutil.Int64sHas([]int64{2, 4, 5}, 2) // True
arrutil.StringsHas([]string{"a", "b"}, "a") // True

// list and val interface{}
arrutil.Contains(list, val)
arrutil.Contains([]uint32{9, 2, 3}, 9) // True
go
ints, err := arrutil.ToInt64s([]string{"1", "2"}) // ints: []int64{1, 2}
ss, err := arrutil.ToStrings([]int{1, 2}) // ss: []string{"1", "2"}

For debugging, the README shows dump.Print(somevar, somevar2, ...) as the entry point, and notes that nested slices and maps are wrapped per element with the call location shown. The README does not document a configuration file, environment variables or global options for dump; it is a function call, not a service.

Where goutil is the wrong tool

The first limitation is surface area. A module described as 900+ functions across roughly two dozen packages means that adopting it for one helper pulls in a namespace you did not audit. Go's module system only compiles the packages you import, so the binary cost is bounded by your imports, but the review cost is not: you are trusting code you did not read. If you need exactly one function, writing it yourself is often cheaper than adding a dependency.

The second limitation is version churn. The recent release history shows v0.7.5, v0.7.6 and v0.8.0 within about two months, and the major version is still 0. Under Go module semantics a v0.x module makes no compatibility promise, so a minor bump can change exported behaviour. The README does not document a deprecation policy or a compatibility guarantee, so pin the version in go.mod and read the release notes before upgrading.

The third limitation is the generic constraints. Several arrutil functions are constrained by types from comdef, and the README's function listing is truncated mid-signature. If you rely on a generic helper with a custom named type, confirm the constraint accepts it. This is a documentation gap, not a runtime failure, but it costs time.

Finally, goutil is not a substitute for domain libraries. It does not parse YAML, does not provide an ORM, and does not route HTTP requests. httpreq wraps http.Client for convenience; it is not a retry or circuit-breaking framework. If your need is a full HTTP client with policy, look elsewhere.

goutil against the standard library and samber/lo

The honest comparison is with the standard library first. Since Go 1.21, the slices and maps packages cover generic search, sorting and cloning. If you are on a modern toolchain and your needs are Contains, Index or Sort, the standard library wins on dependency count and on being reviewed by the Go team. goutil's advantage is breadth: the standard library has no ToInt64s, no dot-path map lookup, no dump printer, no cflag wrapper around flag.FlagSet, no timex with DayStart and DayAgo, no fakeobj for fs.File in tests. Those are the reasons to add it.

The second comparison is with samber/lo, a popular generic functional utility library for Go. The difference in approach is scope and style: lo concentrates on generic slice, map and channel operations in a functional idiom (Map, Filter, Reduce, Uniq), while goutil spreads across concrete concerns including filesystem, environment, process, CLI flags, error wrapping and test assertions. If your codebase wants functional pipelines over collections, lo's API is narrower and easier to hold in your head. If you want one module for slice checks, string formatting, filesystem helpers and a CLI flag wrapper, goutil covers more ground. Many projects end up with neither and write the ten helpers they actually use.

Maintenance, upgrade cost and the MIT licence

The repository is not archived. The last push was on 2026-06-25, which is the same timestamp as the v0.8.0 release, so the most recent visible activity is that release. Releases are frequent enough that upgrades are a recurring task rather than a yearly one: v0.7.5, v0.7.6 and v0.8.0 all landed between 2026-05-04 and 2026-06-25. Budget for reading release notes when you bump the version, and note that the 0.x major version means the project has not committed to API stability.

Upgrade cost is mostly mechanical. The module has four direct dependencies: golang.org/x/sync, golang.org/x/sys, golang.org/x/term and golang.org/x/text. Those are maintained by the Go team and are common in Go module graphs already, so the transitive footprint is modest. The go.mod declares go 1.19, which is the floor for consumers.

The licence is MIT, per the repository metadata and the LICENSE file at the root. MIT is permissive: it allows use in closed-source products provided the copyright notice and permission notice are retained. That is a statement about the licence text, not legal advice; have your own counsel review attribution requirements if you redistribute. One practical consequence of MIT is that there is no copyleft obligation on your own code, which is usually why teams pick it.

Editorial conclusion

Adopt goutil when you want a single import path for everyday slice, string, map, struct, error and filesystem helpers, and when the transitive dependencies (golang.org/x/sync, golang.org/x/sys, golang.org/x/term, golang.org/x/text) are acceptable in your module graph. Skip it if you only need one or two helpers or if you cannot take new dependencies. Before committing, verify the exact generic signatures in arrutil and comdef against pkg.go.dev, since some README snippets are truncated and the exported types behind constraints like ScalarType are not shown.

Frequently asked questions

How do I install gookit/goutil?

Run go get github.com/gookit/goutil inside your module directory. The module's go.mod declares go 1.19, so your toolchain needs to be at least that version.

Which Go version does gookit/goutil require?

The go.mod file in the repository declares go 1.19. Its direct dependencies are golang.org/x/sync, golang.org/x/sys, golang.org/x/term and golang.org/x/text.

What is the licence for gookit/goutil?

The repository is MIT licensed, with a LICENSE file at the root. The README does not add any licence restrictions beyond that.

Can I use a single helper from gookit/goutil without importing everything?

Yes. The library is split into subpackages such as arrutil, strutil, fsutil and maputil, so you can import only the one you need instead of the root package.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
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/gookit-goutil.svg)](https://hysenlabs.com/projects/gookit-goutil)