Separate config, cache, and runtime storage per platform conventions (XDG on Linux, ~/Library on macOS)

Use case or problem

Obsidian picks the right config directory per platform — ~/Library/Application Support/obsidian/ on macOS and $XDG_CONFIG_HOME/obsidian/ on Linux. But it then dumps all file types into that single directory regardless: config, cache, GPU cache, logs, state, and runtime sockets all live together.

This matters for anyone managing dotfiles via version control. On both platforms you’re forced to either track everything — including 100MB+ Electron cache dirs and ephemeral sockets — or nothing.

On macOS, the specific problems are:

  • Electron cache files (GPU cache, Code Cache, Disk Cache) belong in ~/Library/Caches/obsidian/, not ~/Library/Application Support/obsidian/
  • The .obsidian-cli.sock runtime socket has no well-defined location; it should go in $TMPDIR/obsidian/ (the standard macOS ephemeral runtime location)

On Linux, the problem is broader — all file types are merged into $XDG_CONFIG_HOME/obsidian/, conflating what the XDG Base Directory Specification explicitly separates:

  • Cache → $XDG_CACHE_HOME/obsidian/ (default: ~/.cache/obsidian/)
  • State/logs → $XDG_STATE_HOME/obsidian/ (default: ~/.local/state/obsidian/)
  • Runtime socket → $XDG_RUNTIME_DIR/obsidian/obsidian-cli.sock

Proposed solution

Route each file type to the appropriate platform directory:

File type macOS Linux
Config ~/Library/Application Support/obsidian/ (already correct) $XDG_CONFIG_HOME/obsidian/ (already correct)
Cache ~/Library/Caches/obsidian/ $XDG_CACHE_HOME/obsidian/
Logs / state ~/Library/Application Support/obsidian/logs/ $XDG_STATE_HOME/obsidian/
Runtime socket $TMPDIR/obsidian/obsidian-cli.sock $XDG_RUNTIME_DIR/obsidian/obsidian-cli.sock

As an Electron app, Obsidian can control all of these via app.getPath() overrides. The implementation can be backward-compatible: if a legacy directory already contains data, continue using it; only apply the new layout on fresh installs.

3 Likes