Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dev Workstation Setup

Automated post-install script that turns a fresh macOS machine into a fully configured development workstation.

Supported: macOS 14+ (Apple Silicon + Intel)

Philosophy: Brew (CLI tools + GUI casks) · mise (language toolchains) · defaults write (system tweaks) · Brew Cask (JetBrains IDEs)

Quick Start

# 1. Clone the repo
git clone https://github.com/hugodantas/dev-setup.git
cd dev-setup

# 2. Create your config
cp config.env.example config.env
$EDITOR config.env  # set name, email, hostname, timezone

# 3. Run setup (one-shot, top-to-bottom — no menu, no reboot)
./setup.sh

Use -v / --verbose for full command output instead of spinners. No reboot is required.

Architecture

dev-setup/
├── setup.sh                  # Single one-shot install script (top-to-bottom)
├── Brewfile                  # Every brew formula, cask, and font in one place
├── config.env                # Personal values (gitignored)
├── config.env.example
├── .shellcheckrc             # Project-wide shellcheck config
├── .github/workflows/lint.yml # CI: shellcheck + Brewfile + TOML validation
├── lib/
│   ├── helpers.sh            # Colors, run(), logging, sudo keeper, spinner
│   └── installers.sh         # install_config (templated dotfile copier w/ backup)
├── shared/
│   ├── mise.toml             # Language toolchain (single source of truth) + [tasks]
│   └── devtools.sh           # install_mise_toolchain, configure_git (incl. SSH signing)
└── configs/                  # Dotfiles (sed-substituted at install, .bak on overwrite)
    ├── kitty.conf            # Kitty terminal
    ├── tmux.conf
    ├── zshrc / zprofile / bashrc
    └── claude/CLAUDE.md      # User-level Claude Code instructions

What Gets Installed

The script runs top-to-bottom in this order. No menu, no phases — one command, one pass.

System configuration (no installs)

Area Mechanism Details
Identity scutil Sets HostName, LocalHostName, ComputerName
Time systemsetup Timezone + NTP sync
Toolchain xcode-select --install Command Line Tools (if missing)
SSH server systemsetup -setremotelogin on Remote login enabled
Appearance defaults write Dark mode, JetBrainsMono on Kitty
Keyboard defaults write -g KeyRepeat/InitialKeyRepeat Fast key repeat, disable press-and-hold
Scrolling defaults write -g com.apple.swipescrolldirection Natural scrolling
Finder defaults write com.apple.finder Show extensions + hidden files + path bar + status bar; no .DS_Store on net/USB
Dock defaults write com.apple.dock Auto-hide (no delay), minimize-into-app
Input defaults write -g NS*Substitution* Disable autocorrect, smart quotes, smart dashes
Power pmset -c sleep 0 displaysleep 0 Never sleep on AC
SSH key ssh-keygen ed25519 key generated, added to Apple keychain
Touch ID for sudo /etc/pam.d/sudo_local Authenticate sudo with your fingerprint — no more password typing
Pre-flight check inline Aborts with a clear message if config.env still has placeholders
GitHub SSH key gh ssh-key add Auto-registers the generated key on the authed GitHub account
Signed commits git config gpg.format ssh Uses the same ed25519 key to sign every commit + tag

Dev tools, apps & IDEs

Category Manager Tools
Languages mise .NET 10, OpenJDK 25, Node.js LTS + pnpm + Bun, Go, Rust, Python 3.14, Lua, Flutter (stable), Neovim, OpenTofu, Firebase CLI
Editor Brew + git Neovim + LazyVim, tree-sitter
Git Brew Git, lazygit, GitHub CLI, delta (side-by-side diffs), git-lfs
Databases Brew PostgreSQL 18 CLI, Redis CLI
Container engine Brew Cask OrbStack
Container tools Brew lazydocker, dive
Infrastructure Brew Ansible + ansible-lint
AI Brew Claude Code (claude-code formula)
CLI Toolkit Brew eza, bat, ripgrep, fd, fzf, btop, yazi, tmux, httpie, jq, yq, sd, glow, fastfetch, tealdeer, shellcheck, hadolint, prettier, p7zip, trash-cli, grpcurl, sshpass — see CLI Toolkit Reference below
Mobile Google + Brew Android SDK cmdline-tools, FlutterFire CLI (Flutter itself via mise)
Terminal & Fonts Brew Cask Kitty + JetBrainsMono Nerd Font
GUI Apps Brew Cask Chromium, Signal, WhatsApp, Telegram, Discord, VLC, RetroArch, OBS Studio, Insomnia, Proxyman, Boop, Obsidian, LibreOffice, ProtonVPN, BalenaEtcher, Visual Studio Code, Fork, MarkEdit, Raycast, Rectangle, Maccy, AltTab, Stats, Keka, Snipaste
IDEs Brew Cask JetBrains Rider, JetBrains WebStorm, Android Studio

Install management: All formulas + casks live in a single declarative Brewfile. Edit that file to add/remove packages, then run brew bundle install (or just re-run setup.sh). To capture what's currently installed: brew bundle dump --force --file=Brewfile.

Configuration

All personal values live in config.env (gitignored). Copy config.env.example and edit:

GIT_USER_NAME="Your Name"
GIT_USER_EMAIL="you@example.com"
HOSTNAME="myhostname"          # sets HostName, LocalHostName, ComputerName
TIMEZONE="America/Sao_Paulo"

That's everything — the macOS path doesn't need GPU/printer/VM/etc. flags.

Optimizing tool versions with mise

Language toolchains are declared in shared/mise.toml and installed in one shot during Phase 2:

[tools]
node     = "lts"
go       = "latest"
rust     = "stable"
python   = "3.14"
java     = "openjdk-25"
dotnet   = "10"
flutter  = "stable"
# ...

After install, this file is copied to ~/.config/mise/config.toml. To pin a different version per-project, drop a local .mise.toml in the repo root — mise will switch automatically when you cd into it.

Built-in mise run tasks

shared/mise.toml also defines task shortcuts you can run from anywhere:

mise run update-all          # brew (formulas + casks) + mise upgrade
mise run sync-dotfiles       # re-copy configs/* to $HOME without re-running setup.sh
mise run sync-claude-config  # just refresh ~/.claude/CLAUDE.md after editing it

The update-all zsh alias points at mise run update-all, so an interactive update-all works too.

Shell Aliases

After setup, these shortcuts are available:

Alias Command Alias Command
lg lazygit ld lazydocker
fm yazi n / vim / v neovim
fl / flr flutter / flutter run dn / dnr / dnb / dnt / dnw dotnet / run / build / test / watch run
dk / dkc docker / docker compose tf tofu (OpenTofu)
ans / ansp ansible / ansible-playbook c claude code
ls / ll / lt / la eza variants cat bat
grep ripgrep find fd
top btop rm trash-put (safe delete)
diff delta update-all mise run update-all

Plus 177+ git aliases from the Oh My Zsh git plugin (gst, gc, gp, gd, gco, gcb, gl, glog, etc.).

Execution Flow

./setup.sh runs every step in this single linear order:

System config → SSH key → Homebrew → Kitty + fonts → mise toolchain →
Android SDK + Flutter Android wiring → Neovim + LazyVim → Ansible → OrbStack +
container tools → Claude Code → Git tools → DB clients → CLI toolkit →
GUI casks → JetBrains IDEs → dotfiles → summary
  • No menu, no phase prompts, no reboot — start it and walk away.
  • A sudo keepalive runs in the background to prevent timeout during long installs.
  • All commands run through a run() wrapper that handles spinners, logging, and error capture.
  • Logs are saved to /tmp/dev-setup-*.log.

Claude Code workstation memory

This setup also installs a user-level ~/.claude/CLAUDE.md (from configs/claude/CLAUDE.md). It tells Claude Code, every session, which CLI tools you have installed and which ones to prefer (e.g. rg over grep, fd over find, mise for language version pinning, OrbStack as the docker engine, etc.). If you edit that file in the repo, run mise run sync-claude-config to push it to ~/.claude/CLAUDE.md — no need to re-run the whole setup.

CLI Toolkit Reference

The Phase 2 install drops a lot of small CLI tools onto your $PATH. Most are "modern remakes" of classic UNIX commands — same job, friendlier UX. Here's what each one is for, in one line.

Drop-in replacements for classic commands

Tool Replaces What it does
eza ls Colorful ls with git status, tree mode, icons. ls, ll, lt, la aliases all use it.
bat cat cat with syntax highlighting + paging. Great for reading code in the terminal.
ripgrep (rg) grep Recursively searches code at terrifying speed. Respects .gitignore by default.
fd find Simpler, faster find with sane defaults (skips .git, hidden files, etc.).
sd sed for find-replace sd 'foo' 'bar' file.txt — no regex headaches for simple substitutions.
delta git diff viewer Side-by-side colored git diffs with line numbers and syntax highlighting.
trash-cli rm Moves files to the system trash instead of deleting forever. The rm alias points here.

Search & navigation

Tool What it does
fzf Fuzzy finder. Type a fragment, get an interactive list. Bound to Ctrl+R for shell history, Ctrl+T for files.

Data wrangling

Tool What it does
jq The de facto JSON processor for the shell. curl ... | jq '.items[].name'.
yq Same idea as jq, but for YAML, TOML, and XML.

HTTP & networking

Tool What it does
httpie (http) Friendly HTTP client. http POST api.example.com name=hugo instead of curl's flag soup.
grpcurl curl, but for gRPC services.
sshpass Lets you script ssh with a password (non-interactive). Last-resort tool — prefer keys.
wget / curl Classic downloaders, kept around because so many scripts need them.

TUIs (full-screen terminal apps)

Tool What it does
lazygit A git TUI — stage hunks, rewrite history, resolve conflicts visually. Aliased to lg.
lazydocker Same idea for Docker — see containers, logs, stats in one screen. Aliased to ld.
yazi Modern file manager in the terminal, with image previews. Aliased to fm.
btop Resource monitor — CPU/RAM/network graphs, prettier than htop. Aliased to top.
tmux Terminal multiplexer: split panes, detach sessions, reattach after SSH drops.

Markdown & docs

Tool What it does
glow Renders Markdown files beautifully in the terminal. glow README.md.
tealdeer (tldr) Community-written one-page summaries of common commands. tldr tar gives you the 5 flags you actually use.
fastfetch System info splash on shell startup (logo + OS, kernel, GPU, packages).

Build, lint, format

Tool What it does
shellcheck Static analyzer for bash/sh — catches quoting bugs, dead code, footguns.
hadolint Linter for Dockerfiles.
prettier Opinionated code formatter for JS/TS/JSON/YAML/Markdown/CSS/HTML.
tree-sitter Parser library Neovim uses for syntax highlighting; installed as a build-time dep for LazyVim.

Container introspection

Tool What it does
dive Explore a Docker image layer-by-layer to see what bloated it.

Misc utilities

Tool What it does
p7zip 7z command — extracts/creates .7z, .rar, .zip, etc.
git-lfs Git Large File Storage — handles big binaries in repos without fattening history.
ansible-lint Catches Ansible playbook anti-patterns.

What is OrbStack?

OrbStack is a macOS-native replacement for Docker Desktop. It bundles a Docker engine and a Linux VM manager in one app, but unlike Docker Desktop:

  • Drop-in compatibledocker, docker compose, and kubectl commands work unchanged.
  • Way lighter — boots in seconds, uses ~0.1% CPU at idle, and ~600 MB RAM (Docker Desktop typically eats several GB).
  • Faster file I/O — bind-mounts to your Mac filesystem are 2–10× faster than Docker Desktop.
  • Built for Apple Silicon — runs both ARM and x86 images natively via Rosetta.
  • Linux machines too — spin up a full Ubuntu/Fedora/Arch VM in one command (orb create ubuntu), which is handier than vagrant/utm for quick test boxes.
  • Free for personal use ($8/mo for commercial use).

If you've used Docker Desktop, OrbStack feels the same but without the fan noise.

Requirements

  • macOS 14+ (Sonoma or newer)
  • Internet connection
  • Admin access (for sudo steps in Phase 1)

License

MIT

About

Automated post-install setup for Fedora 43 KDE — Flatpak (GUI) | Brew (CLI) | DNF (System) | JetBrains (IDEs)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages