go-ini/ini: reading and writing INI files in Go
Package ini provides INI file read and write functionality in Go
At a glance
- What is it?
- go-ini/ini is an Apache-2.0 Go library for loading INI configuration from files, byte slices and readers, and for writing sections, keys and comments back out. It suits services that need ordered, human-editable config files without leaving Go.
- Who is it for?
- Adopt go-ini/ini when your configuration lives in human-edited INI files and you need to write comments and preserve key order, which encoding/json and go-yaml/v3 do not do. Skip it when your config is nested maps or arrays, or when you need environment variable expansion, which the README does not document.
- Can I use it commercially?
- Yes. Apache-2.0 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 26 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 go-ini/ini solves and who reaches for it
Go's standard library ships encoding/json and encoding/xml but no INI parser. INI remains common for application config because a human can open the file, edit one key, and save it without worrying about quoting or indentation. go-ini/ini fills that gap: it reads INI files and writes them back. The README lists the intended capabilities, including loading from multiple data sources with overwrites, reading with recursion values, parent-child sections and auto-increment key names, and converting values to Go types.
The audience is Go developers who own a config file that operators edit by hand. That covers a CLI tool with a per-user config, a daemon with a site-specific settings file, or a service that ships defaults and lets the deployment override them. The library is also a fit when a program must generate or update a config file rather than only consume one, because the README notes it can read and write comments of sections and keys, and keep sections and keys in order as you parse and save. A generated file that loses its comments or reorders keys is a support burden, so that pair of features is the practical reason to pick this package over a minimal parser.
Data sources, sections and keys: how the library is put together
The repository layout shows the split: data_source.go, parser.go, file.go, section.go, key.go, struct.go, helper.go and error.go, with a matching _test file for most of them. The data source layer is what the README calls loading from multiple sources. A file, a []byte, an io.Reader and an io.ReadCloser are all accepted, and later loads overwrite earlier values. That is the mechanism behind layered configuration: embed defaults, then load a file, then load an override, and the last write wins.
Above the data source sits the parser, which produces a File value. A File holds Section values, and a Section holds Key values. struct.go is the bridge to Go types, mapping sections and keys onto struct fields. helper.go holds the conversion helpers the README refers to as tons of helper methods. The README also claims parent-child sections, recursion values and auto-increment key names, which means the parser is not a flat key-value reader: it has rules for resolving a key through a parent section and for generating sequential key names. Those rules are documented on the project site rather than in the README, so read the Getting Started page before relying on them.
Install and first read: a go-ini/ini example
The README states the minimum Go version is 1.13 and gives the module path gopkg.in/ini.v1. Install it with go get:
$ go get gopkg.in/ini.v1@latestIf an existing project imports github.com/go-ini/ini, the README shows a go.mod rewrite instead of editing every import. This edits go.mod in place:
go mod edit -replace github.com/go-ini/ini=gopkg.in/ini.v1@latestOnce the dependency is in place, the README points to the Getting Started page at https://ini.unknwon.io/docs/intro/getting_started for the loading API, and to the GoDoc reference at pkg.go.dev for the full list of methods. The README itself does not print a worked code sample, so confirm the exact function names there before writing code against them.
Where go-ini/ini stops being the right tool
INI has no standard for nested structures. go-ini/ini works around that with parent-child sections and recursion values, but those are conventions the library defines, not something every INI consumer understands. If another program reads the same file and does not implement the same rules, the file is no longer portable. For genuinely nested configuration, JSON, YAML or TOML express the shape directly.
The README does not document environment variable expansion, so a deployment that expects a placeholder inside the file to resolve will not get that from this library. It also does not document rollback, file watching or hot reload, which means a long-running service that expects config changes to apply without a restart has to implement that itself. The write path is another boundary: because the library preserves order and comments, saving a file it did not fully understand can produce a file that differs from what a human expects, so treat programmatic writes to a hand-maintained config with care.
Finally, the repository is not archived, and the last push was on 2026-09-05, with v1.67.3 released on 2026-06-08. That is recent activity, but the API is stable enough that the README still points at Go 1.13 as the floor, which tells you the project optimises for compatibility over new language features.
go-ini/ini against go-yaml/v3 and encoding/json
The closest structural alternative is go-yaml/v3, which parses YAML into Go values and handles nesting and arrays natively. The difference in approach is the file format's contract with humans. YAML is indentation-sensitive and its type inference surprises people (the Norway problem is the usual example); INI has flat sections and string values, so what you read in the file is what you get, and go-ini/ini converts to Go types through explicit helpers. YAML also does not round-trip comments by default, while go-ini/ini states that it reads and writes comments and keeps sections and keys in order.
encoding/json is the other comparison point. It is in the standard library, so there is no dependency to manage, and it handles arbitrary nesting. But JSON forbids comments entirely, and its output is not something an operator edits comfortably. If your config file is machine-written and machine-read, JSON is simpler. If a person edits it and expects their comments to survive the next programmatic save, go-ini/ini's write support is the feature that decides it. The trade-off is that you accept INI's flat model and the library's own conventions for anything hierarchical.
Maintenance, upgrades and the Apache-2.0 licence
The module declares go 1.13 in go.mod and depends only on github.com/stretchr/testify v1.11.1, and that dependency is test-only. A single test dependency means the upgrade surface is small: moving to a new release of go-ini/ini does not drag a tree of transitive modules behind it. The Makefile defines build, test, bench, vet and coverage targets, so a contributor or a downstream fork can run the same checks the project runs. The release cadence visible in the facts is v1.67.1 in January 2026, v1.67.2 in May 2026 and v1.67.3 in June 2026, with the last push on 2026-09-05.
The licence is Apache-2.0, which permits commercial and closed-source use and includes an explicit patent grant. That is a permissive licence, but the obligations are real: keep the LICENSE file and any notices with redistributed copies, and check whether your organisation's policy requires more. Nothing here is legal advice; read the LICENSE file in the repository for the actual terms. On the upgrade side, the README's own note about the import path is the one migration cost worth planning for: projects still importing github.com/go-ini/ini need the go mod edit -replace line or an import rewrite.
Editorial conclusion
Adopt go-ini/ini when your configuration lives in human-edited INI files and you need to write comments and preserve key order, which encoding/json and go-yaml/v3 do not do. Skip it when your config is nested maps or arrays, or when you need environment variable expansion, which the README does not document. Verify the gopkg.in/ini.v1 import path and that your toolchain is Go 1.13 or newer before adding it to go.mod.
Frequently asked questions
What is an INI file used for in a Go project?
An INI file holds configuration as named sections containing key-value pairs, which makes it easy for a person to edit by hand. go-ini/ini reads those files into a File value with Section and Key types, and can write sections, keys and comments back out.
How can I open an INI file with go-ini/ini?
The README states the library loads from a file, a []byte, an io.Reader and an io.ReadCloser. Loading the same configuration from several sources applies overwrites, so the last source loaded wins for any key it defines.
Can a .INI file be a virus?
The repository does not discuss malware, and go-ini/ini only parses and writes INI text. Treat an INI file as data the library reads, not as something it executes.
What Go version does go-ini/ini require?
The README states the minimum requirement of Go is 1.13, and the module's go.mod declares go 1.13. Its only listed dependency is github.com/stretchr/testify v1.11.1, which is used for tests.
How do I install go-ini/ini and what is the import path?
The README gives go get gopkg.in/ini.v1@latest, and the module path in go.mod is gopkg.in/ini.v1. If code still imports github.com/go-ini/ini, the README shows go mod edit -replace github.com/go-ini/ini=gopkg.in/ini.v1@latest as a way to change the import path without rewriting every file.
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/go-ini-ini)