Skip to content

Configuration Format

All examples have been validated on macOS 26 (Tahoe).

The CLI is fully free: every command works across all preference domains, with JSON output, headless apply, filtering, and rollback to any run available to everyone.

The simplest valid config requires version and domains:

{
"version": "1.0",
"domains": {
"com.apple.dock": {
"autohide": true,
"orientation": "left",
"show-recents": false
}
}
}
{
"version": "1.0",
"os": "26",
"domains": {
"com.apple.dock": {
"autohide": true,
"orientation": "left",
"show-process-indicators": false,
"show-recents": false,
"tilesize": 48,
"magnification": true,
"largesize": 96
},
"com.apple.finder": {
"AppleShowAllExtensions": true,
"ShowPathbar": true,
"FXEnableExtensionChangeWarning": false,
"FXPreferredViewStyle": "Nlsv"
},
"NSGlobalDomain": {
"AppleKeyboardUIMode": 3,
"com.apple.keyboard.fnState": true,
"AppleInterfaceStyle": "Dark"
}
}
}

Use extended form for arrays that should ignore order:

{
"version": "1.0",
"domains": {
"com.apple.finder": {
"FavoriteItems": {
"value": ["Applications", "Documents", "Downloads"],
"compare": "unordered",
"note": "Sidebar items - order doesn't matter"
}
}
}
}

Compare modes (validated in testing):

  • default or strict: Exact equality including array order
  • unordered: Arrays/dicts compared by content, ignoring order

All Unicode, emojis, and escape sequences are supported:

{
"version": "1.0",
"domains": {
"com.apple.TextEdit": {
"author": "日本語テスト",
"emoji-test": "🎉🚀💻",
"path-with-spaces": "/Users/test/My Documents/file.txt"
}
}
}

Configs with 100+ domains are supported with good performance (~73ms per domain):

{
"version": "1.0",
"domains": {
"com.apple.domain1": { "key1": "value1" },
"com.apple.domain2": { "key2": "value2" },
...
"com.apple.domain100": { "key100": "value100" }
}
}

Every config must have:

  1. "version": "1.0" - Config schema version
  2. "domains": { ... } - Map of domain names to key-value pairs

Optional fields:

  • "os": "26" - Target macOS version (informational)
Terminal window
# Export current Apple preferences
macprefs export my-prefs.json
# Review what would change
macprefs plan --config my-prefs.json
# Apply with interactive confirmation
macprefs apply --config my-prefs.json

filter turns a raw export into a clean, apply-safe config. It classifies every key with local guardrails (value-facts, name patterns, optional baseline diff) and writes a keep-only config plus a report of the skip/review keys:

Terminal window
# Export everything, then filter to a keep-only config + report
macprefs export raw.json
macprefs filter raw.json -o clean.json # writes clean.json + raw.report.txt
# Optional: use a baseline to detect intentionally-changed keys
macprefs filter raw.json -o clean.json --baseline baseline.json
# clean.json is immediately consumable by plan/apply
macprefs plan --config clean.json

filter exits 0 when nothing needs review, 2 when one or more keys are flagged for human review.

Given a raw export raw.json like this:

{
"version": "1.0",
"domains": {
"com.apple.dock": {
"autohide": true,
"trash-full": false,
"RecentApps-UUID": "1F2E-AA"
},
"com.apple.finder": {
"ShowPathbar": true,
"GoToField": "/Users/alice/Projects",
"FXRecentFolders": ["/Users/alice/Downloads"]
}
}
}

macprefs filter raw.json -o clean.json writes a keep-only config (clean.json) containing just the apply-safe keys (in the extended { "value": … } form, keys sorted):

{
"domains" : {
"com.apple.dock" : {
"autohide" : {
"value" : true
}
},
"com.apple.finder" : {
"ShowPathbar" : {
"value" : true
}
}
},
"version" : "1.0"
}

…plus a human-readable report (raw.report.txt) of the keys it set aside, each with its reason, source, and confidence:

macprefs filter report
======================
Input: raw.json
Baseline: (none)
Summary: 2 keep, 3 skip, 1 review
SKIP (3)
--------
[com.apple.dock]
RecentApps-UUID
reason: matches hard-skip pattern suffix("UUID")
source: pattern confidence: 1.00
[com.apple.finder]
FXRecentFolders
reason: an array element contains a user-specific path
source: valueFact confidence: 1.00
GoToField
reason: value contains a user-specific path
source: valueFact confidence: 1.00
REVIEW (1)
----------
[com.apple.dock]
trash-full
reason: uncertain — no signal
source: pattern confidence: 0.50

clean.json is immediately consumable by plan/apply/validate; the report is your audit trail for the keys that need a human decision (here trash-full has no deterministic signal, so it’s flagged for you rather than guessed). Since one key needs review, filter exits 2.

The recommended pipeline gates on validate, reports drift with plan, then enforces with apply — all license-free:

Terminal window
# 1. Gate: fail the build on an invalid config (exit 1)
macprefs validate --config my-prefs.json
# 2. Report drift (exit 2 = drift, informational)
macprefs plan --config my-prefs.json --format json
# 3. Enforce headlessly
macprefs apply --config my-prefs.json --yes
  • Shorthand form: Direct "key": value infers type from JSON
  • Extended form: "key": {"value": ..., "compare": "unordered", "note": "..."} for options
  • Managed-subset apply: Only listed keys are compared/applied; unlisted keys ignored
  • Domain scope: all preference domains are available
  • Types: JSON bool → plist integer (0/1), JSON number → plist integer/float, JSON string → plist string

Documentation auto-synced from macprefs configuration examples.