Warning
Although cutler is solid enough for daily-driving now, expect breaking changes before the v1 release.
Important
The prebuilt binaries are compiled and shipped from macOS 14 on arm64. Intel Macs will require a manual compilation of the project.
cutler simplifies macOS configuration by letting you manage system settings through a single TOML file instead of clicking through System Settings or typing complex defaults commands in the terminal.
Define your settings once, then easily apply, track, and revert changes across your system—think of it as infrastructure-as-code for your Mac.
Check out the Usage section for more details.
- Install cutler using 🍺 Homebrew:
brew install hitblast/tap/cutler
Besides using Homebrew as shown above, you can install the project in a couple of other ways:
- Using
cargo
:
cargo install cutler
- Using
mise
:
# NOTE: This will compile the binary manually for your system.
mise use -g cargo:cutler
Tip
If none of these installation methods work for you, try checking out the latest GitHub release. You can also use the periodic release workflows, which have a retention period of 90 days.
cutler
looks for your configuration in a file named config.toml
, checking the following locations in order:
$XDG_CONFIG_HOME/cutler/config.toml
~/.config/cutler/config.toml
~/.config/cutler.toml
config.toml
in the current directory (fallback)
It respects your $XDG_CONFIG_HOME
setting, so you don't have to worry about
path issues. Just place your config.toml
file in one of these locations and
you're set.
To easily get started, simply type the following command to generate a prebuilt configuration:
cutler init
Here’s a basic example of a TOML configuration for cutler:
[dock]
tilesize = 46
[menuextra.clock]
FlashDateSeparators = true
For more details on the different defaults
domains and available values on
macOS, take a look at the Resources section. The TOML above
translates into these commands:
defaults write com.apple.dock "tilesize" -int "46"
defaults write com.apple.menuextra.clock "FlashDateSeparators"
You can also configure settings for NSGlobalDomain
like this:
[NSGlobalDomain]
ApplePressAndHoldEnabled = true
[NSGlobalDomain.com.apple.mouse]
linear = true
cutler
converts the above TOML into:
defaults write NSGlobalDomain "ApplePressAndHoldEnabled" -bool true
defaults write NSGlobalDomain com.apple.mouse.linear -bool true
Warning
Currently, cutler does not verify the integrity of domains or keys under NSGlobalDomain
. Please review these settings manually before applying any changes.
cutler also supports running external shell commands the moment it applies the defaults. You can define commands with simple syntax like this:
[external]
[[external.command]]
cmd = "echo \"Hello World\""
This translates to running:
echo "Hello World"
For more complex scenarios, you can use a more advanced structure with separate arguments and variables:
# Define reusable variables here:
[external.variables]
common_args = ["Hello", "World"]
[external]
[[external.command]]
cmd = "echo"
# If you reference a variable (for example, $common_args) and it isn't defined
# in the [external.variables] section, cutler will fall back and try to resolve it
# from the environment (e.g. $PATH).
args = ["$common_args", "$PATH"]
sudo = false
This roughly translates to:
echo Hello World /usr/local/bin:/usr/bin:...
Once your configuration file is ready (including your defaults and external commands), apply your settings by running:
cutler apply
After cutler
updates the defaults, it will also:
- Execute any external commands defined in the
[external]
section. - Restart necessary system services on your Mac so that the new settings take effect.
- Create a snapshot file named
.cutler_snapshot
in your home directory. This file records your configuration state and helps with reverting later on.
To verify current settings against your configuration, run:
cutler status
To revert modifications, run:
cutler unapply
Now, when it comes to managing the configuration file itself, there is a config
command which has two other subcommands:
# Shows the contents of the configuration file.
cutler config show
# Unapplies and deletes the configuration file.
cutler config delete
You can add --verbose
for more detail on what happens behind the scenes. For
additional information about all available commands, run:
cutler help
cutler currently supports automatically generating shell completions for Bash and Zsh, making it easier to use the project for power users.
# For bash users
cutler completion bash
# For zsh users
cutler completion zsh
# Specify a different output directory:
cutler completion bash --dir ~/.local/share/bash-completion/completions
cutler completion zsh --dir ~/.zfunc
Assuming you've generated the completion script using the command given above, you can source it like this for temporary use:
source ./cutler.bash
For permanent use, add to your ~/.bashrc
:
source /path/to/cutler.bash > ~/.bashrc
- Make sure you have a directory for custom completions:
mkdir -p ~/.zfunc
- Assuming you've already generated the configuration file from the command given above, you can copy the completion file:
cp _cutler ~/.zfunc/
- Then, add to your
~/.zshrc
:
fpath=(~/.zfunc $fpath)
autoload -U compinit && compinit
- Restart your shell or run:
source ~/.zshrc
Finding the ideal set of macOS defaults can be challenging. Visit this website to have a look at some useful ones fast: macOS defaults website
Sample configuration files are preincluded with this repository for you to have a look at and get hold of the tool quickly: see examples
This is a personal project aimed at making the task of setting up a Mac more straightforward. Contributions are always welcome! Feel free to help out by creating a pull request or submitting an issue.
This project is licensed under the MIT License.