pp: colored pretty printer for Go structs, maps, and slices
Colored pretty printer for Go language
At a glance
- What is it?
- pp is a Go package that wraps fmt-like functions with ANSI color and per-type syntax highlighting, letting a developer call pp.Print() where they would call fmt.Printf and get structured, colored output instead of a flat string. Bold formatting may not render on Windows, and the module requires a recent Go toolchain.
- Who is it for?
- pp is the right choice for Go projects that rely on fmt.Printf for debugging and want syntax-highlighted output without changing the call site significantly. The go.mod requires Go 1.26.0, so any project on an older toolchain needs an upgrade before adding the dependency.
- 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 2 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 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Colored output for Go values where fmt would give you a flat string
Go's standard fmt package formats values with %v or %+v and produces a plain text string, offering no syntax highlighting and no line-by-line layout for nested structs or maps. Tracing a deeply nested value through a wall of fmt output during debugging takes time. pp addresses this by applying ANSI color codes and per-type formatting to the same values, turning them into something closer to what a REPL or a JSON viewer would show.
The package targets developers who want richer debug output without switching to a logging library or restructuring their code. Calls to pp.Print() and pp.Println() are drop-in companions to their fmt counterparts: the function signature is similar, and the difference is that pp produces colored, indented output rather than a compact string. For a map like {"foo": "bar", "hello": "world"}, the output shows each key and value on its own line with each type colored differently.
Importing pp and using its 4 fmt-like functions
The package is available at pkg.go.dev/github.com/k0kubun/pp/v3, and the import path for a Go module is:
import "github.com/k0kubun/pp/v3"Adding that import and running go mod tidy will fetch the dependency. Once imported, calling pp.Print() with any Go value produces colored output to standard output.
m := map[string]string{"foo": "bar", "hello": "world"}
pp.Print(m)4 fmt-like functions are available: pp.Print(), pp.Println(), pp.Sprint(), and pp.Fprintf(). Sprint returns the formatted string rather than writing it. Fprintf writes to any io.Writer rather than to standard output, which is useful for sending formatted output to a file or a buffer during testing. The documentation at pkg.go.dev/github.com/k0kubun/pp/v3 has the full API reference.
pp.Default vs pp.New(): shared configuration versus independent instances
Configuration changes made through pp.Default apply to every call that uses the package-level functions. Disabling color globally, for example, changes the output for every pp.Print() and pp.Println() call in the process.
pp.Default.SetColoringEnabled(false)
pp.Println() // no colorCreating a separate instance with pp.New() lets a different part of the code configure its own printer without affecting the package-level default. A test helper might use a pp.New() instance with SetExportedOnly(true) and SetOmitEmpty(true) to reduce noise, while production debug calls keep the default settings.
mypp := pp.New()
mypp.SetColoringEnabled(false)
mypp.SetExportedOnly(true)
mypp.SetOmitEmpty(true)
mypp.Println()Separating instances matters in larger programs where multiple packages use pp without coordinating. A package that disables color on pp.Default affects every other package using the global functions, so pp.New() is the right choice when isolation is needed. The README lists further configuration options in the PrettyPrinter documentation at pkg.go.dev.
Custom color schemes: 8 foreground colors, background variants, and Bold per type
pp provides a ColorScheme struct where each field names a Go type category: Integer, Float, String, and others. Each field accepts a color flag value, and multiple flags are combined with the bitwise OR operator. A scheme setting Integer to pp.Green | pp.Bold gives integers a bold green color; setting Float to pp.Black | pp.BackgroundWhite | pp.Bold gives floats a bold black foreground on a white background.
scheme := pp.ColorScheme{
Integer: pp.Green | pp.Bold,
Float: pp.Black | pp.BackgroundWhite | pp.Bold,
String: pp.Yellow,
}
pp.Default.SetColorScheme(scheme)8 foreground colors are available: Black, Red, Green, Yellow, Blue, Magenta, Cyan, and White. 8 matching Background variants mirror them, from BackgroundBlack through BackgroundWhite. Bold and NoColor round out the flag set, where NoColor disables color for a specific type. Any foreground can be combined with any background and optionally with Bold, but the README notes that Bold will not work on the Windows platform. Calling pp.ResetColorScheme() restores the default scheme.
go.mod requires Go 1.26.0, and go-colorable handles Windows terminals
The go.mod file at the repository root sets the minimum Go version to 1.26.0, so any project on an older toolchain cannot add this module without upgrading Go. Two direct dependencies are listed: github.com/mattn/go-colorable, which handles color output on Windows terminals, and golang.org/x/text, which handles text processing. Two indirect dependencies round out the chain: github.com/mattn/go-isatty and golang.org/x/sys.
go-colorable exists specifically because Windows terminal color support behaves differently from POSIX terminals. Its presence means the package author has addressed the basic Windows compatibility question, but the README flags bold formatting as a known gap on that platform. Color will render correctly on Windows; Bold in a custom color scheme may not, and building a scheme that relies on bold should account for that.
Where pp produces unhelpful output: CI logs and production code
ANSI color codes are sequences of characters that tell a terminal to apply color. In a context without a terminal, such as a CI log stored to a file or forwarded through a log aggregator, those sequences appear as literal characters rather than color changes, making the output harder to read rather than easier. pp.Default.SetColoringEnabled(false) disables the codes, but that change has to be made explicitly.
pp is also the wrong layer for production logging. A production logger serialises to JSON, writes to a collector, and structures data for queries. pp writes to standard output or an io.Writer and formats for human reading, not machine parsing. Converting pp output to something structured would require disabling color, removing the indentation, and post-processing the text, at which point a proper logging library does a better job from the start.
For comparison, fmt.Printf("%+v", v) is the zero-dependency alternative for quick debugging. It prints exported and unexported fields with their names, produces no color, and adds no transitive dependencies. Adding pp means richer output in exchange for a recent Go toolchain requirement and 3 transitive dependencies.
Module v3 and what the import path change means for existing code
The module path is github.com/k0kubun/pp/v3, following Go's major version 3 convention. Any code importing github.com/k0kubun/pp without the /v3 suffix is on a different major version and will not receive v3 features or fixes without an import path change. This is a Go modules rule rather than anything pp-specific, but it is worth confirming before adding the dependency to a project that has used the package before.
CHANGELOG.md at the repository root lists what each version changed. Callers that depend on specific formatting output for edge cases should pin their go.mod to a known-good version and read CHANGELOG.md before upgrading, since no documented stability policy governs how formatting output may change between minor or patch releases.
Editorial conclusion
pp is the right choice for Go projects that rely on fmt.Printf for debugging and want syntax-highlighted output without changing the call site significantly. The go.mod requires Go 1.26.0, so any project on an older toolchain needs an upgrade before adding the dependency. The go-colorable dependency handles Windows terminal compatibility, but bold output may not render correctly on that platform, according to the README. For long-lived debug output in a CI pipeline, the ANSI color codes pp injects become noise, and calling pp.Default.SetColoringEnabled(false) is the switch to disable them.
Frequently asked questions
What is pp in Go?
pp is a colored pretty printer for Go that provides 4 fmt-like functions, pp.Print(), pp.Println(), pp.Sprint(), and pp.Fprintf(), and produces ANSI-colored, indented output for Go values such as structs, maps, and slices.
How do I install k0kubun/pp?
Add import "github.com/k0kubun/pp/v3" to your Go file and run go mod tidy to fetch the dependency. The go.mod in the repository requires Go 1.26.0 or higher.
Can I disable color in pp output?
Calling pp.Default.SetColoringEnabled(false) disables ANSI color codes for all package-level functions. For an isolated instance, create one with pp.New() and call SetColoringEnabled(false) on it without affecting the global default.
Does pp work on Windows?
Color output on Windows is handled by the go-colorable dependency. The README flags Bold formatting as not working on Windows, so color schemes that rely on bold should be tested on that platform before relying on it.
What is SetExportedOnly in pp?
SetExportedOnly is a configuration method on a PrettyPrinter instance that limits output to exported struct fields. It is set on an instance created with pp.New() rather than on pp.Default, so it does not affect other parts of the program using the package-level functions.
Official sources
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.
[](https://hysenlabs.com/projects/k0kubun-pp)