janwillemaltink
  • home
  • blog
  • Finetuning gids
💻

New Macbook Guide

Introduction

For who is this guide?

This is my personal migration guide for setting up a fresh MacBook. It's opinionated and assumes a very specific toolchain:

  • Password Manager / SSH Agent: 1Password
  • Package Manager: Homebrew (everything goes through Brew)
  • Shell: Zsh with Starship prompt
  • Terminal: Ghostty
  • JavaScript/Typescript: pnpm
  • Python: uv (Ruff as main)
  • Editors: Cursor (VS Code backup)
  • Browser: Brave
  • Application Launcher: Raycast

It describes detailed configuration steps for very specific situations (like setting up a 1Password SSH agent connection with a Hetzner VPS). I've still chosen to post it here, though; the overall steps or structure of the dotfiles repository might be helpful for anyone reading.

Phases

The guide follows a deliberate order — each phase builds on the previous:

Phase
Purpose
1. Foundation
macOS setup, security, accounts
2. Enablers
Xcode CLI tools, Homebrew
3. Identity & SSH
1Password, SSH keys, authentication
4. Git
Clone dotfiles, configure Git
5. Shell & Tools
Zsh, terminal, dev runtimes
6. Applications
GUI apps, editor & AI configs

Dotfiles

If possible, I try to use dotfiles to configure the settings of my applications. This allows me to use Git version manager. Not all applications offer this type of configuration though.

The repository can be found here:

dotfiles

jwa91 ⋅ 22 days ago

To streamline and standardize Python development, this repo is also needed:

python-template

jwa91 ⋅ 8 days ago

Phase 1: The Foundation (System & Accounts)

Do this before installing any software to avoid permission headaches later.

1.1 Update macOS

Run softwareupdate --all --install --force or check System Settings. Do this first to ensure Xcode tools match your OS version.

1.2 User Accounts (Security Best Practice):

Create a separate Admin account (managed by you) and downgrade your daily driver account to Standard user. This prevents accidental system-wide changes and limits malware reach.

*macOS prompts for admin credentials when needed anyway — so even with an admin daily account, you’re already in a pseudo “standard + escalate” model. This makes the security model explicit and safer.

1.3 FileVault

Turn on FileVault (Disk Encryption) immediately in System Settings > Privacy & Security.

1.4 HostName

Give your machine a recognizable name (useful for networking/terminal prompts).

sudo scutil --set HostName "dev-macbook"
sudo scutil --set ComputerName "dev-macbook"
sudo scutil --set LocalHostName "dev-macbook"

Phase 2: The Enablers

The core dependencies for everything else.

2.1 Xcode Command Line Tools

You rarely need the full Xcode app (~40GB) immediately. Start with just the CLI tools (~600MB).

xcode-select --install 

2.2 Homebrew

The Package Manager. Never install tools (Node, Git, Python) manually. Use Brew.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Phase 3: Identity and SSH

Establish cryptographic identity and a reusable SSH foundation.

3.1 Install 1password

1Password will be our SSH agent. Install both the desktop app and the CLI:

brew install --cask 1password
brew install 1password-cli

Roles:

  • Desktop app → owns:
    • SSH agent
    • private key storage
    • Touch ID / Apple Watch auth
  • CLI (op) → gives you:
    • terminal access to vaults
    • automation
    • scripting
    • future Git signing / secrets injection

3.2 Sign in to 1Password using the desktop app

  1. Sign in
  2. Enable:
    • Start at login
    • Keep in menubar
  3. Enable SSH Agent in Settings → Developer

3.3 Sign in to 1Passord CLI

  1. Sign in:
op signin
  1. Verify:
op whoami
ℹ️

Before we continue

It helps to briefly explain the general set up. We will maintain one SSH key per security domain, in my case i start with 2:

  • GitHub key → Git operations only
  • Hetzner key → VPS access only

The second one will most likely not be that use-full for most people.

3.4 Generate the SSH key’s in the 1Password app

As of now, the official, fully supported way to generate SSH keys for the 1Password SSH agent is still via the desktop app UI. The CLI can manage SSH items, but key generation + agent registration is still primarily app-driven on macOS.

  1. Go to your Personal / Private vault
  2. New Item → SSH Key
  3. Click Add Private Key → Generate New Key
  4. Use type Ed25519
  5. Give it a clear title like:
  6. GitHub – MacBook Pro 2025

  7. Save
  8. Repeat for Hetzner

Now 1Password holds:

  • private key
  • public key
  • fingerprint

No ssh-keygen needed on the Mac.

3.5 Prepare Public Keys locally

  1. Open 1Password.
  2. Select your GitHub key item.
  3. Under the section "public key", click only on the key code (starts with ssh-ed25519...) to copy it.
  4. Create the file:
mkdir -p ~/.ssh
nano ~/.ssh/github.pub
  1. Paste the public key and save.
  2. Repeat this for your Hetzner key (e.g., ~/.ssh/hetzner.pub).

3.6 Register Keys at Services

Github

  1. Copy the public key to your clipboard:
pbcopy < ~/.ssh/github.pub
  1. Go to GitHub Settings > SSH and GPG keys.
  2. Click New SSH key.
  3. Title: Dev MacBook Pro 2025 (or similar).
  4. Key type: Authentication Key.
  5. Paste the key and save.

Hetzner

  1. Log in to the Hetzner Cloud Console in your browser.
  2. Select your server and click the >_ (Console) icon to open the terminal window.
  3. Log in with your credentials
  4. Open the authorized keys file:
nano ~/.ssh/authorized_keys
  1. Add the public key on a new line*

*just cmd v doesnt work in a browser console like this, but you can do right mouse click paste.

  1. Save and exit.

3.7 Configure SSH Config

Back in the terminal of the macbook, create and edit the SSH config file

nano ~/.ssh/config

Add the following configuration:

Host *
  IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"

Host github.com
  User git

Host hetzner
  HostName <YOUR_VPS_IP_OR_HOSTNAME>
  User jw
  1. Ensure 1Password is unlocked
  2. Run the GitHub test:
ssh -T git@github.com

Expected output: “Hi [username]! You’ve succesfully authenticated”

Quick note about steps 4-6 below.. In theory they could also be executed with just one single script. The reason I have chosen to split it up, is that it helps me to keep an overview

Phase 4: Git

Configure Git identity and preferences from dotfiles.

4.1 Clone the dotfiles repo

git clone git@github.com:jwa91/dotfiles.git ~/dotfiles

4.2 Run the Git setup script

cd ~/dotfiles/git
./setup.sh

This creates the symlink.

4.3 Verify

git config --global --list

What the dotfiles git/ folder contains:

📂 File
🎯 Purpose
config
Global Git configuration
commit_template.txt
Template shown when writing commits
setup.sh
Symlinks config to ~/.gitconfig

Phase 5: Shell, Terminal & Prompt

Bootstrap the shell environment and install the developer ecosystem.

5.1 Install Zsh Configuration

Run the first setup script. This focuses **only** on making your terminal look correct and behave smartly. It installs core shell dependencies (`starship`, `fzf`), sets up your plugins, and symlinks your config files (including Ghostty and Starship).

cd ~/dotfiles/zsh/setup
./install-zsh.sh

What this does:

  • Installs Starship (prompt) & FZF (search)
  • Symlinks .zshrc, .zshenv, etc.
  • Sets up Ghostty config
  • Creates ~/Developer and other base directories

Restart your terminal (or open a new tab) after this step to see the new prompt.

I really like the look of it!
I really like the look of it!

5.2 Install Developer Tools

Now that the shell is ready, install your actual work tools. This script uses Homebrew Bundle to install everything defined in Brewfile (Node, Python/uv, Bun, Ghostty App, Fonts, etc.).

./install-tools.sh

What this does:

  • Installs Language Runtimes: bun, pnpm, uv
  • Installs GUI Apps: ghostty
  • Installs Fonts: JetBrainsMono Nerd Font
  • Clones Templates: Fetches your Python templates to ~/Developer/templates

To learn more about that last thing, see the dedicated Git repository.

Phase 6: Applications & Config

Install GUI apps and symlink their configurations.

6.1 Install Applications

With the shell script..

cd ~/dotfiles/config/setup
./install-apps.sh

..the following Brewfile will get installed:

6.2 Link Application Configs

Symlink all application settings to your dotfiles:

./link-apps.sh

What this does:

  • Links Cursor settings, keybindings, snippets, and MCP config
  • Links VS Code settings, keybindings, snippets
  • Links Claude Desktop config
  • Links Claude Code settings, commands, and agents
  • Links Codex config and instructions
  • Links GitHub CLI config
  • Links Cheat config and personal cheatsheets

7. Next steps..

Given this is my first attempt at dotfiles, this repo will probably change often.

janwillemaltink.
InstagramGitHubX
# Development & IDEs
cask "cursor"
cask "visual-studio-code"

# AI & LLM Tools
cask "claude"
cask "claude-code"
cask "codex"
cask "ollama"

# Productivity & Utilities
cask "raycast"
cask "hiddenbar"

# Browsers & Communication
cask "brave-browser"
cask "whatsapp"
cask "telegram"

# Media
cask "spotify"

# CLI Tools
brew "gh"
brew "tree"
brew "curl"
brew "cheat"