DEV Community

Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on • Edited on

.env vs .toml for Config in Go: What Should You Use?

Hello, I'm Maneshwar. I'm working on FreeDevTools online currently building **one place for all dev tools, cheat codes, and TLDRs* — a free, open-source hub where developers can quickly find and use tools without any hassle of searching all over the internet.

Managing config in Go projects is simple—until y
ou have to decide how to do it. Two popular options are .env files and .toml files. Let’s break down what each does, when to use them, and how to implement both cleanly.

.env — The Minimalist's Choice

.env files are basically key-value pairs like:

PORT=8080
DB_URL=postgres://user:pass@localhost:5432/dbname
DEBUG=true
Enter fullscreen mode Exit fullscreen mode

How to use in Go

Use the github.com/joho/godotenv package:

go get github.com/joho/godotenv
Enter fullscreen mode Exit fullscreen mode
package main

import (
    "log"
    "os"

    "github.com/joho/godotenv"
)

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    port := os.Getenv("PORT")
    log.Println("Server will run on port:", port)
}
Enter fullscreen mode Exit fullscreen mode

Pros

  • Dead simple
  • Popular in 12-factor apps
  • Great for secrets + env-specific settings

Cons

  • No support for structured config (arrays, nested data)
  • All values are strings

.toml — Structured and Powerful

.toml stands for "Tom's Obvious, Minimal Language". It supports rich types: strings, ints, arrays, nested tables.

[server]
port = 8080
debug = true

[database]
url = "postgres://user:pass@localhost:5432/dbname"
max_connections = 20
Enter fullscreen mode Exit fullscreen mode

🛠 How to use in Go

Use github.com/pelletier/go-toml:

go get github.com/pelletier/go-toml
Enter fullscreen mode Exit fullscreen mode
package main

import (
    "fmt"
    "log"

    "github.com/pelletier/go-toml"
)

type Config struct {
    Server struct {
        Port  int
        Debug bool
    }
    Database struct {
        URL            string
        MaxConnections int `toml:"max_connections"`
    }
}

func main() {
    var config Config
    if _, err := toml.DecodeFile("config.toml", &config); err != nil {
        log.Fatal(err)
    }
    fmt.Println("DB URL:", config.Database.URL)
}
Enter fullscreen mode Exit fullscreen mode

Pros

  • Native support for structured configs
  • Type-safe
  • Better for large configs

Cons

  • More verbose
  • Requires struct mapping

When to Use What?

Use Case Use .env Use .toml
Small config or secrets 🚫
Structured config (nested) 🚫
Environment-specific overrides ✅ (with profiles)
Type safety 🚫
Simplicity 🚫

Combine Both?

Yes, many real-world apps load secrets from .env and structured settings from .toml. Example:

# .env
DB_PASSWORD=supersecret
Enter fullscreen mode Exit fullscreen mode
# config.toml
[database]
user = "admin"
host = "localhost"
Enter fullscreen mode Exit fullscreen mode
// Load .env
_ = godotenv.Load()
password := os.Getenv("DB_PASSWORD")

// Load config.toml
var config Config
_, _ = toml.DecodeFile("config.toml", &config)

// Combine them
dsn := fmt.Sprintf("postgres://%s:%s@%s", config.Database.User, password, config.Database.Host)
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

  • Use .env when you want simplicity or are working with containerized/12-factor apps.
  • Use .toml when your config has structure, or you want clean type mapping.
  • Use both when it makes sense—there’s no rule saying you can’t.

FreeDevTools

I’ve been building FreeDevTools.

A collection of UI/UX-focused tools crafted to simplify workflows, save time, and reduce friction in searching tools/materials.

Any feedback or contributors are welcome!

It’s online, open-source, and ready for anyone to use.

👉 Check it out: FreeDevTools
⭐ Star it on GitHub: freedevtools

Let’s make it even better together.

Top comments (2)

Collapse
 
syeo66 profile image
Red Ochsenbein (he/him)

I tend to use only environment variables and inject them using dotenvx if there is need for a config file.

Collapse
 
shiva_shanker_k profile image
shiva shanker

That's amazing..🤌❤️‍🔥.env for secrets, .toml for organized config. Most devs use both - .env for stuff that changes, .toml for stuff that stays the same. Simple.