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.
Minimal Config
Section titled “Minimal Config”The simplest valid config requires version and domains:
{ "version": "1.0", "domains": { "com.apple.dock": { "autohide": true, "orientation": "left", "show-recents": false } }}Full Example (Multiple Domains)
Section titled “Full Example (Multiple Domains)”{ "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" } }}Extended Form with Compare Hints
Section titled “Extended Form with Compare Hints”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):
defaultorstrict: Exact equality including array orderunordered: Arrays/dicts compared by content, ignoring order
Special Characters
Section titled “Special Characters”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" } }}Large Configs
Section titled “Large Configs”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" } }}Required Fields
Section titled “Required Fields”Every config must have:
"version": "1.0"- Config schema version"domains": { ... }- Map of domain names to key-value pairs
Optional fields:
"os": "26"- Target macOS version (informational)
Workflow Examples
Section titled “Workflow Examples”Export and Apply
Section titled “Export and Apply”# Export current Apple preferencesmacprefs export my-prefs.json
# Review what would changemacprefs plan --config my-prefs.json
# Apply with interactive confirmationmacprefs apply --config my-prefs.jsonFilter Ephemeral Keys
Section titled “Filter Ephemeral Keys”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:
# Export everything, then filter to a keep-only config + reportmacprefs export raw.jsonmacprefs filter raw.json -o clean.json # writes clean.json + raw.report.txt
# Optional: use a baseline to detect intentionally-changed keysmacprefs filter raw.json -o clean.json --baseline baseline.json
# clean.json is immediately consumable by plan/applymacprefs plan --config clean.jsonfilter 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.jsonBaseline: (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.50clean.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.
CI/CD Workflow
Section titled “CI/CD Workflow”The recommended pipeline gates on validate, reports drift with plan, then
enforces with apply — all license-free:
# 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 headlesslymacprefs apply --config my-prefs.json --yes- Shorthand form: Direct
"key": valueinfers 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.