dots detects the current OS and architecture at runtime and uses this information to apply platform-specific configuration. This enables a single manifest or config file to work across macOS, Linux, Windows, and multiple CPU architectures.
A platform is an OS-architecture pair in os-arch format:
| Identifier | OS | Architecture |
|---|---|---|
darwin-arm64 |
macOS | Apple Silicon |
darwin-amd64 |
macOS | Intel |
linux-amd64 |
Linux | x86_64 |
linux-arm64 |
Linux | ARM64 |
windows-amd64 |
Windows | x86_64 |
windows-arm64 |
Windows | ARM64 |
freebsd-amd64 |
FreeBSD | x86_64 |
You can use either the OS alone (darwin) or the full OS-arch pair (darwin-arm64) as keys in platform sections. The OS-only key matches all architectures for that OS.
WSL is detected as linux.
Check your current platform:
dots info --platformdots uses Go's runtime.GOOS and runtime.GOARCH to detect the platform. No external tools or environment variables are needed.
When a manifest or config file contains platform-specific sections, dots merges them in order of increasing specificity:
base -> OS -> OS-arch
For example, on darwin-arm64:
- Start with the base (top-level) configuration
- Merge the
darwinplatform section (if present) - Merge the
darwin-arm64platform section (if present)
Each step builds on the previous result. More specific sections override less specific ones.
How values combine depends on the data type:
| Type | Behavior | Example |
|---|---|---|
| Maps (links, merge) | Deep merge: new keys are added, existing keys are replaced | Base links + darwin links |
| Scalars (link_strategy, hooks) | Replace: more specific value wins | copy overrides symlink |
| Lists (tags, requires) | Concatenate with deduplication | [editor] + [macos] = [editor, macos] |
# Base links
links:
init.lua: "@config/nvim/init.lua"
lua/: "@config/nvim/lua/"
platform:
darwin:
links:
clipboard.lua: "@config/nvim/lua/clipboard.lua"On macOS, the resolved links contain all three entries. The init.lua and lua/ entries come from the base, and clipboard.lua is added from the darwin section.
hooks:
post_install: scripts/install.sh
platform:
darwin:
hooks:
post_install: scripts/install-mac.shOn macOS, post_install is scripts/install-mac.sh. On other platforms, it remains scripts/install.sh.
package:
tags: [editor]
requires: [personal/zsh]
platform:
darwin:
tags: [macos]
requires: [personal/homebrew]On macOS, tags resolve to [editor, macos] and requires to [personal/zsh, personal/homebrew]. Duplicates are removed.
The platform block in a manifest can override links, hooks, requires, tags, overlay, merge, and link_strategy. See Dotfile.yaml Reference.
The platform block in the config can override core settings (link_strategy, conflict_strategy, backup). See config.yaml Reference.
Given this manifest on darwin-arm64:
package:
name: nvim
tags: [editor]
links:
init.lua: "@config/nvim/init.lua"
hooks:
post_install: scripts/install.sh
platform:
darwin:
links:
mac-clip.lua: "@config/nvim/lua/clipboard.lua"
hooks:
post_install: scripts/install-mac.sh
tags: [macos]
darwin-arm64:
links:
bin/nvim: "@bin/nvim"The resolved result:
| Field | Value |
|---|---|
| links | init.lua, mac-clip.lua, bin/nvim (3 entries) |
| hooks.post_install | scripts/install-mac.sh (darwin overrode base) |
| tags | [editor, macos] (concatenated, deduped) |
Note that darwin-arm64 did not override post_install again, so the darwin value persists.
Use the platforms field in the package block to restrict a package to specific platforms:
package:
name: aerospace
platforms: [darwin]This package is skipped during installation on non-macOS systems. Both OS (darwin) and OS-arch (darwin-arm64) identifiers are accepted. An empty or omitted platforms list means the package works on all platforms.
The Apple-family path aliases (@apple-config, @apple-data, @apple-cache, @apple-logs, @apple-launchagents) only resolve on darwin. On every other OS they return an error at resolution time, wrapping the sentinel dots.ErrAliasUnavailable.
Because the error fires at resolution rather than at parse time, scope Apple aliases properly:
- Inside a
platform.darwinblock, so non-darwin installs never see them. - Optionally combined with
package.platforms: [darwin]for a "double-locked" Mac-only package — theplatformsgate skips installation entirely, and theplatform.darwinblock keeps the Apple aliases out of the resolved manifest on other systems.
package:
name: my-launchagent
platforms: [darwin]
platform:
darwin:
links:
com.user.foo.plist: "@apple-launchagents/com.user.foo.plist"See Path Aliases for the full Apple family table.