Skip to content

macOS Defaults

mise can declare macOS user defaults (preferences) in the [bootstrap.macos.defaults] section of mise.toml and apply them with mise bootstrap macos defaults apply or as part of mise bootstrap:

toml
[bootstrap.macos.dock]
autohide = true
orientation = "left"
tilesize = 48
show_recents = false

[bootstrap.macos.finder]
show_all_files = true
show_pathbar = true
preferred_view_style = "list"

[bootstrap.macos.keyboard]
key_repeat = 2
initial_key_repeat = 15
press_and_hold = false

[bootstrap.macos.trackpad]
tap_to_click = true

[bootstrap.macos.defaults]
"com.apple.finder" = { AppleShowAllFiles = false }

Friendly settings and raw defaults share the same preference keys. Use [bootstrap.macos.defaults] for preferences not covered by the friendly sections. Within the same config file, raw defaults override the raw (domain, key) generated by a friendly setting. Across config files, the normal global-to-local precedence still applies, so a local friendly setting can override a global raw default for the same pair.

Preview and apply

sh
mise bootstrap macos defaults status
mise bootstrap macos defaults apply --dry-run
mise bootstrap macos defaults apply

Apply as the user whose preferences should change. Choose either a friendly key or a raw entry for each preference unless you intentionally need an override. The example sets friendly show_all_files = true and raw AppleShowAllFiles = false to demonstrate that the raw entry wins within the same file.

Friendly sections

[bootstrap.macos.dock] supports:

KeyRaw default
autohide_delaycom.apple.dock.autohide-delay
autohide_time_modifiercom.apple.dock.autohide-time-modifier
autohidecom.apple.dock.autohide
orientationcom.apple.dock.orientation
tilesizecom.apple.dock.tilesize
magnificationcom.apple.dock.magnification
largesizecom.apple.dock.largesize
show_recentscom.apple.dock.show-recents
mru_spacescom.apple.dock.mru-spaces

autohide_delay and autohide_time_modifier accept integers or floats, such as 0 and 0.5.

orientation must be bottom, left, or right.

[bootstrap.macos.finder] supports:

KeyRaw default
sort_folders_firstcom.apple.finder._FXSortFoldersFirst
save_new_documents_to_cloudNSGlobalDomain.NSDocumentSaveNewDocumentsToCloud
show_all_filescom.apple.finder.AppleShowAllFiles
show_pathbarcom.apple.finder.ShowPathbar
show_status_barcom.apple.finder.ShowStatusBar
show_extensions_warningcom.apple.finder.FXEnableExtensionChangeWarning
preferred_view_stylecom.apple.finder.FXPreferredViewStyle

save_new_documents_to_cloud controls the default save location globally for application save dialogs, even though it is grouped under finder.

preferred_view_style must be icon, list, column, or gallery.

[bootstrap.macos.keyboard] supports:

KeyRaw default
automatic_capitalizationNSGlobalDomain.NSAutomaticCapitalizationEnabled
automatic_spelling_correctionNSGlobalDomain.NSAutomaticSpellingCorrectionEnabled
key_repeatNSGlobalDomain.KeyRepeat
initial_key_repeatNSGlobalDomain.InitialKeyRepeat
press_and_holdNSGlobalDomain.ApplePressAndHoldEnabled
fn_stateNSGlobalDomain.com.apple.keyboard.fnState

[bootstrap.macos.trackpad] supports:

KeyRaw defaults
tap_to_clickcom.apple.AppleMultitouchTrackpad.Clicking, com.apple.driver.AppleBluetoothMultitouch.trackpad.Clicking
three_finger_dragcom.apple.AppleMultitouchTrackpad.TrackpadThreeFingerDrag, com.apple.driver.AppleBluetoothMultitouch.trackpad.TrackpadThreeFingerDrag

Unknown friendly keys, invalid enum values, and unsupported value types produce a warning and are ignored.

Dock applications

Declare pinned applications in order with apps:

toml
[bootstrap.macos.dock]
apps = [
  "/System/Applications/Utilities/Terminal.app",
  "/Applications/Firefox.app",
  "~/Applications/Example.app",
]

Paths must be absolute or start with ~/, end in .app, and contain no .. components. Duplicate paths, including symlinks to the same application, are rejected. Every declared application must exist as a directory before a changed layout can be applied. Omit apps to leave the layout alone; apps = [] removes all recognised application tiles.

The list owns the applications pinned in com.apple.dock's persistent-apps preference. Apply adds, removes, and reorders those applications while preserving existing tiles' bookmarks and metadata. Symlinks are resolved when matching applications; new tiles retain the declared path. Non-application and unrecognised tiles are preserved, and persistent-others is untouched. Running unpinned apps and the recent-app section are outside this list.

Status compares application paths and order, so metadata added by Dock does not cause drift. Moving a pinned app manually does cause drift; apply restores the declared order. There is no capture or synchronization operation.

The usual precedence applies: raw persistent-apps overrides apps in the same file, and more local configuration wins across files. A winning raw declaration keeps exact plist comparison and whole-value replacement. defaults_entries has its usual precedence over shorthand defaults in the same file.

As with other Dock preferences, mise does not restart Dock. Relaunch it after applying when convenient (killall Dock), or use the existing post-defaults hook described below.

Raw defaults

Each key under [bootstrap.macos.defaults] is a preferences domain. Quote domains containing dots. TOML values map to property-list types as follows:

TOML valueproperty-list typeexample
booleanbooleanautohide = true
integerintegertilesize = 48
floatrealscale = 1.5
stringstringorientation = "left"
arrayarrayfavorite-spaces = [1, 2, 3]
tabledictionaryoptions = { enabled = true }

Arrays and tables are converted recursively, so nested values retain their types. For example, a Dock entry can be declared as an array of dictionaries:

toml
[bootstrap.macos.defaults."com.apple.dock"]
"persistent-apps" = [
  { "tile-type" = "file-tile", "tile-data" = { "file-label" = "Terminal" } },
]

The configured value replaces the entire preference value; arrays and dictionaries are not merged element-by-element. TOML dates and times are not supported and are skipped with a warning. Binary plist data has no native TOML type and is also not supported.

Semantics

[bootstrap.macos.defaults] follows the same rules as [bootstrap.packages]:

  • Declarative and additive — (domain, key) pairs merge across the config hierarchy (global → project) as a union; a more local config overrides the value of a pair the global config declared but cannot remove it. mise never deletes a default.
  • OS-filtered — on anything other than macOS the section is inert: mise bootstrap macos defaults status and mise doctor list the entries as skipped (so nothing is silently invisible) and mise bootstrap macos defaults apply ignores them, so a shared config authored for both Linux and macOS works as is.
  • Manual application only — mise never writes defaults implicitly; only mise bootstrap macos defaults apply or the full mise bootstrap does, after the usual confirmation prompt.
  • Strictly typed — an existing value only counts as in sync when both the value and the plist type match: an integer 1 does not satisfy a configured true. mise bootstrap macos defaults apply converges it to the typed value.

User defaults are per-user, so unlike system packages they never involve sudo. sudo defaults system domains are not supported.

Current-host preferences

Use an explicit entry for preferences normally written with defaults -currentHost:

toml
[[bootstrap.macos.defaults_entries]]
domain = "NSGlobalDomain"
key = "com.apple.mouse.tapBehavior"
host = "current"
value = 1

Entries accept the same typed values as defaults, including arrays and tables. The optional host is "any" by default; "current" scopes reads, writes, and synchronization to the current host. The same domain and key can be managed independently in each scope.

Preferences merge global → local by domain, key, and host. Explicit entries override shorthand defaults in the same file. The global-domain aliases -g and -globalDomain share the identity of NSGlobalDomain.

Status labels current-host domains with (current host) and JSON entries include host. Scalar dry-runs include -currentHost.

Targeted dictionary updates

Add path to a defaults entry to manage a nested value in a shared dictionary without replacing its siblings. For example, disable one symbolic shortcut while retaining its parameters and the other shortcuts:

toml
[[bootstrap.macos.defaults_entries]]
domain = "com.apple.symbolichotkeys"
key = "AppleSymbolicHotKeys"
path = ["64", "enabled"]
value = false

Each path component is a literal dictionary key, so dots in a component are not separators. The path must contain at least one component. value accepts the same types as defaults and replaces the selected value in full, including when that value is an array or dictionary. Array indices are not supported.

Paths work with both host = "any" (the default) and host = "current". Mise reads the existing plist in the selected host scope, applies the patches, and writes the updated value. Unselected values retain their types, including data and dates. Missing parent dictionaries are created; an existing scalar or array along the path is an error. Status compares only the selected value, and dry-run output shows its path.

Declarations with the same domain, key, host, and path merge global → local, with the last value winning. Ancestor/descendant patches, or a patch and a whole-value declaration for the same preference and host, are rejected before writing. All patched values are prepared before the first preference write. As with other preferences, applications may change a value concurrently; this is not an atomic transaction with those applications.

Commands

sh
mise bootstrap macos defaults status            # shows defaults drift
mise bootstrap macos defaults status --missing  # exit 1 if anything is unset or differs

mise bootstrap macos defaults apply           # writes unset/differing defaults
mise bootstrap macos defaults apply --dry-run # print the planned preference writes
mise bootstrap macos defaults apply --yes     # skip the confirmation prompt

mise bootstrap macos defaults status reports each entry as set (matches), differs (a value exists but doesn't match — the current value is shown), or unset. mise doctor summarizes the same drift.

App restarts

Some applications only pick up changed defaults after a relaunch — mise prints a reminder after writing, and top-level mise bootstrap includes the same reminder in its final follow-up summary. The usual suspects:

sh
killall Dock
killall Finder
killall SystemUIServer

mise deliberately does not kill applications itself. After mise bootstrap writes defaults, the follow-up summary reminds you to relaunch; a common post-defaults hook is:

toml
[bootstrap.hooks.post-defaults]
run = "killall Dock || true"

The stored value may already match while Dock or Finder still displays its previous behavior. Check status, then relaunch the affected app when convenient. A post-defaults hook runs on every selected bootstrap, even when no preference changed; use the manual commands above when that is not desirable.

Finding keys

To discover a setting's domain and key, change it in System Settings and diff the output of defaults read before and after, or read a domain directly:

sh
defaults read com.apple.dock
defaults read-type com.apple.dock tilesize
MIT LicenseCopyright © 2026jdx.dev