Split View: 2026 macOS 개발자 생산성 스택 — Raycast·Karabiner·Hammerspoon·Homebrew·Ghostty 심층 가이드
2026 macOS 개발자 생산성 스택 — Raycast·Karabiner·Hammerspoon·Homebrew·Ghostty 심층 가이드
프롤로그 — Spotlight를 끄던 날
2022년쯤 나는 Spotlight를 껐다. 정확히는 cmd-space를 Raycast로 옮겼고, 다시는 돌아가지 않았다. 그게 시작이었다.
생산성 스택이라는 말은 좀 거창하지만, 실제로는 단순하다. 하루에 수백 번 누르는 키, 매일 띄우는 창, 매주 손대는 설정 파일을 자동화·표준화하는 도구 묶음이다. 2026년의 macOS는 이게 어느 때보다 잘 작동한다. Raycast는 Spotlight를 완전히 대체했고, Ghostty는 iTerm2의 자리를 빠르게 가져가고 있고, AeroSpace는 i3 사용자가 macOS로 넘어올 때 사라졌던 마지막 변명을 없앴다. Homebrew는 brew bundle로 새 맥 셋업을 선언적으로 만들었고, mise는 asdf의 후계자가 되었다.
이 글은 "여기 좋은 도구 10개" 식의 리스트가 아니다. 각 도구가 왜 그 자리에 있고, 어떤 도구를 무엇으로 대체했고, 어떻게 서로 맞물리는지 — 구체적인 설정과 함께 — 다룬다. 끝에는 "최소 생산성 스택" 한 줄을 남긴다.
1장 · 런처 — Raycast가 Spotlight를 대체했다
1.1 왜 Spotlight로는 부족한가
Spotlight는 검색기다. Raycast는 명령 팔레트다. 이 차이가 모든 것을 결정한다.
Spotlight로 "Slack을 띄운다"는 동작은 가능하지만, "지금 켜진 Slack 창에서 #ops 채널을 연다"는 안 된다. "오늘 새벽 2시 14분에 저장한 Figma 파일을 연다", "현재 클립보드를 base64로 인코딩한다", "Linear에서 내가 어제 만든 티켓을 띄운다" — 이것도 안 된다. Raycast는 다 된다. 확장(extension) 이라는 단일 모델로.
1.2 Raycast의 2026년 상태
2026년 5월 기준 Raycast Store에는 1,300개 이상의 확장이 있다. GitHub, Linear, Jira, Notion, Slack, VS Code, Docker, Figma, AWS, Vercel — 거의 모든 개발자 도구가 1급(first-class) 확장을 갖고 있다. 그 위에 두 가지 큰 변화가 얹혔다.
첫째, Raycast AI. 2025년 후반 Raycast는 OpenAI·Anthropic·Perplexity 모델을 명령 팔레트 안에 통합했고, 2026년 봄 UI를 다시 갈았다. tab을 두 번 누르면 AI Chat이 뜨고, 거기서 자연어로 "지금 클립보드의 JSON을 보기 좋게 정렬해서 다시 클립보드에 넣어줘" 같은 명령을 시킬 수 있다. Anthropic Claude·OpenAI GPT 모델은 Pro 플랜(8/월)에서 쓴다.
둘째, MCP(Model Context Protocol) 통합. Raycast AI Chat 안에서 MCP 서버를 자동 로드해서 — 예컨대 로컬의 file·git·shell MCP를 — Raycast 안의 AI가 직접 명령을 실행할 수 있다. 이것이 2026년 가장 큰 단일 변화다.
1.3 Alfred — 여전히 유효한 선택지
Alfred는 죽지 않았다. 오히려 안정성과 라이센스 모델(Powerpack $42 일회성, Raycast Pro는 구독)에서 강점을 유지한다. 메모리는 30 ~ 50 MB, 시작 지연은 약 100 ms로 Raycast(80 ~ 120 MB, 약 200 ms)보다 가볍다. 단점은 AI 통합이 없고, 확장 생태계가 정체되어 있다는 점이다.
내 추천은 단순하다. 새로 시작한다면 Raycast. Alfred에서 7년쯤 Workflow를 쌓아뒀고 그게 잘 돌아간다면 굳이 옮길 이유는 없다.
1.4 첫 30분 설정
Raycast를 설치하고 가장 먼저 할 일.
Settings → General → Hotkey를cmd-space로. 시스템 Spotlight 단축키는Settings → Keyboard → Spotlight에서 해제한다.Settings → Extensions → Window Management활성화. 키바인딩은 빈 상태로 두고 — Rectangle/AeroSpace를 쓰면 충돌하므로.Settings → AI → Quick AI Hotkey를 비워둔다(나중에 Karabiner Hyper key로 묶을 것).- 처음 깔 확장 다섯 개:
Brew,GitHub,Visual Studio Code,Color Picker,Quicklinks.
2장 · Karabiner-Elements — Caps Lock을 Hyper key로
2.1 Hyper key란 무엇인가
Hyper key는 shift + control + option + command 네 모디파이어를 한 번에 누른 것처럼 행동하는 가상 키다. 어떤 정상적인 앱도 이 네 개를 동시에 요구하지 않기 때문에, Hyper로 시작하는 단축키는 시스템 어디와도 충돌하지 않는 "전역 네임스페이스"가 된다.
전통적으로는 거의 안 쓰는 Caps Lock을 Hyper로 매핑한다. 같이 흔히 쓰는 트릭은 "단독으로 눌렀다 떼면 Escape, 누른 채 다른 키와 조합하면 Hyper" 다 — Vim 사용자에게는 큰 보상이다.
2.2 Karabiner JSON 스니펫
Karabiner-Elements의 Complex Modifications JSON 스니펫은 다음과 같이 생겼다.
{
"description": "Caps Lock -> Hyper (Escape on tap)",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "caps_lock",
"modifiers": { "optional": ["any"] }
},
"to": [
{
"key_code": "left_shift",
"modifiers": ["left_control", "left_option", "left_command"]
}
],
"to_if_alone": [
{ "key_code": "escape" }
]
}
]
}
이 한 덩이를 ~/.config/karabiner/assets/complex_modifications/에 두면, Karabiner Settings의 Complex Modifications 탭에서 한 번 클릭으로 활성화된다.
2.3 Hyper로 무엇을 묶을 것인가
내 권장:
Hyper + T→ 터미널(Ghostty) 띄우기Hyper + B→ 브라우저Hyper + S→ SlackHyper + R→ Raycast AI 즉시 호출Hyper + 1..9→ AeroSpace 워크스페이스 1..9 전환
Hyper 매핑은 Karabiner JSON에서 직접 해도 되지만, 더 깔끔한 방법은 앱 단축키는 Raycast Quicklinks/Hotkey로, 시스템 동작은 Hammerspoon으로 위임하는 것이다. Karabiner는 "Caps Lock → Hyper" 한 줄만 책임진다.
2.4 Goku로 JSON 지옥 탈출
Karabiner JSON은 빠르게 거대해진다. goku(Clojure로 EDN을 JSON으로 컴파일)나 karabiner.ts(TypeScript)로 옮기면 훨씬 다루기 쉬워진다. 2026년 시점에서 인기는 비등하지만, 새로 시작한다면 EDN보다는 TypeScript 쪽이 학습곡선이 짧다.
3장 · Hammerspoon — Lua로 macOS를 스크립팅한다
3.1 Hammerspoon이 뭘 하는가
Hammerspoon은 macOS의 시스템 API를 Lua 스크립팅 엔진에 노출시키는 데스크탑 자동화 도구다. 창 이동·키 후킹·USB 이벤트·네트워크 상태·배터리 — 거의 모든 macOS 이벤트가 Lua 함수의 인수로 들어온다.
기본 설정은 비어 있다. ~/.hammerspoon/init.lua에 본인이 원하는 동작을 직접 쓴다. 변경은 즉시 적용된다(라이브 리로드).
3.2 첫 init.lua
local hyper = {"ctrl", "alt", "cmd", "shift"}
-- Hyper + H/J/K/L: 창을 화면 절반에 스냅
hs.hotkey.bind(hyper, "H", function()
local win = hs.window.focusedWindow()
local f = win:screen():frame()
win:setFrame({x = f.x, y = f.y, w = f.w / 2, h = f.h})
end)
hs.hotkey.bind(hyper, "L", function()
local win = hs.window.focusedWindow()
local f = win:screen():frame()
win:setFrame({x = f.x + f.w / 2, y = f.y, w = f.w / 2, h = f.h})
end)
-- Hyper + F: 풀스크린(스페이스 만들지 않고)
hs.hotkey.bind(hyper, "F", function()
local win = hs.window.focusedWindow()
win:setFrame(win:screen():frame())
end)
-- Hyper + R: 설정 리로드
hs.hotkey.bind(hyper, "R", function()
hs.reload()
hs.alert.show("Hammerspoon reloaded")
end)
이 30줄로 Rectangle의 절반은 대체된다. 나머지 절반(드래그로 스냅, 1/3·2/3 분할)이 필요하면 Spoons 중 WindowGrid나 MiroWindowsManager를 얹는다.
3.3 더 큰 그림 — 환경 인식
Hammerspoon의 진짜 가치는 창 관리가 아니다. 환경의 변화를 트리거로 받는 것이다.
- 회의실 모니터에 HDMI가 꽂히면 → Slack 알림 끄기, Do Not Disturb 켜기
- 특정 Wi-Fi에 연결되면 → VPN 자동 시작
- 09:00에 Calendar에 회의가 잡혀 있으면 → Karabiner profile을 "회의" 프로파일로 자동 전환
이런 건 Lua 30 ~ 50줄로 짠다. 시스템 단위로 사고를 옮긴다는 점에서 Hammerspoon은 Raycast/Karabiner와 다른 층(layer)에 있다.
3.4 Hammerspoon vs Karabiner — 역할 분담
둘 다 자동화 도구지만 층이 다르다.
- Karabiner: 입력 이벤트 자체를 변환한다. "Caps Lock 키 → Hyper 모디파이어" 같은 키보드 드라이버 수준.
- Hammerspoon: 변환된 이벤트(또는 시스템 이벤트)를 받아 Lua 코드를 실행한다. "Hyper-T가 눌리면 Ghostty 띄우고 특정 프로파일로 시작" 같은 응용 수준.
권장 규칙: Karabiner는 키 매핑만, 나머지는 Hammerspoon. 그래야 JSON이 폭주하지 않는다.
4장 · Homebrew와 Brewfile — 30분 안에 새 맥 만들기
4.1 brew 단독으로는 부족하다
새 맥을 받았을 때 brew install 50번을 손으로 치는 사람을 봤다. 그 시간에 Brewfile 하나 쓰면 된다.
brew bundle은 Brewfile을 읽어 패키지 상태를 선언적으로 맞춘다. brew install이 명령형(imperative)이라면, Brewfile은 "이 머신은 이 상태여야 한다"고 선언한다. 2026년 기준 brew bundle은 Homebrew formulae·Cask·Mac App Store·VS Code 확장·Go 패키지·Cargo 패키지·uv 도구·Flatpak·krew 플러그인까지 지원한다.
4.2 Brewfile 예시
# ~/.config/brew/Brewfile
# Taps
tap "homebrew/bundle"
tap "homebrew/cask-fonts"
# Core CLI tools
brew "git"
brew "gh"
brew "fish"
brew "starship"
brew "mise"
brew "ripgrep"
brew "fd"
brew "fzf"
brew "bat"
brew "eza"
brew "delta"
brew "jq"
brew "yq"
brew "direnv"
brew "lazygit"
brew "neovim"
# Dotfile management
brew "chezmoi"
# Container & Cloud
brew "docker"
brew "kubectl"
brew "k9s"
brew "helm"
# Cask apps
cask "raycast"
cask "ghostty"
cask "karabiner-elements"
cask "hammerspoon"
cask "aerospace"
cask "1password"
cask "1password-cli"
cask "cleanshot"
cask "visual-studio-code"
cask "orbstack"
cask "font-jetbrains-mono-nerd-font"
# Mac App Store (requires `brew install mas`)
brew "mas"
mas "Xcode", id: 497799835
# VS Code extensions
vscode "ms-python.python"
vscode "rust-lang.rust-analyzer"
새 맥에서:
xcode-select --install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew bundle --file=~/.config/brew/Brewfile
이걸 chezmoi에 넣어두면, 새 맥 셋업이 3개 명령으로 끝난다.
4.3 brew bundle dump의 함정
brew bundle dump는 현재 설치된 모든 것을 Brewfile로 덤프한다. 편하지만 위험하다. 일회용으로 깔았다가 안 쓰는 도구가 같이 박힌다. Brewfile은 손으로 관리하라. 덤프는 초기 마이그레이션 때 한 번만 쓰고, 그 뒤로는 수동 편집.
4.4 무엇은 brew, 무엇은 Mac App Store인가
내 경험칙:
- 코드 서명·Apple ID 결합이 필요한 앱(예: iWork, App Sandbox 강제 앱): Mac App Store.
- 빈번한 업데이트가 중요한 개발 도구: brew cask.
- 둘 다 가능하면 brew cask. 자동화 친화적.
5장 · 터미널 전쟁 2026 — iTerm2·Ghostty·WezTerm·Warp
5.1 풍경 정리
오랫동안 macOS 터미널은 사실상 iTerm2 한 강자였다. 2024 ~ 2025년 사이 풍경이 바뀌었다. Mitchell Hashimoto(Vagrant·Terraform·Consul의 창시자)가 Ghostty를 공개했고, 2026년 3월 Ghostty 1.3이 스크롤백 검색과 네이티브 스크롤바를 더하면서 iTerm2 사용자가 빠르게 넘어왔다.
| 터미널 | 입력 지연 | 출력 처리량 | 멀티플렉서 내장 | AI 통합 | 설정 | 가격 |
|---|---|---|---|---|---|---|
| Ghostty 1.3 | 2 ms | 매우 높음 | 있음(탭/스플릿) | 없음 | 단일 ZON 파일 | 무료/OSS |
| iTerm2 | 12 ms | 보통 | 있음(트리거 풍부) | 일부 | GUI 위주 | 무료 |
| WezTerm | 3 ms | 높음 | 있음(강력) | 없음 | Lua 단일 파일 | 무료/OSS |
| Warp | 8 ms | 보통 | 일부 | 깊은 통합 | 클라우드 동기화 | Free/Team |
| Alacritty | 3 ms | 매우 높음 | 없음 | 없음 | YAML | 무료/OSS |
(입력 지연 수치는 2026년 벤치마크 보고서들의 중앙값. 환경에 따라 다르다.)
5.2 Ghostty — 2026년 디폴트
권장은 단순하다. 새로 시작한다면 Ghostty. 이유:
- macOS 네이티브로 빌드되어 시스템 폰트 렌더링·이벤트 핸들링과 잘 맞는다.
- 키-스크린 지연이 가장 낮다.
- 설정은 단일
~/.config/ghostty/config파일, 텍스트 기반, dotfile에 그대로 들어간다. - ANSI·OSC·Sixel 등 모던 프로토콜을 빠르게 채택한다.
설정 예:
# ~/.config/ghostty/config
font-family = JetBrainsMono Nerd Font
font-size = 14
theme = catppuccin-mocha
window-padding-x = 12
window-padding-y = 12
macos-titlebar-style = tabs
window-decoration = false
cursor-style = bar
shell-integration = fish
5.3 iTerm2 — 떠나기 아쉬운 거인
iTerm2의 강점은 여전하다. 트리거(Trigger), 프로파일 분기, 셸 통합, 자동 스크립트 — 13년치 기능이 쌓여 있다. 본인이 이미 트리거에 수십 개 룰을 박아 뒀다면 iTerm2를 유지하는 게 합리적이다. 새로 시작한다면 굳이 갈 필요는 없다.
5.4 WezTerm vs Warp — 양 극단
- WezTerm은 크로스 플랫폼 일관성과 Lua 설정의 표현력이 강점. macOS·Linux·Windows를 오가며 동일 설정을 쓰고 싶고, 내장 멀티플렉서로 tmux를 대체하고 싶다면 이쪽.
- Warp는 AI를 터미널 자체에 박아 넣은 제품. 명령 실패 시 약 80% 정도는 정확한 진단·수정 제안을 준다(2026년 사용자 보고 기준). 단점은 클라우드 의존과 가격($15/월/시트, Pro 이상). 회사 카드로 결제할 수 있고, 자연어로 셸을 쓰는 게 편하다면 가치가 있다.
5.5 권장
- 단독 개발자, 빠른 셸 위주: Ghostty.
- 크로스 플랫폼·Lua 광신도: WezTerm.
- AI 의존이 큰 비기너 ~ 중급: Warp.
- 트리거에 살림 차린 iTerm2 베테랑: iTerm2 유지.
6장 · 창 관리 — Rectangle, 또는 AeroSpace
6.1 Rectangle — "조심스러운" 선택
Rectangle은 무료·OSS·App Store 없이 다운로드된다. 절반·1/4·1/6·커스텀 사이즈를 단축키로 스냅한다. Magnet과의 차이는 가격(무료)과 다중 모니터 다루기(Rectangle이 우월). 2026년 시점에서 macOS 윈도우 매니저로 권하는 첫 번째 카드는 여전히 Rectangle이다.
6.2 AeroSpace — i3가 그리웠던 사람을 위한
AeroSpace는 i3/Sway 스타일의 타일링 윈도우 매니저다. 창을 자동으로 타일링하고, 키보드로 이동·리사이즈·워크스페이스 전환을 한다. 결정적으로 SIP(System Integrity Protection) 해제가 필요 없다 — 이게 yabai와의 큰 차이다. 그래서 macOS 업데이트에 강하다.
설정은 ~/.aerospace.toml 단일 파일.
# ~/.aerospace.toml (발췌)
start-at-login = true
default-root-container-layout = 'tiles'
[mode.main.binding]
alt-h = 'focus left'
alt-j = 'focus down'
alt-k = 'focus up'
alt-l = 'focus right'
alt-shift-h = 'move left'
alt-shift-j = 'move down'
alt-shift-k = 'move up'
alt-shift-l = 'move right'
alt-1 = 'workspace 1'
alt-2 = 'workspace 2'
alt-3 = 'workspace 3'
alt-shift-1 = 'move-node-to-workspace 1'
alt-shift-2 = 'move-node-to-workspace 2'
alt-slash = 'layout tiles horizontal vertical'
alt-comma = 'layout accordion horizontal vertical'
장점은 명확하다. 마우스를 거의 안 쓴다, 워크스페이스 전환이 즉시(애니메이션 없는 모드), 멀티 모니터에서도 일관됨.
단점도 있다. macOS UI(특히 Mission Control·Spotlight)와 일부 충돌이 있고, 1.0 도달 전이라 종종 깨지는 호환성 변경이 있다. 그래도 데일리 드라이버로 충분히 쓸 만하다.
6.3 어느 쪽인가
- macOS 네이티브 워크플로우를 지키고 싶다: Rectangle.
- 키보드 중심·다중 워크스페이스를 i3처럼 쓰고 싶다: AeroSpace.
- yabai는 SIP를 풀어야 하고 이후 macOS 업데이트에 자주 깨진다. 2026년에는 추천하지 않는다.
7장 · 비밀번호와 시크릿 — 1Password CLI vs Bitwarden CLI
7.1 둘 다 좋다, 결정 축이 다를 뿐
- 1Password: 구독제. CLI(
op), Connect Server, Shell Plugins(AWS CLI·gh·Docker·Stripe 등 100+ 도구를 투명하게 가로채는 통합), 내장 SSH agent. 개발자 워크플로우에서 가장 매끈하다. - Bitwarden: OSS·자체 호스팅 가능. CLI, Bitwarden Secrets Manager(GitHub Actions·GitLab·Kubernetes 통합). 가격 면에서 훨씬 우호적.
7.2 1Password 권장 사용 패턴
# .env 파일에 op:// 레퍼런스만 두고, 실행 시 주입
# .env
DATABASE_URL="op://Engineering/postgres-prod/connection-string"
AWS_ACCESS_KEY_ID="op://Engineering/aws-prod/access-key-id"
# 실행
op run --env-file=.env -- npm run dev
SSH 키도 1Password vault에 넣고 SSH agent로 노출한다. 평문 ~/.ssh/id_*이 사라진다.
7.3 Bitwarden 사용 패턴
# 1회 로그인 후 세션 토큰
export BW_SESSION="$(bw unlock --raw)"
# 비밀 꺼내기
bw get password "AWS Production"
CI에는 Bitwarden Secrets Manager의 SDK(Go·Python·JS)를 쓴다.
7.4 결정
- 1인 개발자·SSH 헤비: 1Password.
- 20명 엔지니어링 팀·예산 민감: Bitwarden + Secrets Manager.
- 어느 쪽이든 평문 시크릿을 dotfile에 박아두는 짓만은 그만둔다.
8장 · 런타임 버전 관리 — mise가 asdf를 대체한 이유
8.1 mise — Rust로 다시 쓴 asdf
mise(전 rtx)는 2022년 Jeff Dickey가 시작한 도구다. asdf의 .tool-versions 파일을 그대로 읽고, asdf 플러그인도 호환한다. 그러면서 다음을 더한다.
- 성능: asdf는 shim 방식이라 런타임 호출마다 약 120 ms 오버헤드. mise는 셸 프롬프트 로딩 시 약 5 ms. 매 호출마다 빠르다.
- 백엔드 다양성: asdf 플러그인 외에 core(Node·Python·Go 등 내장 구현체)·cargo·npm·pipx·ubi·aqua를 직접 지원.
env/tasks: direnv + Make 일부를 대체한다.
8.2 사용 예
# 글로벌 기본
mise use --global node@22 python@3.13 go@1.23
# 프로젝트별 (.mise.toml 또는 .tool-versions)
cd ~/code/myapp
mise use node@20.18 python@3.12
# 작업(tasks)
mise tasks add dev -- npm run dev
mise run dev
~/.config/mise/config.toml에 환경 변수, 글로벌 도구, 라이센스 등을 선언한다.
8.3 asdf에서 mise로
mise import 명령 한 번에 asdf 설정을 그대로 가져온다. shim이 사라지면서 셸 호출 지연이 눈에 보일 정도로 줄어든다. 새로 시작한다면 mise. 이미 asdf에서 잘 돌아가는 큰 팀이라면, 강제로 옮길 필요는 없다.
9장 · Dotfiles 전략 — chezmoi vs stow vs bare git
9.1 세 가지 접근
- bare git repo:
git --git-dir=$HOME/.dotfiles --work-tree=$HOME별칭으로$HOME전체를 트래킹. 의존성 없음, 최소주의. 단점은 실수로 비밀 파일을 push하기 쉽다. - GNU stow: 심볼릭 링크 매니저.
~/dotfiles/zsh/.zshrc를stow zsh로~/.zshrc에 링크. 단순·UNIX 친화적. 단점은 머신별 분기·시크릿 처리가 없다. - chezmoi: Go 템플릿으로 OS별 분기·시크릿 암호화·
onchange스크립트(자동 재실행). 가장 강력하지만 학습곡선이 있다.
9.2 2026년 권장 — chezmoi
세 가지 중 하나만 고르라면 chezmoi. 이유:
- 단일 명령(
chezmoi init https://github.com/<user>/dotfiles)으로 새 머신에 적용. .chezmoi.toml.tmpl에서chezmoi.os == "darwin"같은 조건으로 macOS/Linux 분기.- 비밀은 1Password·Bitwarden·Keychain·age를 통해 자동 복호화. 평문 push 위험을 구조적으로 막는다.
run_onchange_prefix가 붙은 스크립트는 변경됐을 때만 재실행 — Brewfile 변경 시brew bundle자동 호출에 딱이다.
9.3 chezmoi 설정 스켈레톤
chezmoi init --apply git@github.com:youruser/dotfiles.git
저장소 구조 예:
~/.local/share/chezmoi/
├── .chezmoi.toml.tmpl
├── dot_zshrc.tmpl
├── dot_gitconfig.tmpl
├── private_dot_ssh/
│ └── config
├── run_onchange_install-packages.sh.tmpl
└── README.md
dot_zshrc.tmpl 내부:
export EDITOR=nvim
{{ if eq .chezmoi.os "darwin" -}}
eval "$(/opt/homebrew/bin/brew shellenv)"
{{ end -}}
9.4 stow를 굳이 권하지 않는 이유
stow는 좋다. 단순한 머신 한 대만 다룬다면 잘 작동한다. 하지만 머신이 둘 이상이거나, 시크릿이 끼면 머지않아 직접 분기 처리를 짜게 된다. 그 시점이 오면 chezmoi로 가는 게 자연스럽다.
10장 · 스크린샷·스크린캐스트 — CleanShot X, Kap, Loom
10.1 CleanShot X — 2026년 기준 디폴트
cmd-shift-4 위에 얹는다. 차이점:
- 데스크탑 아이콘 자동 숨김
- 어노테이션·블러·스텝 카운터 내장
- "All-in-One" 모드: 스크린샷, GIF, 비디오, 스크롤링 캡처가 한 단축키
- 클라우드(
cleanshot.cloud) 자동 업로드 옵션
가격은 일회성 라이센스(또는 Setapp 포함). 한 번 사면 평생 업데이트. 회사 카드로 사기 쉬운 가격이다.
10.2 Kap — OSS 대안
Kap은 macOS 전용 OSS 스크린 레코더. MP4·WebM·GIF를 깔끔하게 뽑는다. 기능은 CleanShot보다 적지만, 무료에 빠르다. 단순 GIF만 필요하면 Kap으로 충분하다.
10.3 Loom — 비동기 비디오 커뮤니케이션
Loom은 정확히 "녹화 후 링크 공유" 한 가지에 최적화된 제품. PR 코멘트, 디자인 리뷰, 비동기 스탠드업에 강하다. CleanShot의 클라우드 모드와 기능적으로는 겹치지만, Loom 쪽이 시청 트래킹·반응 기능까지 묶어 준다.
내 권장:
- 일상 스크린샷: CleanShot X.
- 빠른 GIF: Kap.
- 동료에게 보내는 비동기 비디오: Loom.
11장 · 모든 것을 묶는 키 한 줄 — Hyper key map의 완성
이 시점에서 도구들이 어떻게 맞물리는지 한 장에 그려본다.
Caps Lock (Karabiner) ──► Hyper (⌃⌥⌘⇧)
│
├─ T ─► Hammerspoon ─► Ghostty 띄움
├─ B ─► Hammerspoon ─► 브라우저
├─ S ─► Hammerspoon ─► Slack
├─ R ─► Raycast AI 즉시 호출
├─ 1..9 ─► AeroSpace 워크스페이스 전환
├─ H/J/K/L ─► Hammerspoon ─► 창 절반 스냅
└─ Space ─► Raycast 명령 팔레트(앞서 매핑)
이 한 다이어그램에 이 글의 핵심이 들어 있다. Karabiner는 키만 바꾸고, Hammerspoon은 시스템 동작만 묶고, Raycast는 명령 팔레트만 책임지고, AeroSpace는 창만 다룬다. 각각이 한 가지를 잘 한다.
12장 · 최소 생산성 스택 — 한 줄로 줄이면
처음 시작하는 사람을 위한 최소 생산성 스택.
1. Raycast (Spotlight 대체)
2. Karabiner-Elements (Caps Lock → Hyper)
3. Ghostty (터미널)
4. Homebrew + Brewfile (선언적 설치)
5. mise (런타임 버전)
6. 1Password 또는 Bitwarden (시크릿)
7. chezmoi (dotfiles)
8. Rectangle 또는 AeroSpace (창 관리)
9. CleanShot X (스크린샷)
추가 시점은 본인 워크플로우에 구멍이 보일 때. 처음부터 9개를 다 깔 필요는 없다. 1·2·3·4부터 시작해도 일주일이면 체감이 바뀐다.
에필로그 — 도구는 도구일 뿐
생산성 스택을 만들 때 가장 흔한 실수는 도구 자체를 목적으로 만드는 것이다. 매일 dotfiles 저장소를 다듬으며 하루를 보내고, Karabiner JSON을 100줄 짜고, 정작 코드는 안 쓴다. 그건 hobby다. 일이 아니다.
도구는 하루에 30번 누르는 키, 100번 띄우는 창, 10번 같은 명령을 친 그 자리에만 든다. 측정 가능한 마찰을 없애는 데에만 시간을 쓰고, 나머지는 디폴트로 둔다.
이 글의 도구 묶음은 내가 그 원칙으로 4년 다듬은 것이다. 지금도 매해 한두 개씩 바뀐다. 2024년에는 iTerm2 → Ghostty가 바뀌었고, 2025년에는 asdf → mise가 바뀌었고, 2025년 후반에는 yabai → AeroSpace가 바뀌었다. 2026년 후반에는 또 무엇이 바뀔지 모른다. 그 변화에 빠르게 적응하는 것이 진짜 생산성이다.
30일 적용 체크리스트
- 1일차: Raycast 깔고
cmd-space옮긴다. Spotlight 단축키 해제. - 2일차: Karabiner-Elements 깔고 Caps Lock을 Hyper로 매핑. tap-단독은 Escape.
- 3일차: Homebrew + Brewfile 1차 작성.
brew bundle한 번 돌린다. - 4일차: Ghostty로 갈아탄다. 설정 파일을 dotfiles에 박는다.
- 7일차: mise로 런타임 버전 통일. asdf가 있었다면
mise import. - 14일차: chezmoi로 dotfiles 마이그레이션. 비밀은 1Password/Bitwarden 백엔드.
- 21일차: Hammerspoon
init.lua에 자기만의 단축키 5 ~ 10개. - 30일차: AeroSpace 또는 Rectangle로 창 관리 표준화.
안티 패턴
- 매일 Karabiner JSON을 손으로 편집한다 → goku/TS 컴파일러로 옮긴다.
- Brewfile 없이
brew install만 친다 → 새 맥에서 후회한다. - 평문
.env를 git에 넣는다 → 1Password/Bitwarden refer 패턴으로 옮긴다. - 한 번에 9개를 다 깐다 → 1·2·3·4부터 한 주씩.
- yabai를 새로 깐다 → 2026년에는 AeroSpace로 시작한다.
다음 글 예고
다음 글에서는 이 도구 묶음을 팀 표준으로 만드는 방법 — 즉, 사내 Brewfile·chezmoi 템플릿·Raycast 확장 배포·온보딩 자동화 — 를 다룬다. 1인 워크플로우와 팀 워크플로우는 결이 다르다. 30명짜리 엔지니어링 팀이 한 명도 빠짐없이 같은 dotfiles 베이스 위에서 시작한다면, 새 동료의 첫 주가 어떻게 달라지는지를 본다.
참고 / References
- Raycast — https://www.raycast.com/
- Raycast AI — https://www.raycast.com/core-features/ai
- Alfred — https://www.alfredapp.com/
- Karabiner-Elements — https://karabiner-elements.pqrs.org/
- Karabiner Complex Modifications — https://ke-complex-modifications.pqrs.org/
- Hammerspoon — https://www.hammerspoon.org/
- Homebrew — https://brew.sh/
- Homebrew Bundle & Brewfile — https://docs.brew.sh/Brew-Bundle-and-Brewfile
- Ghostty — https://ghostty.org/
- iTerm2 — https://iterm2.com/
- WezTerm — https://wezterm.org/
- Warp — https://www.warp.dev/
- Alacritty — https://alacritty.org/
- Rectangle — https://rectangleapp.com/
- AeroSpace — https://github.com/nikitabobko/AeroSpace
- AeroSpace Guide — https://nikitabobko.github.io/AeroSpace/guide
- 1Password CLI — https://developer.1password.com/docs/cli/
- Bitwarden CLI — https://bitwarden.com/help/cli/
- mise-en-place — https://mise.jdx.dev/
- asdf — https://asdf-vm.com/
- chezmoi — https://www.chezmoi.io/
- GNU Stow — https://www.gnu.org/software/stow/
- CleanShot X — https://cleanshot.com/
- Kap — https://getkap.co/
- Loom — https://www.loom.com/
The 2026 macOS Developer Productivity Stack — Raycast, Karabiner, Hammerspoon, Homebrew, Ghostty Deep Dive
Prologue — The Day I Turned Off Spotlight
Around 2022 I turned off Spotlight. To be precise, I rebound cmd-space to Raycast and never went back. That was the start.
"Productivity stack" sounds grand, but it is simple in practice: a bundle of tools that automate and standardize the keys you press hundreds of times a day, the windows you open every day, and the config files you touch every week. In 2026 macOS has never been better at this. Raycast has fully replaced Spotlight. Ghostty is rapidly eating iTerm2's mindshare. AeroSpace removed the last excuse i3 users had for not coming to macOS. Homebrew has made new-Mac setup declarative with brew bundle. mise has become asdf's successor.
This post is not "10 good tools." It is why each tool occupies its slot, what it replaced, and how the pieces interlock — with concrete configs. At the end, a one-line "minimum viable stack."
1 · The Launcher — Raycast Replaced Spotlight
1.1 Why Spotlight Is Not Enough
Spotlight is a search box. Raycast is a command palette. That distinction decides everything.
"Open Slack" works fine in Spotlight. "Open the #ops channel inside the Slack window I already have" does not. "Open the Figma file I saved at 2:14 AM today." "Base64-encode the current clipboard." "Show the Linear ticket I created yesterday." Spotlight gets none of these. Raycast gets all of them. Via one unified model: extensions.
1.2 Raycast in 2026
As of May 2026, the Raycast Store has over 1,300 extensions. GitHub, Linear, Jira, Notion, Slack, VS Code, Docker, Figma, AWS, Vercel — nearly every developer tool has a first-class extension. On top of that, two large shifts.
First, Raycast AI. In late 2025 Raycast integrated OpenAI, Anthropic, and Perplexity models directly into the command palette, and the UI was redesigned in spring 2026. Press tab twice to open AI Chat and run natural-language commands like "format the JSON currently on my clipboard and put it back." Anthropic Claude and OpenAI GPT models are available on the Pro plan (8/month).
Second, MCP (Model Context Protocol) integration. Raycast AI Chat now auto-loads MCP servers, so a local file/git/shell MCP can be invoked directly by the AI inside the launcher. That is the single biggest change of 2026.
1.3 Alfred — Still a Valid Choice
Alfred is not dead. It still wins on stability and on its license model (Powerpack at $42 one-time, versus Raycast Pro's subscription). Memory footprint is 30 to 50 MB, launch latency around 100 ms, both lighter than Raycast (80 to 120 MB, around 200 ms). The downsides: no native AI, and a stagnating extension ecosystem.
My take is simple: if you are starting fresh, Raycast. If you have seven years of Alfred Workflows that work, there is no compelling reason to migrate.
1.4 The First 30 Minutes
After installing Raycast:
Settings -> General -> Hotkeyset tocmd-space. Disable the system Spotlight shortcut atSettings -> Keyboard -> Spotlight.Settings -> Extensions -> Window Managementon. Leave the keybindings empty — Rectangle or AeroSpace will own those.Settings -> AI -> Quick AI Hotkeyblank for now (you will bind it through Karabiner Hyper later).- First five extensions to install:
Brew,GitHub,Visual Studio Code,Color Picker,Quicklinks.
2 · Karabiner-Elements — Caps Lock as Hyper
2.1 What Is a Hyper Key
A Hyper key is a virtual key that behaves as if you pressed shift + control + option + command simultaneously. No reasonable app demands all four modifiers at once, so any shortcut starting with Hyper sits in a "global namespace" that collides with nothing.
The traditional trick is to remap Caps Lock — a near-useless key — to Hyper. Even better, the classic combo: Escape on tap, Hyper on hold. A huge win for Vim users.
2.2 The Karabiner JSON Snippet
A Karabiner-Elements complex modification snippet looks like this.
{
"description": "Caps Lock -> Hyper (Escape on tap)",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "caps_lock",
"modifiers": { "optional": ["any"] }
},
"to": [
{
"key_code": "left_shift",
"modifiers": ["left_control", "left_option", "left_command"]
}
],
"to_if_alone": [
{ "key_code": "escape" }
]
}
]
}
Drop this into ~/.config/karabiner/assets/complex_modifications/ and enable it with one click in the Karabiner Settings Complex Modifications tab.
2.3 What to Bind to Hyper
My recommendation:
Hyper + T-> open terminal (Ghostty)Hyper + B-> browserHyper + S-> SlackHyper + R-> Raycast AI quick invokeHyper + 1..9-> switch AeroSpace workspaces 1..9
You can wire these directly in Karabiner JSON, but the cleaner pattern is app shortcuts via Raycast Quicklinks/Hotkey, system actions via Hammerspoon. Karabiner owns only the "Caps Lock -> Hyper" line.
2.4 Escaping JSON Hell with Goku
Karabiner JSON grows fast. Move to goku (Clojure compiling EDN to JSON) or karabiner.ts (TypeScript) and it becomes much more manageable. In 2026 the two are roughly tied in popularity; for a fresh start the TypeScript flavor has the shorter learning curve.
3 · Hammerspoon — Scripting macOS in Lua
3.1 What Does Hammerspoon Do
Hammerspoon is a desktop automation tool that exposes macOS system APIs to a Lua scripting engine. Window moves, key hooks, USB events, network state, battery — nearly every macOS event arrives as arguments to a Lua function.
The default config is empty. You write what you want in ~/.hammerspoon/init.lua. Changes apply instantly via live reload.
3.2 A First init.lua
local hyper = {"ctrl", "alt", "cmd", "shift"}
-- Hyper + H / L: snap window to left or right half
hs.hotkey.bind(hyper, "H", function()
local win = hs.window.focusedWindow()
local f = win:screen():frame()
win:setFrame({x = f.x, y = f.y, w = f.w / 2, h = f.h})
end)
hs.hotkey.bind(hyper, "L", function()
local win = hs.window.focusedWindow()
local f = win:screen():frame()
win:setFrame({x = f.x + f.w / 2, y = f.y, w = f.w / 2, h = f.h})
end)
-- Hyper + F: maximize without creating a new Space
hs.hotkey.bind(hyper, "F", function()
local win = hs.window.focusedWindow()
win:setFrame(win:screen():frame())
end)
-- Hyper + R: reload config
hs.hotkey.bind(hyper, "R", function()
hs.reload()
hs.alert.show("Hammerspoon reloaded")
end)
Thirty lines replace half of what Rectangle does. For the other half (drag-to-snap, third/two-thirds), layer in a Spoon like WindowGrid or MiroWindowsManager.
3.3 The Bigger Picture — Environment Awareness
The real value of Hammerspoon is not window management; it is using environment changes as triggers.
- HDMI of the conference room monitor plugged in -> silence Slack, enable Do Not Disturb
- Connected to a specific Wi-Fi -> start VPN automatically
- 09:00 with a meeting in Calendar -> swap Karabiner profile to "meeting"
Each of these is 30 to 50 lines of Lua. Hammerspoon operates at a different layer than Raycast or Karabiner because it thinks in system events, not key remaps.
3.4 Hammerspoon vs Karabiner — Division of Labor
They are both automation tools, but at different layers.
- Karabiner transforms the input events themselves. Keyboard-driver level: "Caps Lock key -> Hyper modifier."
- Hammerspoon receives transformed (or system) events and runs Lua. Application level: "Hyper-T pressed -> open Ghostty with the dev profile."
The rule: Karabiner only remaps keys. Everything else is Hammerspoon. That keeps your JSON from exploding.
4 · Homebrew and Brewfile — Build a New Mac in 30 Minutes
4.1 brew Alone Is Not Enough
I have watched people receive a new Mac and type 50 brew install commands by hand. Write one Brewfile instead.
brew bundle reads a Brewfile and converges the machine to a declarative package state. Where brew install is imperative, the Brewfile says "this machine should be in this state." As of 2026 brew bundle supports Homebrew formulae, Cask, Mac App Store, VS Code extensions, Go packages, Cargo packages, uv tools, Flatpak, and krew plugins. One Brewfile describes a polyglot environment.
4.2 A Sample Brewfile
# ~/.config/brew/Brewfile
# Taps
tap "homebrew/bundle"
tap "homebrew/cask-fonts"
# Core CLI tools
brew "git"
brew "gh"
brew "fish"
brew "starship"
brew "mise"
brew "ripgrep"
brew "fd"
brew "fzf"
brew "bat"
brew "eza"
brew "delta"
brew "jq"
brew "yq"
brew "direnv"
brew "lazygit"
brew "neovim"
# Dotfile management
brew "chezmoi"
# Container and cloud
brew "docker"
brew "kubectl"
brew "k9s"
brew "helm"
# Cask apps
cask "raycast"
cask "ghostty"
cask "karabiner-elements"
cask "hammerspoon"
cask "aerospace"
cask "1password"
cask "1password-cli"
cask "cleanshot"
cask "visual-studio-code"
cask "orbstack"
cask "font-jetbrains-mono-nerd-font"
# Mac App Store (requires `brew install mas`)
brew "mas"
mas "Xcode", id: 497799835
# VS Code extensions
vscode "ms-python.python"
vscode "rust-lang.rust-analyzer"
On a fresh Mac:
xcode-select --install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew bundle --file=~/.config/brew/Brewfile
Keep this in chezmoi and new-Mac setup is three commands.
4.3 The brew bundle dump Trap
brew bundle dump writes every currently installed package into a Brewfile. Convenient, dangerous. One-off tools you forgot about get pinned. Maintain Brewfiles by hand. Use dump once for migration, then edit manually.
4.4 brew vs Mac App Store
My rules of thumb:
- Apps that need code signing or Apple ID binding (iWork, sandbox-forced apps): Mac App Store.
- Developer tools where rapid updates matter: brew cask.
- If both are available, brew cask. More automation-friendly.
5 · The Terminal Wars 2026 — iTerm2, Ghostty, WezTerm, Warp
5.1 The Landscape
For years macOS had a single dominant terminal: iTerm2. The landscape shifted in 2024 to 2025. Mitchell Hashimoto (creator of Vagrant, Terraform, Consul) released Ghostty, and in March 2026 Ghostty 1.3 shipped scrollback search and native scrollbars — at which point iTerm2 users started migrating in volume.
| Terminal | Input latency | Output throughput | Built-in multiplexer | AI integration | Config | Price |
|---|---|---|---|---|---|---|
| Ghostty 1.3 | 2 ms | Very high | Yes (tabs/splits) | None | Single ZON file | Free, OSS |
| iTerm2 | 12 ms | Moderate | Yes (rich triggers) | Partial | GUI-driven | Free |
| WezTerm | 3 ms | High | Yes (powerful) | None | Single Lua file | Free, OSS |
| Warp | 8 ms | Moderate | Partial | Deep | Cloud-synced | Free/Team |
| Alacritty | 3 ms | Very high | None | None | YAML | Free, OSS |
(Latency numbers are medians from 2026 benchmark reports; environments vary.)
5.2 Ghostty — The 2026 Default
The recommendation is simple: if you are starting fresh, Ghostty. Reasons:
- Built natively for macOS; system font rendering and event handling feel right.
- Lowest key-to-screen latency on the platform.
- Single
~/.config/ghostty/configfile, text-based, slots directly into your dotfiles. - Adopts modern terminal protocols (ANSI, OSC, Sixel) quickly.
Example config:
# ~/.config/ghostty/config
font-family = JetBrainsMono Nerd Font
font-size = 14
theme = catppuccin-mocha
window-padding-x = 12
window-padding-y = 12
macos-titlebar-style = tabs
window-decoration = false
cursor-style = bar
shell-integration = fish
5.3 iTerm2 — The Giant Worth Staying With
iTerm2's strengths are intact: Triggers, profile branching, shell integration, AppleScript automation — 13 years of features piled up. If you already have dozens of trigger rules wired in, staying on iTerm2 is rational. Starting fresh, there is no reason to.
5.4 WezTerm vs Warp — Two Extremes
- WezTerm wins on cross-platform consistency and Lua-configured expressiveness. If you bounce between macOS, Linux, and Windows with one config, or want a built-in multiplexer to replace tmux, this is the pick.
- Warp is a product that bakes AI into the terminal itself. According to 2026 user reports it correctly diagnoses and suggests fixes for roughly 80% of failed commands. Downsides: cloud dependency and pricing ($15/month/seat for Pro and up). If a company card pays and you like talking to your shell in natural language, it is worth it.
5.5 Recommendation
- Solo developer, shell-heavy: Ghostty.
- Cross-platform, Lua zealot: WezTerm.
- Beginner to intermediate leaning on AI: Warp.
- iTerm2 veteran with a trigger graveyard: stay on iTerm2.
6 · Window Management — Rectangle or AeroSpace
6.1 Rectangle — The Conservative Pick
Rectangle is free, OSS, downloaded outside the App Store. It snaps halves, quarters, sixths, and custom sizes via shortcuts. Versus Magnet: price (free) and multi-monitor behavior (Rectangle is better). As of 2026 it is still the first window manager I recommend on macOS.
6.2 AeroSpace — For Those Who Missed i3
AeroSpace is an i3/Sway-style tiling window manager. It auto-tiles windows and exposes keyboard navigation, resizing, and workspace switching. Critically, it does not require disabling SIP (System Integrity Protection) — a major difference from yabai. That makes it resilient to macOS updates.
Config lives in a single ~/.aerospace.toml.
# ~/.aerospace.toml (excerpt)
start-at-login = true
default-root-container-layout = 'tiles'
[mode.main.binding]
alt-h = 'focus left'
alt-j = 'focus down'
alt-k = 'focus up'
alt-l = 'focus right'
alt-shift-h = 'move left'
alt-shift-j = 'move down'
alt-shift-k = 'move up'
alt-shift-l = 'move right'
alt-1 = 'workspace 1'
alt-2 = 'workspace 2'
alt-3 = 'workspace 3'
alt-shift-1 = 'move-node-to-workspace 1'
alt-shift-2 = 'move-node-to-workspace 2'
alt-slash = 'layout tiles horizontal vertical'
alt-comma = 'layout accordion horizontal vertical'
The wins are clear: almost no mouse, instant workspace switches (animation-free mode), consistent multi-monitor behavior.
The downsides too: friction with parts of macOS UI (Mission Control, Spotlight in particular), and breaking changes are expected pre-1.0. Still good enough as a daily driver.
6.3 Which One
- Stick to native macOS workflows: Rectangle.
- Keyboard-first, i3-style multiple workspaces: AeroSpace.
- yabai requires disabling SIP and breaks frequently after macOS updates. Not recommended in 2026.
7 · Passwords and Secrets — 1Password CLI vs Bitwarden CLI
7.1 Both Are Good; The Decision Axis Differs
- 1Password: subscription. CLI (
op), Connect Server, Shell Plugins (transparent integrations with AWS CLI, gh, Docker, Stripe, and 100+ other tools), built-in SSH agent. The smoothest developer workflow. - Bitwarden: OSS, self-hostable. CLI plus Bitwarden Secrets Manager (GitHub Actions, GitLab, Kubernetes integrations). Far friendlier pricing.
7.2 Recommended 1Password Pattern
# Put op:// references in your .env and inject at runtime
# .env
DATABASE_URL="op://Engineering/postgres-prod/connection-string"
AWS_ACCESS_KEY_ID="op://Engineering/aws-prod/access-key-id"
# Run
op run --env-file=.env -- npm run dev
Store SSH keys in your 1Password vault and expose them via the built-in SSH agent. Plaintext ~/.ssh/id_* files disappear.
7.3 Bitwarden Pattern
# Log in once, capture a session token
export BW_SESSION="$(bw unlock --raw)"
# Retrieve a secret
bw get password "AWS Production"
For CI, use the Bitwarden Secrets Manager SDK (Go, Python, JS).
7.4 Decision
- Solo developer, SSH-heavy: 1Password.
- 20-person engineering team, cost-sensitive: Bitwarden + Secrets Manager.
- Either way, stop committing plaintext secrets to dotfiles.
8 · Runtime Version Management — Why mise Replaced asdf
8.1 mise — asdf Rewritten in Rust
mise (formerly rtx) was started in 2022 by Jeff Dickey. It reads the same .tool-versions file as asdf and is compatible with asdf plugins. It adds:
- Performance: asdf's shim approach adds about 120 ms per runtime call. mise adds roughly 5 ms when the shell prompt loads. Per-call calls are faster.
- Multiple backends: beyond asdf plugins, mise has core (Node, Python, Go etc. built in), cargo, npm, pipx, ubi, aqua.
envandtasks: replaces parts of direnv and Make.
8.2 Usage
# Global defaults
mise use --global node@22 python@3.13 go@1.23
# Per-project (.mise.toml or .tool-versions)
cd ~/code/myapp
mise use node@20.18 python@3.12
# Tasks
mise tasks add dev -- npm run dev
mise run dev
~/.config/mise/config.toml declares env vars, global tools, licenses, and more.
8.3 Migrating From asdf
mise import brings your asdf setup over in one shot. The shims disappear and shell-call latency drops visibly. Starting fresh: use mise. Big teams already happy on asdf: no forced migration.
9 · Dotfile Strategy — chezmoi vs stow vs Bare Git
9.1 Three Approaches
- Bare git repo: alias
git --git-dir=$HOME/.dotfiles --work-tree=$HOMEto track$HOMEin place. Zero dependencies, maximally minimal. Downside: very easy to push a secret by accident. - GNU stow: a symlink manager.
~/dotfiles/zsh/.zshrcbecomes~/.zshrcviastow zsh. Simple, UNIX-friendly. Downside: no machine branching, no secret handling. - chezmoi: Go templates for OS branching, secret encryption, and
onchangescripts. The most powerful — with a learning curve.
9.2 The 2026 Recommendation — chezmoi
If forced to pick one, chezmoi. Why:
- One command (
chezmoi init https://github.com/<user>/dotfiles) applies the repo on a new machine. .chezmoi.toml.tmplbranches bychezmoi.os == "darwin"and similar to keep macOS and Linux configs in one tree.- Secrets are fetched and decrypted via 1Password, Bitwarden, Keychain, or age. Structurally prevents plaintext pushes.
- Scripts prefixed
run_onchange_re-run only when changed — perfect for invokingbrew bundlewhenever the Brewfile is edited.
9.3 A chezmoi Skeleton
chezmoi init --apply git@github.com:youruser/dotfiles.git
Repository layout:
~/.local/share/chezmoi/
├── .chezmoi.toml.tmpl
├── dot_zshrc.tmpl
├── dot_gitconfig.tmpl
├── private_dot_ssh/
│ └── config
├── run_onchange_install-packages.sh.tmpl
└── README.md
Inside dot_zshrc.tmpl:
export EDITOR=nvim
{{ if eq .chezmoi.os "darwin" -}}
eval "$(/opt/homebrew/bin/brew shellenv)"
{{ end -}}
9.4 Why I Do Not Recommend stow
stow is fine. On a single machine it works. The moment you add a second machine or secrets enter the mix, you will start writing your own branching logic. That is the moment to jump to chezmoi.
10 · Screenshots and Screencasts — CleanShot X, Kap, Loom
10.1 CleanShot X — The 2026 Default
Bind it on top of cmd-shift-4. The differentiators:
- Auto-hides desktop icons
- Built-in annotation, blur, step counters
- "All-in-One" mode: screenshots, GIFs, video, and scrolling captures behind one hotkey
- Optional cloud (
cleanshot.cloud) auto-upload
Priced as a one-time license (or via Setapp). Buy once, lifetime updates. Easy to expense.
10.2 Kap — The OSS Alternative
Kap is a macOS-only OSS screen recorder. Outputs MP4, WebM, and GIF cleanly. Fewer features than CleanShot but free and fast. For quick GIFs alone, Kap is plenty.
10.3 Loom — Async Video Communication
Loom is optimized for one thing: record, share a link. PR comments, design reviews, async standups. CleanShot's cloud mode overlaps functionally, but Loom adds view tracking and reactions.
My split:
- Daily screenshots: CleanShot X.
- Quick GIFs: Kap.
- Async videos to teammates: Loom.
11 · One Diagram That Wires It All Up
At this point it helps to see how the tools chain together.
Caps Lock (Karabiner) ──► Hyper (ctrl+alt+cmd+shift)
│
├─ T ─► Hammerspoon ─► open Ghostty
├─ B ─► Hammerspoon ─► browser
├─ S ─► Hammerspoon ─► Slack
├─ R ─► Raycast AI quick invoke
├─ 1..9 ─► AeroSpace workspace switch
├─ H/J/K/L ─► Hammerspoon ─► half-window snap
└─ Space ─► Raycast command palette (mapped earlier)
The thesis of this whole post lives in that diagram. Karabiner only remaps keys. Hammerspoon only handles system actions. Raycast only owns the command palette. AeroSpace only manages windows. Each tool does one thing well.
12 · The Minimum Viable Stack
For someone starting today, the minimum viable productivity stack.
1. Raycast (Spotlight replacement)
2. Karabiner-Elements (Caps Lock -> Hyper)
3. Ghostty (terminal)
4. Homebrew + Brewfile (declarative install)
5. mise (runtime versions)
6. 1Password or Bitwarden (secrets)
7. chezmoi (dotfiles)
8. Rectangle or AeroSpace (window management)
9. CleanShot X (screenshots)
Add to it only when your workflow shows a real hole. You do not need all nine on day one. Items 1, 2, 3, and 4 alone shift your daily experience within a week.
Epilogue — Tools Are Just Tools
The most common mistake when building a productivity stack is making the tools themselves the goal. Spend a whole day polishing the dotfiles repo, write 100 lines of Karabiner JSON, ship zero code. That is a hobby, not work.
Tools belong only where you press a key 30 times a day, open a window 100 times a day, type the same command 10 times a day. Spend time on measurable friction, default the rest.
The bundle in this post is what I have refined over four years against that principle. It still shifts one or two pieces every year. 2024 was iTerm2 to Ghostty. 2025 was asdf to mise. Late 2025 was yabai to AeroSpace. Late 2026 will be something else. Adapting fast to those shifts is the real productivity.
30-Day Adoption Checklist
- Day 1: Install Raycast, move
cmd-space. Disable Spotlight's shortcut. - Day 2: Install Karabiner-Elements. Map Caps Lock to Hyper, Escape on tap.
- Day 3: Write a first Brewfile. Run
brew bundleonce. - Day 4: Switch to Ghostty. Drop the config file into your dotfiles.
- Day 7: Unify runtime versions under mise.
mise importif you had asdf. - Day 14: Migrate dotfiles to chezmoi. Wire secrets through 1Password/Bitwarden.
- Day 21: Add 5 to 10 personal shortcuts to Hammerspoon
init.lua. - Day 30: Standardize on AeroSpace or Rectangle for window management.
Anti-Patterns
- Hand-editing Karabiner JSON every day -> move to goku or a TS compiler.
brew installwith no Brewfile -> regret it on the next new Mac.- Plaintext
.envin git -> migrate to 1Password/Bitwarden references. - Installing all nine on day one -> stagger items 1 through 4 first, one week at a time.
- Installing yabai fresh -> in 2026, start with AeroSpace.
Coming Next
The next post tackles turning this bundle into a team standard: an in-house Brewfile, chezmoi templates, Raycast extension distribution, onboarding automation. Single-developer workflows and team workflows have different grain. When a 30-person engineering team starts every new hire on the same dotfiles base, the first week looks very different.
References
- Raycast — https://www.raycast.com/
- Raycast AI — https://www.raycast.com/core-features/ai
- Alfred — https://www.alfredapp.com/
- Karabiner-Elements — https://karabiner-elements.pqrs.org/
- Karabiner Complex Modifications — https://ke-complex-modifications.pqrs.org/
- Hammerspoon — https://www.hammerspoon.org/
- Homebrew — https://brew.sh/
- Homebrew Bundle and Brewfile — https://docs.brew.sh/Brew-Bundle-and-Brewfile
- Ghostty — https://ghostty.org/
- iTerm2 — https://iterm2.com/
- WezTerm — https://wezterm.org/
- Warp — https://www.warp.dev/
- Alacritty — https://alacritty.org/
- Rectangle — https://rectangleapp.com/
- AeroSpace — https://github.com/nikitabobko/AeroSpace
- AeroSpace Guide — https://nikitabobko.github.io/AeroSpace/guide
- 1Password CLI — https://developer.1password.com/docs/cli/
- Bitwarden CLI — https://bitwarden.com/help/cli/
- mise-en-place — https://mise.jdx.dev/
- asdf — https://asdf-vm.com/
- chezmoi — https://www.chezmoi.io/
- GNU Stow — https://www.gnu.org/software/stow/
- CleanShot X — https://cleanshot.com/
- Kap — https://getkap.co/
- Loom — https://www.loom.com/