# ol.dirs next A 0-dependency implementation of XDG base directories, systemd unit directories, Windows Known Folder paths, and macOS standard directories for Clojure, ClojureScript, and ClojureDart. ## ol.dirs # ol.dirs _platforms: clj, cljs_ Cross-platform directory lookup for Clojure, ClojureScript on Node, and ClojureDart. The public API returns strings or vectors of strings and never creates directories. * arity 0 returns the base directory * arity 1 appends an application name * arity 2 appends qualifier, organization, and application using platform rules See [`config-home`](#config-home), [`data-home`](#data-home), [`state-home`](#state-home), and [`home-dir`](#home-dir). ## data-home ### clj _platforms: clj_ ```clojure (data-home) (data-home application) (data-home qualifier organization application) ``` Returns the writable user data directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L14-L19) ### cljs _platforms: cljs_ ```clojure (data-home) (data-home application) (data-home qualifier organization application) ``` Returns the writable user data directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L14-L19) --- ## config-home ### clj _platforms: clj_ ```clojure (config-home) (config-home application) (config-home qualifier organization application) ``` Returns the writable user configuration directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L21-L26) ### cljs _platforms: cljs_ ```clojure (config-home) (config-home application) (config-home qualifier organization application) ``` Returns the writable user configuration directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L21-L26) --- ## state-home ### clj _platforms: clj_ ```clojure (state-home) (state-home application) (state-home qualifier organization application) ``` Returns the writable user state directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L28-L33) ### cljs _platforms: cljs_ ```clojure (state-home) (state-home application) (state-home qualifier organization application) ``` Returns the writable user state directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L28-L33) --- ## data-dirs ### clj _platforms: clj_ ```clojure (data-dirs) (data-dirs application) (data-dirs qualifier organization application) ``` Returns the shared data search roots as a vector of strings. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L35-L40) ### cljs _platforms: cljs_ ```clojure (data-dirs) (data-dirs application) (data-dirs qualifier organization application) ``` Returns the shared data search roots as a vector of strings. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L35-L40) --- ## config-dirs ### clj _platforms: clj_ ```clojure (config-dirs) (config-dirs application) (config-dirs qualifier organization application) ``` Returns the shared configuration search roots as a vector of strings. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L42-L47) ### cljs _platforms: cljs_ ```clojure (config-dirs) (config-dirs application) (config-dirs qualifier organization application) ``` Returns the shared configuration search roots as a vector of strings. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L42-L47) --- ## cache-home ### clj _platforms: clj_ ```clojure (cache-home) (cache-home application) (cache-home qualifier organization application) ``` Returns the writable user cache directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L49-L54) ### cljs _platforms: cljs_ ```clojure (cache-home) (cache-home application) (cache-home qualifier organization application) ``` Returns the writable user cache directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L49-L54) --- ## runtime-dir ### clj _platforms: clj_ ```clojure (runtime-dir) (runtime-dir application) (runtime-dir qualifier organization application) ``` Returns the runtime directory, or `nil` on platforms without one. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L56-L61) ### cljs _platforms: cljs_ ```clojure (runtime-dir) (runtime-dir application) (runtime-dir qualifier organization application) ``` Returns the runtime directory, or `nil` on platforms without one. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L56-L61) --- ## executable-dir ### clj _platforms: clj_ ```clojure (executable-dir) (executable-dir application) (executable-dir qualifier organization application) ``` Returns the user executable directory, or `nil` when unsupported. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L63-L68) ### cljs _platforms: cljs_ ```clojure (executable-dir) (executable-dir application) (executable-dir qualifier organization application) ``` Returns the user executable directory, or `nil` when unsupported. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L63-L68) --- ## preference-dir ### clj _platforms: clj_ ```clojure (preference-dir) (preference-dir application) (preference-dir qualifier organization application) ``` Returns the preference directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L70-L75) ### cljs _platforms: cljs_ ```clojure (preference-dir) (preference-dir application) (preference-dir qualifier organization application) ``` Returns the preference directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L70-L75) --- ## home-dir ### clj _platforms: clj_ ```clojure (home-dir) ``` Returns the user’s home directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L77-L79) ### cljs _platforms: cljs_ ```clojure (home-dir) ``` Returns the user’s home directory. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L77-L79) --- ## audio-dir ### clj _platforms: clj_ ```clojure (audio-dir) ``` Returns the user’s audio or music directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L81-L83) ### cljs _platforms: cljs_ ```clojure (audio-dir) ``` Returns the user’s audio or music directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L81-L83) --- ## desktop-dir ### clj _platforms: clj_ ```clojure (desktop-dir) ``` Returns the user’s desktop directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L85-L87) ### cljs _platforms: cljs_ ```clojure (desktop-dir) ``` Returns the user’s desktop directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L85-L87) --- ## document-dir ### clj _platforms: clj_ ```clojure (document-dir) ``` Returns the user’s documents directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L89-L91) ### cljs _platforms: cljs_ ```clojure (document-dir) ``` Returns the user’s documents directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L89-L91) --- ## download-dir ### clj _platforms: clj_ ```clojure (download-dir) ``` Returns the user’s downloads directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L93-L95) ### cljs _platforms: cljs_ ```clojure (download-dir) ``` Returns the user’s downloads directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L93-L95) --- ## font-dir ### clj _platforms: clj_ ```clojure (font-dir) ``` Returns the user’s font directory, or `nil` when unsupported. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L97-L99) ### cljs _platforms: cljs_ ```clojure (font-dir) ``` Returns the user’s font directory, or `nil` when unsupported. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L97-L99) --- ## picture-dir ### clj _platforms: clj_ ```clojure (picture-dir) ``` Returns the user’s pictures directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L101-L103) ### cljs _platforms: cljs_ ```clojure (picture-dir) ``` Returns the user’s pictures directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L101-L103) --- ## public-dir ### clj _platforms: clj_ ```clojure (public-dir) ``` Returns the user’s public sharing directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L105-L107) ### cljs _platforms: cljs_ ```clojure (public-dir) ``` Returns the user’s public sharing directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L105-L107) --- ## template-dir ### clj _platforms: clj_ ```clojure (template-dir) ``` Returns the user’s templates directory, or `nil` when unsupported or unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L109-L111) ### cljs _platforms: cljs_ ```clojure (template-dir) ``` Returns the user’s templates directory, or `nil` when unsupported or unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L109-L111) --- ## video-dir ### clj _platforms: clj_ ```clojure (video-dir) ``` Returns the user’s videos directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L113-L115) ### cljs _platforms: cljs_ ```clojure (video-dir) ``` Returns the user’s videos directory, or `nil` when unresolved. [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L113-L115) --- ## state-dir ### clj _platforms: clj_ ```clojure (state-dir) (state-dir application) (state-dir qualifier organization application) ``` Alias of [`state-home`](#state-home). [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L117-L122) ### cljs _platforms: cljs_ ```clojure (state-dir) (state-dir application) (state-dir qualifier organization application) ``` Alias of [`state-home`](#state-home). [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L117-L122) --- ## config-dir ### clj _platforms: clj_ ```clojure (config-dir) (config-dir application) (config-dir qualifier organization application) ``` Alias of [`config-home`](#config-home). [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L124-L129) ### cljs _platforms: cljs_ ```clojure (config-dir) (config-dir application) (config-dir qualifier organization application) ``` Alias of [`config-home`](#config-home). [source,window=_blank](https://github.com/outskirtslabs/dirs/blob/main/src/ol/dirs.cljc#L124-L129) ## Changelog # Changelog All notable changes to this project will be documented in this file. This project uses [**Break Versioning**](https://www.taoensso.com/break-versioning). ## ++[++UNRELEASED++]++ ## `v0.1.0` (2026-03-12) This is the first public release of this codebase under the `ol.dirs` name. This release establishes the first published cross-platform directory discovery API for Clojure, ClojureScript on Node, and ClojureDart. Private variations of the clj/JVM code has been used in production for a awhile, but nonetheless I want to be cautious so we’re starting with sub-1.0 versioning. ## ol.dirs # ol.dirs > A 0-dependency implementation of XDG base directories, systemd unit directories, Windows Known Folder paths, and macOS standard directories for Clojure, ClojureScript, and ClojureDart. ![doc](https://img.shields.io/badge/doc-outskirtslabs-orange.svg) ![status: maturing](https://img.shields.io/badge/status-maturing-yellow.svg) [![Clojars Project](https://clojars.org/com.outskirtslabs/dirs)(https://img.shields.io/clojars/v/com.outskirtslabs/dirs.svg)] `ol.dirs` returns string paths or vectors of string paths. It does not create directories, does not check whether they exist, and carries no runtime dependencies. ## Support Matrix | Runtime | Linux | macOS | Windows | | --- | --- | --- | --- | | Clojure | yes | yes | yes | | ClojureScript on Node | yes | yes | yes | | ClojureDart | yes | yes | yes | Project status: **[Maturing](https://docs.outskirtslabs.com/open-source-vital-signs#maturing)**. ## Installation ```clojure ;; deps.edn {:deps {com.outskirtslabs/dirs {:mvn/version "0.1.0"}}} ;; Leiningen [com.outskirtslabs/dirs "0.1.0"] ``` ## Quick Start ```clojure (require '[ol.dirs :as dirs]) (dirs/config-home) ;; => "/home/alice/.config" (dirs/config-home "My App") ;; => "/home/alice/.config/my-app" (dirs/config-home "org" "Acme Corp" "My App") ;; => Linux: "/home/alice/.config/my-app" ;; => macOS: "/Users/Alice/Library/Application Support/org.Acme-Corp.My-App" ;; => Windows: "C:\\Users\\Alice\\AppData\\Roaming\\Acme Corp\\My App" ``` ## Documentation * [Docs](https://docs.outskirtslabs.com/ol.dirs/next/) * [API Reference](https://docs.outskirtslabs.com/ol.dirs/next/api) * [Support via GitHub Issues](https://github.com/outskirtslabs/dirs/issues) ## API Notes These functions support app-specific arities. Arity `0` returns the base directory, arity `1` appends an application name, and arity `3` appends a platform-specific qualifier, organization, and application path. The concrete path shapes are shown below in the `App Path Rules` table and in the example above. `data-home`, `config-home`, `state-home`, `cache-home`, `runtime-dir`, `executable-dir`, `preference-dir`, `state-dir`, and `config-dir` all support those same arities. `data-dirs` and `config-dirs` do too, but return vectors and append the application path to each search root. ### App Path Rules | Form | Linux | macOS | Windows | | --- | --- | --- | --- | | `("My App")` | `my-app` | `My-App` | `My App` | | `("org" "Acme Corp" "My App")` | `my-app` | `org.Acme-Corp.My-App` | `Acme Corp\My App` | ### Base Directories | Function | Linux | macOS | Windows | | --- | --- | --- | --- | | `home-dir` | `$HOME` | `$HOME` | `%USERPROFILE%` | | `data-home` | `$XDG_DATA_HOME` or `$HOME/.local/share` | `$HOME/Library/Application Support` | `%AppData%` | | `config-home` | `$XDG_CONFIG_HOME` or `$HOME/.config` | `$HOME/Library/Application Support` | `%AppData%` | | `state-home` | `$XDG_STATE_HOME` or `$HOME/.local/state` | `$HOME/Library/Application Support` | `%LocalAppData%` | | `cache-home` | `$XDG_CACHE_HOME` or `$HOME/.cache` | `$HOME/Library/Caches` | `%LocalAppData%` | | `data-dirs` | `$XDG_DATA_DIRS` or `/usr/local/share`, `/usr/share` | `/Library/Application Support` | `%ProgramData%` | | `config-dirs` | `$XDG_CONFIG_DIRS` or `/etc/xdg` | `/Library/Application Support` | `%ProgramData%` | | `preference-dir` | same as `config-home` | `$HOME/Library/Preferences` | `%AppData%` | | `runtime-dir` | `$XDG_RUNTIME_DIR` or `nil` | `nil` | `nil` | | `executable-dir` | `$XDG_BIN_HOME` or `$XDG_DATA_HOME/../bin` | `nil` | `nil` | On Linux, trusted systemd units can override `config-home`, `state-home`, and `cache-home` via `CONFIGURATION_DIRECTORY`, `STATE_DIRECTORY`, and `CACHE_DIRECTORY` as documented in [`systemd.exec(5)`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html). ### User-Facing Directories | Function | Linux | macOS | Windows | | --- | --- | --- | --- | | `audio-dir` | `XDG_MUSIC_DIR` from `user-dirs.dirs` | `$HOME/Music` | Music Known Folder | | `desktop-dir` | `XDG_DESKTOP_DIR` from `user-dirs.dirs` | `$HOME/Desktop` | Desktop Known Folder | | `document-dir` | `XDG_DOCUMENTS_DIR` from `user-dirs.dirs` | `$HOME/Documents` | Documents Known Folder | | `download-dir` | `XDG_DOWNLOAD_DIR` from `user-dirs.dirs` | `$HOME/Downloads` | Downloads Known Folder | | `font-dir` | `$XDG_DATA_HOME/fonts` | `$HOME/Library/Fonts` | `nil` | | `picture-dir` | `XDG_PICTURES_DIR` from `user-dirs.dirs` | `$HOME/Pictures` | Pictures Known Folder | | `public-dir` | `XDG_PUBLICSHARE_DIR` from `user-dirs.dirs` | `$HOME/Public` | Public Known Folder | | `template-dir` | `XDG_TEMPLATES_DIR` from `user-dirs.dirs` | `nil` | Templates Known Folder | | `video-dir` | `XDG_VIDEOS_DIR` from `user-dirs.dirs` | `$HOME/Movies` | Videos Known Folder | ## Nil Semantics These functions may return `nil` by design: * `runtime-dir` and `executable-dir` on non-Linux platforms * `font-dir` on Windows * `template-dir` on macOS * Linux user-facing directories when `user-dirs.dirs` is missing, unreadable, disabled, or malformed ## Development ```bash bb test:clj bb test:cljs bb test:cljd bb test ``` The CLJD workspace commands live under [`dart/`](dart/), because the Dart toolchain emits generated files that are easier to keep isolated there. ## License Copyright (C) 2026 Casey Link Distributed under the [EUPL-1.2](https://spdx.org/licenses/EUPL-1.2.html). ## Security policy # Security policy ## Advisories All security advisories for `ol.dirs` will be posted [on GitHub](https://github.com/outskirtslabs/dirs/security/advisories). ## Reporting a vulnerability Please report possible security vulnerabilities [via GitHub](https://github.com/outskirtslabs/dirs/security/advisories), or by emailing me at `casey@outskirtslabs.com`. You may encrypt email with [my public PGP key](https://casey.link/pgp.asc). For the organization-wide security policy, see [Outskirts Labs Security Policy](https://docs.outskirtslabs.com/security-policy). Thank you! [Casey Link](https://casey.link)