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:
[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
mise bootstrap macos defaults status
mise bootstrap macos defaults apply --dry-run
mise bootstrap macos defaults applyApply 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:
| Key | Raw default |
|---|---|
autohide_delay | com.apple.dock.autohide-delay |
autohide_time_modifier | com.apple.dock.autohide-time-modifier |
autohide | com.apple.dock.autohide |
orientation | com.apple.dock.orientation |
tilesize | com.apple.dock.tilesize |
magnification | com.apple.dock.magnification |
largesize | com.apple.dock.largesize |
show_recents | com.apple.dock.show-recents |
mru_spaces | com.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:
| Key | Raw default |
|---|---|
sort_folders_first | com.apple.finder._FXSortFoldersFirst |
save_new_documents_to_cloud | NSGlobalDomain.NSDocumentSaveNewDocumentsToCloud |
show_all_files | com.apple.finder.AppleShowAllFiles |
show_pathbar | com.apple.finder.ShowPathbar |
show_status_bar | com.apple.finder.ShowStatusBar |
show_extensions_warning | com.apple.finder.FXEnableExtensionChangeWarning |
preferred_view_style | com.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:
| Key | Raw default |
|---|---|
automatic_capitalization | NSGlobalDomain.NSAutomaticCapitalizationEnabled |
automatic_spelling_correction | NSGlobalDomain.NSAutomaticSpellingCorrectionEnabled |
key_repeat | NSGlobalDomain.KeyRepeat |
initial_key_repeat | NSGlobalDomain.InitialKeyRepeat |
press_and_hold | NSGlobalDomain.ApplePressAndHoldEnabled |
fn_state | NSGlobalDomain.com.apple.keyboard.fnState |
[bootstrap.macos.trackpad] supports:
| Key | Raw defaults |
|---|---|
tap_to_click | com.apple.AppleMultitouchTrackpad.Clicking, com.apple.driver.AppleBluetoothMultitouch.trackpad.Clicking |
three_finger_drag | com.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:
[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 value | property-list type | example |
|---|---|---|
| boolean | boolean | autohide = true |
| integer | integer | tilesize = 48 |
| float | real | scale = 1.5 |
| string | string | orientation = "left" |
| array | array | favorite-spaces = [1, 2, 3] |
| table | dictionary | options = { 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:
[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 statusandmise doctorlist the entries as skipped (so nothing is silently invisible) andmise bootstrap macos defaults applyignores 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 applyor the fullmise bootstrapdoes, 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
1does not satisfy a configuredtrue.mise bootstrap macos defaults applyconverges 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:
[[bootstrap.macos.defaults_entries]]
domain = "NSGlobalDomain"
key = "com.apple.mouse.tapBehavior"
host = "current"
value = 1Entries 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:
[[bootstrap.macos.defaults_entries]]
domain = "com.apple.symbolichotkeys"
key = "AppleSymbolicHotKeys"
path = ["64", "enabled"]
value = falseEach 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
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 promptmise 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:
killall Dock
killall Finder
killall SystemUIServermise 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:
[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:
defaults read com.apple.dock
defaults read-type com.apple.dock tilesize