How to turn your macOS into a Linux-like Desktop

TLDR: This is NOT about installing Linux on a Mac! Who would do that? 😏

So, you got yourself a new Macbook. Maybe it was received from your employer or client, maybe you bought it yourself. But you were a GNU/Linux user for several years and the new environment seems too much different, even alien, and you have a choice to make: Adapt or Customize.

Adapting is the obvious choice and in a few weeks you can learn how to use the macOS UI, keyboard, and shortcuts. On the other hand, if you still own a (former) Linux machine and intend to switch between them very often, you might want to customize to have both environments looking and behaving the same way (or as close as possible).

This article includes a series of applications, tools, and configurations to make your Mac more Linux-like. Notice they are not a complete package and each option works independently, so feel free to choose one, a few, or all of them, according to your needs.

All the configurations here were based on macOS 14 — Sonoma, released on September 23, 2023. The setting and maybe even some tool compatibility may vary in other versions.

Using Homebrew package manager

A common tip you’ll ever find for new macOS users is to install Homebrew, which is a package manager very similar to apt or pacman and, while not that powerful, it is so useful that Apple should include it by default on any new Mac.

Homebrew is the top suggestion here because it will be used to install other apps in the following sections, so don’t miss this one. Visit brew.sh and follow the instructions, then get used to its commands by running brew help in your terminal.

Changing the macOS keyboard, shortcuts, and the Command key

The first difference you’ll notice on the new Mac when coming from Linux (and also Windows) is the keyboard layout, which replaces the modifier keys Alt for Option, and includes Command in place of Super/Windows.

While the first works almost exactly as its Linux/Windows counterpart, the Command key is nothing like Super and instead replaces the Ctrl key usage in most cases. The position of these modifier keys is also different, being Fn, Ctrl, Option, and Command on the left, and Command and Option on the right.

Swapping modifier keys

Gladly macOS allows to swap any of these keys, as well as the Caps Lock (often useless) in System Settings -> Keyboard -> Keyboard Shortcuts -> Modifier Keys. Just notice the change is per keyboard, so if you use an external keyboard, you might need to swap for both.

The general suggestion is to swap Ctrl and Command, so you can use most of the keyboard shortcuts without the need to change your muscle memory, but that comes with a caveat that it won’t work as expected for terminal applications (especially Tmux and Vim) — if you use terminal apps, continue reading and you’ll find an alternative below.

Using Linux-style word navigation keys

Another difference is that the word navigation keys do not work the same way. Either Command or Options is used to move the cursor across text, depending on the case, and Home and End don’t work at all.

We can, however, rewrite some keys in the ~/Library/KeyBindings/DefaultKeyBinding.dict file. To achieve the same behavior as Linux/Windows, create that file with the following content.

{
  "\UF729"  = moveToBeginningOfParagraph:;                    // home
  "\UF72B"  = moveToEndOfParagraph:;                          // end
  "$\UF729" = moveToBeginningOfParagraphAndModifySelection:;  // shift-home
  "$\UF72B" = moveToEndOfParagraphAndModifySelection:;        // shift-end
  "^\UF729" = moveToBeginningOfDocument:;                     // ctrl-home
  "^\UF72B" = moveToEndOfDocument:;                           // ctrl-end
  "^$\UF729" = moveToBeginningOfDocumentAndModifySelection:;  // ctrl-shift-home
  "^$\UF72B" = moveToEndOfDocumentAndModifySelection:;        // ctrl-shift-end
  "^\UF702" = moveWordLeft:;                                  // ctrl-left
  "^$\UF702" = moveWordLeftAndModifySelection:;               // ctrl-shift-left
  "^\UF703" = moveWordRight:;                                 // ctrl-right
  "^$\UF703" = moveWordRightAndModifySelection:;              // ctrl-shift-right
  "^\U7F" = deleteWordBackward:;                              // ctrl-backspace
  "^\UF728" = deleteWordForward:;                             // ctrl-delete
  "^/" = "noop:";                                             // ctrl-slash stops beep
}

The last one disables the beep when typing Ctrl+/ on a terminal, which may come in handy if you use that shortcut for commenting lines in Vim, for example. My full config, including some comments, can be found in my dot-files DefaultKeyBinding.dict. For more information about those methods, check the documentation for nsstandardkeybindingresponding.

Once you have created/edited this file, log out and in again to load the changes.

Unfortunately, some applications or even websites redefine keyboard shortcuts, so the settings above may not work everywhere.

Creating custom shortcuts with SKHD

If you want custom shortcuts, macOS default settings in System Settings -> Keyboard -> Keyboard Shortcuts are a bit limited, not allowing you to run a command, for example, unless you create some complex macros with Automator. But we can always use a third-party app for shortcuts, and SKHD is a simple yet powerful one.

Just install and start with:

brew install koekeishiya/formulae/skhd
skhd --start-service

and then you can configure the keyboard shortcuts on the ~/.config/shkd/skhdrc file.

Two interesting features of SKHD are that you can create aliases for other shortcuts, and limit them for specific apps. With SKHD you can, for example, use the Ctrl key for general tasks such as copy, paste, open a new tab, etc. This works as an alternative to swapping the Ctrl and Command keys mentioned above.

ctrl - c [
  "firefox" : skhd -k "cmd - c"
  "google chrome" : skhd -k "cmd - c"
  "safari" : skhd -k "cmd - c"
]

ctrl - v [
  "firefox" : skhd -k "cmd - v"
  "google chrome" : skhd -k "cmd - v"
  "safari" : skhd -k "cmd - v"
]

My full SKHD config can be found at my dotfiles, so you can use it as a reference, or simply read their documentation and examples.

Changing mouse/touchpad behavior

macOS uses natural scroll by default, which means that it inverts up/down scroll to mimic a touchscreen. The option can be disabled at System Settings -> Mouse, but turning it off also affects the horizontal scroll (which doesn’t make any sense).

If you also need horizontal scroll, one option is to install Scroll Reverser, a free app that allows you to swap either vertical or horizontal scroll independently and can be installed with Homebrew.

brew install --cask scroll-reverser

Middle click paste

Unfortunately, there isn’t a definitive solution yet to enable middle click paste for selected text, such as Xorg/Wayland default behavior, and while there are some alternatives, none has the same behavior we have on Linux.

As a workaround, terminal emulators such as iTerm2, Kitty, or Alacritty can mimic this behavior, allowing you to easily copy/paste inside the terminal.

For Alacritty, you just need to enable selection.save_to_clipboard in .config/alacritty/alacritty.yml

selection:
  save_to_clipboard: true

Managing Windows and Workspaces

Using multiple workspaces allows to organize windows making them accessible in fixed positions, making it easier to swap windows faster without the need to navigate across them with Command + Tab.

macOS has built-in virtual desktops support, called Spaces, much like any Linux WM. To view, rearrange, create, or delete Spaces we use Mission Control, accessible with CMD + Up. Its configuration can be found in System Settings -> Desktop & Dock -> Mission Control and its keyboard shortcuts are in the same section and in System Settings -> Keyboard -> Keyboard Shortcuts... -> Mission Control. Once Spaces are created, you can assign shortcuts to move straight to them (e.g. Cmd+1, Cmd+2...).

If you have multiple monitors/screens, Spaces are per-screen, which means you have as many as you want on each monitor.

Using a Tiling Window Manager

To use tiling windows like many available for Linux, the solution is to use a third-party application. We have a few options available, from the simplest to more advanced. Most of them can be installed using brew (only AeroSpace can’t).

  • Rectangle app

    Not really a TWM, Rectangle simply allows to use keyboard shortcuts and snap areas to move and resize windows, much like default Gnome behavior. Not fully featured, but enough for some users.

  • Amethyst

    While still very simple, Amethyst has all the basic features of a full TWM without getting in the way of macOS standards and it is configured through a preferences window accessible through the menubar.

  • Yabai

    Now we’re getting serious. Yabai is a fully featured TWM which reminds me a lot of i3 or Sway. It is configured through a shell script and, while it lacks keyboard shortcuts of its own, we can easily use another app (recommended is skhd, mentioned above) for that.

    I decided to use Yabai after testing the other options because it provides a more similar experience to what I am used to. My suggestion is to try each to find which is best for you. My yabai configuration can be found in my dot-files repository.

  • AeroSpace

    A new option, created last year and under active development is AeroSpace. While it might be not as full-featured as Yabai, it is very promising, having already a lot of features and its own keybindings implementation.

Dropdown terminal

If you like a quickly accessible terminal app always at hand, you can use a Dropdown Terminal (a.k.a. Quake mode). Which shows a floating terminal window on the top of the screen at a simple shortcut (e.g. Ctrl + Esc).

There are plenty of options on the market, some even built-in with your terminal app. I created one myself using the tools at hand, in my case Yabai, SKHD, and Alacritty. The config is as follows.

# ~/.config/yabai/yabairc

# dropdown terminal (aka "Quake mode")
# see additional config in ~/.config/skhd/skhdrc
yabai -m rule --add title="ddterm" manage=off grid="10:1:0:0:1:4"
# ~/.config/skhd/skhdrc

# dropdown terminal (aka "quade mode")
# see additional config in ~/.config/yabai/yabairc
ctrl - escape : WINDOW_TITLE="ddterm";                                                                                      \
                WINDOW_ID=$(yabai -m query --windows | jq -e ".[] | select(.title==\"$WINDOW_TITLE\") | .id");              \
                if [ -z "$WINDOW_ID" ]; then                                                                                \
                  pgrep -x alacritty > /dev/null &&                                                                         \
                  alacritty msg create-window --title "$WINDOW_TITLE" ||                                                    \
                  open -na /Applications/Alacritty.app --args --title "$WINDOW_TITLE";                                      \
                else                                                                                                        \
                  DISTANCE=$(yabai -m query --windows --window "$WINDOW_ID" | jq -e '[ .frame.y, .frame.h ] | add');        \
                  if [ "$DISTANCE" -gt 0 ]; then                                                                            \
                    yabai -m window "$WINDOW_ID" --move abs:0:-"$DISTANCE" --layer below --focus mouse;                     \
                  else                                                                                                      \
                    yabai -m window "$WINDOW_ID" --space mouse --move abs:0:0 --grid "10:1:0:0:1:4" --layer above --focus;  \
                  fi;                                                                                                       \
                fi;                                                                                                         \

Docker with Colima

Docker is a required tool for backend developers, but coming from Linux, the Docker for Mac app is a nuisance due to the requirement of a desktop app and menubar item.

Fortunately, we can use Colima (Container runtimes on MacOS) which is a shell-only application and service and works exactly as running Docker on Linux from the terminal.

Note: If you have previously installed Docker Desktop, you must first completely uninstall it before start using Colima.

Follow the steps below to install and enable Docker and Docker Compose using Colima.

# install colima
brew install colima

# install docker client
brew install docker

# install docker-compose and link to docker plugins
brew install docker-compose
mkdir -p ~/.docker/cli-plugins
ln -sfn /opt/homebrew/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose 

# install docker-buildx and link to docker plugins
brew install docker-buildx
mkdir -p ~/.docker/cli-plugins
ln -sfn /opt/homebrew/opt/docker-buildx/bin/docker-buildx ~/.docker/cli-plugins/docker-buildx

# start colima, which defaults to docker runtime
brew services start colima

Conclusion

So, this sort of finishes our tips and tricks to Turn your Mac into a Linux Desktop. Hopefully, it will help you to use a Mac with fewer challenges when coming from Linux.

This article may be updated or expanded in the future, with new tools and configuration suggestions, as I find new ways to use my Mac. However, as I said before, it is up to you to decide which ones to use, or just ignore them altogether and get used to macOS defaults.

References

We want to work with you. Check out our "What We Do" section!