xdg

Cross-platform Go library for resolving XDG Base Directory and user directory paths on Unix, macOS, Windows, and Plan 9.

Library
Go
vv0.5.3
1,022 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
64 /100 Good
Development Activity 68
Maintenance 52
Community 48
Maturity 60
Momentum 28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
86 /100 Excellent
Architecture 85
Code Quality 88
Innovation 78
Learning Curve 92

xdg is a Go package implementing the freedesktop.org XDG Base Directory Specification, giving applications a portable way to locate configuration, data, cache, state, and runtime directories instead of hardcoding paths. It resolves the standard XDG_DATA_HOME, XDG_CONFIG_HOME, XDG_CACHE_HOME, XDG_STATE_HOME, and XDG_RUNTIME_DIR environment variables, falling back to spec-compliant defaults when they are unset, and also exposes well-known user directories such as Desktop, Downloads, Documents, Music, Pictures, Videos, Templates, PublicShare, and Projects.

Beyond Unix-like systems, xdg extends the same API to Windows by mapping XDG semantics onto the Known Folders API, and to Plan 9, so a single set of functions (ConfigFile, DataFile, CacheFile, StateFile, RuntimeFile and their Search* counterparts) works uniformly across platforms — creating parent directories on write and searching multiple base paths on read.

What You Get

  • Package-level variables for all XDG base directories (DataHome, ConfigHome, CacheHome, StateHome, RuntimeDir, BinHome) resolved from environment variables with spec-compliant fallbacks
  • Helper functions (ConfigFile, DataFile, CacheFile, StateFile, RuntimeFile) that create any missing parent directories and return a ready-to-write path for a named file
  • Search functions (SearchConfigFile, SearchDataFile, SearchStateFile, SearchCacheFile, SearchRuntimeFile) that look across every configured base and additional directory to locate an existing file
  • Well-known user directories (Desktop, Downloads, Documents, Music, Pictures, Videos, Templates, PublicShare, Projects) parsed from user-dirs.dirs on Unix or Windows Known Folders
  • Windows Known Folder mapping so the same XDG-style variables resolve to sensible locations even though Windows doesn’t natively set XDG environment variables
  • Reload() to re-read environment variables at runtime without restarting the process

Common Use Cases

  • CLI tools that need a portable place to write config files instead of hardcoding ~/.config
  • Desktop applications locating cache or state files consistently across Linux, macOS, and Windows
  • Applications searching multiple XDG_CONFIG_DIRS to find a config file that could live in several locations
  • Tools that need the user’s Desktop, Downloads, or Documents path without platform-specific code
  • Daemons writing runtime files such as sockets or PID files to XDG_RUNTIME_DIR with a temp-dir fallback

Under The Hood

Architecture The package exposes a flat public API of package-level variables initialized via init() -> Reload(), which calls a platform-specific initDirs selected at compile time through Go build tags (paths_unix.go, paths_darwin.go, paths_windows.go, paths_plan9.go). Each platform file populates a private baseDirectories struct whose methods (dataFile, configFile, searchDataFile, etc., in base_dirs.go) are thinly wrapped by the public functions in xdg.go (DataFile, ConfigFile, SearchConfigFile…). Cross-cutting path logic — creating a file’s parent directories, searching a list of candidate directories, deduplicating and expanding home-relative paths — is factored into internal/pathutil so every platform and every Base/Search function shares identical semantics, while internal/userdirs owns parsing the freedesktop user-dirs.dirs config file and defines the UserDirectories struct. Swapping the core path-resolution logic in internal/pathutil would ripple uniformly through every public function, but platform variance stays isolated to the four paths_*.go files.

Tech Stack The module (github.com/adrg/xdg, go.mod targeting Go 1.25) has a single non-test runtime dependency, golang.org/x/sys v0.45.0, used only on Windows to call windows.KnownFolderPath against FOLDERID_* constants; stretchr/testify v1.11.1 is test-only. There is no code generation, database, or web framework involved — this is a pure filesystem/environment-variable utility library consumed via go get. CI runs a lint job across an ubuntu/macos/windows matrix plus a CodeQL security-and-quality scan, and codecov.yml wires up coverage reporting.

Code Quality Every platform-specific and internal file has a matching test file, often larger than the implementation it covers (paths_windows_test.go runs longer than paths_windows.go, for instance), combining testify assertions with table-style subtests and example_test.go’s runnable, doc-rendered examples. Every path-lookup function returns (string, error), and the internal Create/Search helpers build descriptive error messages listing every path that was attempted rather than swallowing failures. Naming is a consistent verb-first convention (Create, Search, Unique, First, EnvPath) with no use of interface{}/any — everything stays concretely typed.

API Design The public surface is deliberately minimal: package-level variables like xdg.ConfigHome can be read with zero setup, and the file-oriented helpers return a ready-to-write path while transparently creating parent directories, eliminating the most common boilerplate around saving application files. The Search* family mirrors the same names one-to-one, keeping the surface easy to memorize, and Reload() offers a pragmatic escape hatch for processes that need to react to changed environment variables at runtime. The package isn’t conceptually novel — it’s a faithful implementation of an existing spec — but it delivers a portable answer to “where do I put this file” in a single line across four platforms.

Used by 5 apps in this directory

Rust
45%
MIT

Anarlog

AI Assistants · Note Taking · Productivity

9,468

Anarlog is an open-source, local-first AI meeting notetaker that records, transcribes, and summarizes meetings entirely on your device — no cloud lock-in, no mandatory account, and every note saved as a plain markdown file you own forever.

View details
86
Repo Health
77
Technical
68
Dependency
Built with
Rust 45%
TypeScript 40%
Updated today
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
92%
AGPL 3.0

Cozy Stack

File Storage · Productivity

1,270

Self-hosted personal cloud platform that unifies your files, apps, and devices in one private space you fully control.

View details
95
Repo Health
77
Technical
67
Dependency
Built with
Go 92%
Updated yesterday
Go
62%
Apache 2.0

Harness Open Source

Code Editors · Developer Tools · Devops

38,509

A unified open source DevOps platform combining Git hosting, CI/CD pipelines, cloud development environments, and artifact registries in a single self-hosted system.

View details
90
Repo Health
79
Technical
64
Dependency
Built with
Go 62%
TypeScript 33%
Updated yesterday
Go
64%
MIT

Obot

AI Agents · Mcp

1,099

An open-source MCP platform for organizations — host MCP servers, run MCP registries, monitor usage, and build agents and chatbots on top of the Model Context Protocol from one self-hosted deployment.

View details
88
Repo Health
70
Technical
70
Dependency
Built with
Go 64%
Svelte 23%
TypeScript 13%
Updated today

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