structs

Reflection-based Go utilities for converting structs to maps, slices, and field-level metadata without hand-written boilerplate.

Library
Go
vv1.1.0
3,921 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
46 /100 Fair
Development Activity 0
Maintenance 20
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
70 /100 Good
Architecture 78
Code Quality 80
Innovation 55
Learning Curve 65

structs is a small, dependency-free Go library built on top of the standard reflect package to make working with struct values less repetitive. It exposes a single Struct type (and matching package-level functions) that can turn any struct into a map[string]interface{}, a []interface{} of its values, or a list of field names — driven entirely by struct field tags rather than hand-written conversion code.

Field-level behavior is controlled through a structs tag with options like renaming a key, skipping a field with -, flattening a nested struct’s fields into the parent map, stringifying a field via its Stringer implementation, or skipping empty values with omitempty. A companion Field type gives per-field access for reading, setting, or zeroing individual struct fields through reflection, plus zero-value inspection helpers (IsZero, HasZero) for entire structs. The project has been archived by its author since 2018 but remains widely used and stable for its narrow scope.

What You Get

  • structs.Map(s) / New(s).Map() — convert any struct to a map[string]interface{}, recursing into nested structs, slices, and maps of structs
  • structs.Values(s) — flatten a struct’s field values into a []interface{} in declaration order, including embedded struct fields
  • structs.Fields(s) / Names(s) — enumerate a struct’s exported fields or just their names, honoring - tag exclusions
  • Tag-driven behavior via the structs struct tag: custom key names, omitempty, omitnested, flatten, and string (uses a field’s Stringer implementation)
  • Field type for per-field access — Value(), Set(), Zero(), IsZero(), IsEmbedded(), IsExported(), and tag lookups on a single struct field
  • IsZero(s) / HasZero(s) to check whether all or any fields of a struct hold their zero value

Common Use Cases

  • Serializing internal struct-based models to map[string]interface{} for JSON-like APIs, template contexts, or logging without writing a marshaler by hand
  • Building generic configuration or settings systems that need to introspect arbitrary struct shapes at runtime
  • Flattening nested config or DTO structs into a single flat map for form population, key-value stores, or environment-variable style access
  • Validating that required struct fields were actually populated by checking IsZero/HasZero before using a value
  • Writing generic reflection-based tooling (ORWs, CLI flag binders, template engines) that needs to walk arbitrary struct fields uniformly

Under The Hood

Architecture The package is deliberately small and single-purpose: structs.go defines a Struct type that wraps a raw interface value, its reflect.Value, and a configurable tag name, while field.go defines a matching Field type for single-field access, and tags.go provides a tiny tag-parsing helper shared by both. Every package-level function (Map, Values, Fields, Names, IsZero, HasZero) is a thin wrapper that constructs a Struct via New() and delegates to the corresponding method, keeping the functional and object-oriented entry points in lockstep. The most structurally interesting piece is the recursive nested() helper in structs.go, which walks structs, slices, arrays, and maps of structs to build the recursive map output for Map()/FillMap() — a change to that function’s traversal rules is the one place that could ripple across most of the package’s behavior.

Tech Stack Written in pure Go with zero third-party dependencies — only the standard library (reflect, fmt, errors, strings) is imported. It predates Go modules, so there is no go.mod; consumers pull it via go get and GOPATH-style vendoring. CI runs on Travis across several Go 1.x versions plus tip, with coverage reported through goveralls, and installation/build tooling is otherwise absent since the package is a plain importable library with no binaries or build steps of its own.

Code Quality Test coverage is extensive relative to the package’s size: structs_test.go alone is roughly 1,450 lines covering close to fifty test functions, complemented by a dedicated field_test.go, a small tags_test.go, and a structs_example_test.go of runnable, doc-linked Example functions. Error handling uses explicit sentinel errors (errNotExported, errNotSettable) rather than panics for the mutable Field.Set() path, though several read-path functions still panic on invalid struct kinds by design, as documented in their doc comments. Every exported type and function carries a godoc comment, and naming follows standard Go conventions throughout; there is no dedicated linter configuration, consistent with a project of this era, but the code is gofmt-conformant.

API Design The library’s ergonomics come from mirroring the same operation as both a package-level function (structs.Map(s)) and a method on a constructed Struct (structs.New(s).Map()), so callers can reach for the one-off form or the reusable form without learning two different APIs. Tag options (omitempty, omitnested, flatten, string, custom key names) compose the way encoding/json tags do, which keeps the learning curve low for anyone who has used Go’s standard marshaling conventions, and the Field type extends that same tag-driven model down to single-field reads and writes.

Used by 5 apps in this directory

Go
75%
AGPL 3.0

Coder

Code Editors · Developer Tools · Devops

16,920

Self-hosted cloud development environments and AI coding agents — defined in Terraform, connected via WireGuard, automatically shut down when idle.

View details
91
Repo Health
90
Technical
66
Dependency
Built with
Go 75%
TypeScript 23%
Updated today
Go
69%
Other

Hanko

Authentication · Security

9,038

Open source, self-hostable authentication platform with passkeys, SAML SSO, and OAuth — the privacy-first alternative to Auth0 and Clerk.

View details
89
Repo Health
81
Technical
66
Dependency
Built with
Go 69%
TypeScript 27%
Updated 3 days ago
Go
82%
GPL 3.0

Navidrome

File Storage · Music Audio

24,068

Run your own personal Spotify — stream your entire music collection from any device, anywhere, forever.

View details
91
Repo Health
81
Technical
69
Dependency
Built with
Go 82%
JavaScript 15%
Updated yesterday
Go
98%
Apache 2.0

Space Cloud

Authentication · Devops

4,001

Kubernetes-native serverless platform that generates instant GraphQL and REST APIs for any database with built-in auth and real-time subscriptions

View details
50
Repo Health
74
Technical
63
Dependency
Built with
Go 98%
Updated 2 years ago
Go
94%
MIT

Traefik

Automation · Devops · Security

65,130

A cloud-native reverse proxy and load balancer that auto-configures itself from Docker, Kubernetes, and other orchestrators — zero manual routing required.

View details
92
Repo Health
85
Technical
64
Dependency
Built with
Go 94%
Updated 2 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers