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,017stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
56/100Fair
Development Activity56
Maintenance36
Community44
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture85
Code Quality88
Innovation78
Learning Curve92

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

TypeScript
53%
MIT

Anarlog

Note Taking · AI Assistants · Productivity

9,192

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
69
Dependency
Built with
TypeScript53%
Rust36%
Updated today
Go
75%
AGPL 3.0

Coder

Devops · Developer Tools · Code Editors

14,299

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

View details
93
Repo Health
90
Technical
69
Dependency
Built with
Go75%
TypeScript23%
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
94
Repo Health
77
Technical
67
Dependency
Built with
Go92%
Updated 2 days ago
Go
61%
Apache 2.0

Harness Open Source

Developer Tools · Devops · Code Editors

38,169

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
89
Repo Health
79
Technical
64
Dependency
Built with
Go61%
TypeScript34%
Updated 2 days ago
Go
60%
MIT

Obot

AI Agents

965

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
87
Repo Health
70
Technical
70
Dependency
Built with
Go60%
Svelte29%
Updated yesterday

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

Search