One-script terminal environment setup for macOS, Debian/Ubuntu, and Windows (WSL). Run on a fresh machine, get a fully configured terminal in minutes.
π¨π³ δΈζηζζ‘£
| Platform | Status | Package Manager |
|---|---|---|
| π macOS | β Primary β battle-tested | Homebrew |
| π§ Debian / Ubuntu | π§ͺ Experimental β works but not extensively tested | apt + bundled binaries |
| πͺ Windows (WSL) | π§ͺ Experimental β works but not extensively tested | apt (inside WSL) |
| πͺ Windows (native) | β Not supported | Use WSL instead |
Note: This script is primarily developed and tested on macOS. Linux (Debian/Ubuntu) and WSL support has been added and works, but has not gone through long-term usage testing. Issues and PRs welcome!
git clone https://github.com/lewislulu/terminal-setup.git
cd terminal-setup && ./setup.shgit clone https://github.com/lewislulu/terminal-setup.git
cd terminal-setup && ./setup.shFirst install WSL if you haven't:
# In PowerShell (Admin)
wsl --installThen inside WSL:
git clone https://github.com/lewislulu/terminal-setup.git
cd terminal-setup && ./setup.sh./setup.sh --fish # Fish shell
./setup.sh --zsh # Zsh + fish-like plugins
./setup.sh --dry-run # Preview what would be done (no changes)One-liner (auto-clones):
bash <(curl -fsSL https://raw.githubusercontent.com/lewislulu/terminal-setup/main/setup.sh)| π Fish | π Zsh | |
|---|---|---|
| POSIX | β Own syntax | β Compatible |
| Autosuggestions | β Built-in | β via plugin |
| Syntax Highlighting | β Built-in | β via plugin |
| Node Manager | fnm (shared) | fnm (shared) |
| Config | ~/.config/fish/config.fish |
~/.zshrc |
| Best for | Clean defaults, no fuss | Scripting, POSIX compat |
| Component | What |
|---|---|
| Ghostty | GPU-accelerated terminal emulator |
| Fish or Zsh | Shell (your choice) |
| Starship | Cross-shell prompt (Catppuccin Mocha theme) |
| MesloLGS NF | Nerd Font for icons & powerline glyphs |
| bat | cat with syntax highlighting & line numbers |
| eza | ls with icons, git status, tree view |
| fd | find but fast & intuitive |
| ripgrep | grep but orders of magnitude faster |
| fzf | Fuzzy finder (Ctrl+R / Ctrl+T / Alt+C) |
| btop | Beautiful system monitor |
| zoxide | Smart cd that learns your habits |
| jq | JSON processor |
| tldr | Simplified man pages with examples |
| delta | Beautiful git diffs with syntax highlighting |
| lazygit | Git TUI |
| fnm | Fast Node Manager (Rust) |
| Zellij | Modern terminal multiplexer (optional) |
- Installs package manager (Homebrew on macOS, apt on Linux)
- Installs Ghostty terminal (macOS; Linux users install separately)
- Downloads MesloLGS NF nerd fonts
- Installs your shell of choice + plugins
- Installs all CLI tools (Homebrew on macOS, apt + GitHub releases on Linux)
- Installs Starship prompt with Catppuccin Mocha config
- Installs fnm + Node.js LTS (optional)
- Installs Zellij terminal multiplexer (optional)
- Deploys all config files (existing configs are backed up with timestamps)
- Full support, everything installs via Homebrew
- Ghostty installs as a native macOS app
- CLI tools install via apt where available, GitHub releases for others (delta, lazygit, eza)
batβbatcat,fdβfdfindβ symlinks are created automatically- Fonts install to
~/.local/share/fonts/ - Ghostty is not in apt β install manually via snap, build from source, or use another terminal
- Zsh plugins install via apt or git clone
- Everything runs inside WSL (Ubuntu/Debian layer)
- Terminal emulator runs on the Windows side β use Windows Terminal or Ghostty for Windows
- Script detects WSL automatically and adapts
- If run in native Windows (MINGW/Git Bash), the script will prompt you to install WSL
| Shortcut | Expands To |
|---|---|
ls |
eza --icons --group-directories-first |
ll |
eza -la --icons --group-directories-first |
lt |
eza --tree --icons --level=2 |
cat |
bat |
find |
fd |
grep |
rg |
top |
btop |
lg |
lazygit |
| Key | What |
|---|---|
Ctrl+R |
Fuzzy search command history |
Ctrl+T |
Fuzzy find files (uses fd as backend) |
Alt+C |
Fuzzy cd into directory |
fnm install 22 # Install Node 22
fnm install --lts # Install latest LTS
fnm default 22 # Set default version
fnm use 22 # Switch in current shell
echo "22" > .node-version # Auto-switch when entering this directoryBoth shell configs include a set-ssh-key function for quick SSH key switching:
set-ssh-key my-key-name # Clears agent, loads ~/.ssh/my-key-name
set-ssh-key # Shows available keys on errorBest practice: Prefer
~/.ssh/configwithHostaliases andIdentitiesOnly yesfor automatic key selection. Theset-ssh-keyfunction is a fallback for edge cases.
GPU-accelerated, native macOS app, fast startup, clean config format. It's what iTerm2 should have been β modern, minimal, and doesn't try to do everything. Still early but moving fast.
- Cross-shell: Same prompt config works in both Fish and Zsh. p10k is Zsh-only.
- TOML config: Declarative and readable vs p10k's wizard-generated mess.
- Rust binary: Fast, no shell framework dependency.
- Catppuccin theme: Consistent with the rest of the stack.
If you only use Zsh and want maximum prompt speed, p10k's instant prompt is technically faster. But Starship is fast enough and works everywhere.
Different people have different needs:
- Fish: Best out-of-box experience. Autosuggestions, syntax highlighting, completions β all built-in, zero config. But it's not POSIX-compatible, so
bashscripts won't work directly, and some tools assume POSIX shell syntax. - Zsh: POSIX-compatible, so all bash scripts and one-liners work. With plugins (autosuggestions + syntax-highlighting), you get 90% of Fish's UX. The trade-off: more moving parts.
If you're primarily a user/developer who runs other people's scripts β Zsh.
If you want the cleanest shell experience and don't mind the occasional bash script.sh β Fish.
We only install 3 Zsh plugins: zsh-autosuggestions, zsh-syntax-highlighting, zsh-completions.
For 3 plugins, a plugin manager is overkill:
- zinit: Original author abandoned it. Community fork (zdharma-continuum) exists but adds complexity for no gain at this scale. Turbo mode and ice modifiers are powerful but unnecessary here.
- antidote/sheldon: Good tools, but still an extra layer. More things that can break.
- Oh My Zsh: Framework, not a plugin manager. Loads 100+ files on startup. Slow.
- Homebrew: Already installed,
brew install+ onesourceline in.zshrc. Updates viabrew upgrade. Zero extra dependencies. Done.
Rule of thumb: If you have <5 plugins, Homebrew direct install. If you have 10+, consider antidote or sheldon.
On Linux: Zsh plugins install via apt (
zsh-autosuggestions,zsh-syntax-highlightingpackages) or git clone as fallback.
| fnm | nvm | |
|---|---|---|
| Language | Rust | Bash |
| Shell startup | ~1ms | ~200-400ms (or lazy-load hack) |
| Fish support | β Native | β Needs nvm.fish (separate project) |
| Zsh support | β Native | β Native |
| Auto-switch | β
--use-on-cd (reads .node-version, .nvmrc) |
|
| Install | brew install fnm / curl |
curl script, modifies shell rc |
| Shared across shells | β Same Node installs for Fish & Zsh | β nvm.fish and nvm-sh use different paths |
The killer reasons:
- Speed: nvm adds 200-400ms to shell startup. fnm adds ~1ms. This matters when you open terminals frequently.
- Unified: One tool, one Node install location (
~/.local/share/fnm/), works identically in Fish and Zsh. With nvm, you'd need nvm-sh for Zsh and nvm.fish for Fish β two different tools with incompatible storage paths. - Auto-switch:
fnm env --use-on-cdreads.node-versionor.nvmrcfiles and switches automatically when youcdinto a project. No extra hooks needed. - nvm.fish is a community project, not official nvm. It works well but it's another dependency with its own quirks (custom
nvm_datapath,set --universal nvm_default_version).
If you have existing .nvmrc files in your projects, fnm reads them β fully compatible.
- Designed for terminal use (monospace, clear at small sizes)
- Includes all Nerd Font glyphs (icons, powerline, devicons)
- Same font used by Powerlevel10k β battle-tested in terminals
- Available in Regular/Bold/Italic/Bold Italic
Alternatives: JetBrains Mono Nerd Font, Fira Code Nerd Font. All good choices. MesloLGS just has the widest compatibility.
Git's default diff output is functional but ugly. Delta adds:
- Syntax highlighting in diffs
- Line numbers
- Side-by-side view
- Proper word-level diff highlighting
- Navigate between files with
n/N
Configured globally β works with git diff, git log -p, git show, etc. Zero behavior change, just better output.
zoxide learns your most-used directories. After a few days:
z proj # jumps to ~/projects (or wherever you go most with "proj" in the path)
z doc # jumps to ~/Documents
zi # interactive fuzzy selection with fzfIt's cd with a brain. Falls back to regular cd behavior for explicit paths.
The single most impactful CLI tool you can install:
- Ctrl+R: Fuzzy search through command history (replaces the terrible default reverse-i-search)
- Ctrl+T: Find any file by fuzzy name match
- Alt+C: cd into any directory by fuzzy match
- Integrates with
fdautomatically (faster thanfind, respects.gitignore)
Once you use fzf for a week, you can't go back.
MIT




