Change macOS user preferences via command line
The System Preferences window is not the only way to adjust user settings. Macs come with a defaults
command line interface that lets you read, write, and delete macOS user defaults. You may have even used it before — revealing hidden files in Finder is a popular snippet (hot tip: ⌘
+ ⇧
+ .
is quicker).
defaults write com.apple.finder AppleShowAllFiles -string YES
Let’s take it apart to get familiar with the terminology used throughout this article:
defaults
- interfacewrite
- methodcomapple.finder
- domainAppleShowAllFiles
- key-string
- type descriptorYES
- new value
You may be scratching your head asking yourself — why the hell would I prefer to do it through the command line instead of using a nice looking GUI (graphical user interface) to change things? Two reasons! A command line way gives you access to things that you cannot change via graphical panels (toggling hidden files is a perfect example). The next one is even better — do you remember last time when you had to set up a new computer from scratch? Change the settings, add a desktop background, disable the screen saver, download your favourite software etc. How long do you spend on these tasks? Two hours? Four? Ten? I spent about five minutes. Boom!
Write, read and delete defaults settings
The defaults
interface isn’t complicated to use and comes equipped with just a few methods:
read
- prints current user settingsread-type
- prints the type of given keywrite
- writes new settingsdelete
- deletes a key or a full domaindomains
- prints the full list of domainsfind
- searches all domain and keys for a given namehelp
- I’m sure you know what this does
Domains — system components and installed apps
Printing all the domains via defaults domains
is a very helpful way to check what actually can be changed. Domains are objects that contain settings for a particular system component, installed application or a configuration .plist
file located in /Library/Preferences/
.
defaults domains
...com.apple.ActivityMonitor, com.apple.AddressBook, com.apple.Console, com.apple.DiskUtility, com.apple.FontBook, com.apple.Image_Capture, com.apple.Maps, com.apple.Messages, com.apple.Notes...
Making the output of domains a little bit cleaner
If you (like me) are not a big fan of the comma separated output of defaults domains
, you can pipe it through a translate command to make the output much easier to read.
defaults domains | tr ',' '\n'
...
com.apple.ActivityMonitor
com.apple.AddressBook
com.apple.Console
com.apple.DiskUtility
com.apple.FontBook
com.apple.Image_Capture
com.apple.Maps
com.apple.Messages
com.apple.Notes
...
A basic workflow to amend user defaults
The idea is to traverse through any domains that we would like to change and compose a command that overrides the current setting. Let’s say we would like to find the command to change spell checking inside the Notes app. The workflow would look something like this:
- Print the settings for the notes app to find the right key.
- Check the value type for a given key.
- Write new settings.
defaults read com.apple.Notes
defaults read-type com.apple.Notes NotesContinuousSpellCheckingEnabled
defaults write com.apple.Notes NotesContinuousSpellCheckingEnabled -bool true
As you can see it is not that complicated. Bear in mind that some changes require you to restart an app or, occasionally, a full reboot of the operating system. A good idea is to close an app before changing any of its settings via the command line.
The way to find the domain & key responsible for a setting
Browsing through the output of a defaults read
command or browsing uncle Google for the correct domain and key can be a daunting task. Luckily you can easily find it out by yourself. Good old diff
to the rescue!
- Save a state before a change.
- Make a change through GUI.
- Save a state after a change.
- Find the difference.
defaults read > before
defaults read > after
diff before after
Reading output of the default diff
command isn’t exactly enjoyable so feel free to use any other diff tool. Time for a hot tip now! Visual Studio Code, apart from being really cool code editor, is a fantastic diff tool. Just have a look!
code --diff before after

My defaults tweaks
I actively maintain a list of settings that I change on my machine and you can find it on my dotfiles repository on Github. It isn’t too complex so if you are looking for a real ninja-level defaults tweaks example look at Mathias Bynens one.
Hopefully this article helped you to embrace the power of the defaults command. Share in the comments below your favourite defaults tweaks and stay tuned as more tutorial articles like this one are coming soon. Until next time.
Excellent post - just what I was after. You, sir, are a steely-eyed missile man......
Thanks a lot for reading. Have a great day :)
Have you tried wrangling the modifier keys using this technique?
For example, mapping the caps lock to control, using the diff method, I'm not able to interpret the results:
https://uploads.disquscdn.c...
Sorry but I don't have any experience with things like that. Interesting use case though.
You can use Karabiner Elements to do this
Is it possible to set notification settings for apps using the command line?
Aww yes this looks like the one: https://github.com/jacobsal... - however it doesn't support latest macOS, so I'm holding out for that.
Sorry, I am helpless here :( I have no experience with that.
Thanks for the post! I'm automating my Mac setup and this is exactly what I wanted.
hey, that was awesome, thank you so much!
you might consider changing your first example, that exact key seems not to exist anymore in 10.14.1, unless I'm confused or wrong
and another benefit of changing this from shell you might want to put there is that you can put it in a script that needs a certain setting to work correctly
[I came searching for this for my alarm clock setup that needs the Power -> Schedule setting]
Very good spot with this first example. Personally I always use keyboard shortcut so I haven't even noticed.
Thanks for reading and great suggestions.
Hi can you change a privacy setting in System Preferences using Terminal?
Hi, thanks for you sharing, I got a setting like this:
{
"test1"=1;
"test2" = (
"prop"=1;
"prop2"=2;
)
}
How to update
prop2
?I am more than happy to help you with this one but you need to provide a full domain command that you have used to read this value. It should not be difficult, but I need some more context.
thanks for your reply, actually, I used font-icons in my terminal, so I should to set the correct font for terminal, like iTerm2, it can be configured in preference manually, but after I get its domain info, I found the setting item is in an object-array like
"New Bookmarks"=( { font="xxx"; other="ssxx" }, { etc... } );
there are so many settings in every object, so now no matter use array or array-add are not easy to do it.Great write up... I have struggled with this on numerous attempts and this time I hit 3 websites, each better than the last and this was the last. Thanks for sharing!!
Thanks a lot for a kind word. I am glad it helped you out.
Hey, I tried your diffing technique when changing certain shortcut settings. However, the diff only shows 'enabled = 1' to 'enabled = 0'. It doesn't show which setting is changed, is there any way to check which one it is? The settings I'm trying to change is Keyboard > Shortcuts > Accessibility > Turn VoiceOver on or off.
Yeah, I know it is not the best user experience. I tend to use some diff tool — Visual Studio Code has one built-in that works like a charm for me. You need to climb up the tree and check which flag has been changed.
Nice article Pawel. 👍 I was looking for some commands to set Macs up remotely and this looks like it will do the trick nicely. I particularly like the diff tip, that’s a handy way to find obscure settings. 😃