# General Development Ubuntu Setup A language-agnostic walkthrough for setting up a modern development environment on **Ubuntu 26.04 LTS (Resolute Raccoon)**, working identically on **Intel/AMD (`amd64`) and Arm (`arm64`)**. This is the Linux counterpart to [[General_Development_Mac_Tahoe_Setup]]. The pieces work together: - **Ghostty** — the terminal emulator (what you see) - **Starship** — the shell prompt (what tells you where you are) - **Git** — version control (covered in Prerequisites) - **GitHub CLI** — publishing repos from the command line (covered in Prerequisites) - **VS Code** — the editor (Part 6) - **Claude Code** — the AI, everywhere (Part 7) Each layer is independently swappable, but together they form a fast, low-friction stack with a single AI surface across both terminal and editor. Once this is complete, add language support by following the individual guides: - [[Python_Development_Ubuntu_Setup]] - [[C_Development_Ubuntu_Setup]] - [[Ruby_Development_Ubuntu_Setup]] - [[Go_Development_Ubuntu_Setup]] - [[Rust_Development_Ubuntu_Setup]] Each language guide assumes this general setup is already in place and only adds language-specific tooling. > [!tip] AI assistance is optional > Part 7 of this guide sets up Claude Code as an AI assistant. **You can skip Part 7 entirely** and still have a complete, professional dev environment from Parts 1–6. If you prefer a different AI tool (GitHub Copilot, Cursor, Continue, Cline, Aider), Part 7 includes pointers for adapting the setup to those instead. > [!info] One architecture, one set of instructions > Everything below is chosen to install the same way on both `amd64` and `arm64`. apt resolves the right package for your CPU automatically; the handful of tools installed via official scripts (Starship, uv, rustup, rv, Claude Code) detect your architecture themselves. You can confirm which architecture you're on at any time with `dpkg --print-architecture` (prints `amd64` or `arm64`) or `uname -m` (prints `x86_64` or `aarch64`). --- ## Prerequisites Before starting, you should have: - Ubuntu 26.04 LTS (Resolute Raccoon) on `amd64` or `arm64`, with a desktop session (these guides assume a GUI — Ghostty and the per-language GUI demos need a display) - `sudo` access for your user - A working network connection First, bring the system fully up to date and install the handful of build basics the rest of the setup leans on: ```bash sudo apt update && sudo apt upgrade -y # Build basics + helpers used throughout this guide sudo apt install -y build-essential curl wget git ca-certificates gnupg pkg-config ``` `build-essential` pulls in `gcc`, `g++`, `make`, and the headers needed to compile native code — several language toolchains (and a couple of tools below) expect a working C compiler. ### Why apt, not Homebrew? The Mac guide uses Homebrew for everything. On Linux we use **apt** instead. apt is first-class on both `amd64` and `arm64`; Homebrew on Linux is only officially supported on `x86_64`, so it would break the "works on both architectures" goal the moment you spin up an Arm VM. For the few tools not packaged in apt, we use the projects' own architecture-aware installers. ### Configuring Git Git is already installed from the prerequisites above. Set it up before doing anything else — these settings apply globally and only need to be set once per machine. #### Identity Every commit is stamped with a name and email. Use the same email you use for GitHub: ```bash git config --global user.name "Your Name" git config --global user.email "[email protected]" ``` > [!tip] If you use multiple identities > If you commit to both personal and work repos, you can override `user.email` per-repo later with `git config user.email "[email protected]"` inside that repo's directory. #### Modern defaults These have all become standard in 2026 but aren't always the default in older Git: ```bash # Use 'main' as the default branch name for new repos git config --global init.defaultBranch main # On 'git pull', fast-forward if possible; otherwise merge (don't rebase) git config --global pull.rebase false # On 'git push' for a new branch, automatically set upstream git config --global push.autoSetupRemote true # Colored output in status, diff, etc. git config --global color.ui auto # Use VS Code as the default editor for commit messages # (We'll install VS Code in Part 6 — this line can be run now or later) git config --global core.editor "code --wait" ``` #### Credential storage (libsecret) macOS uses the Keychain. On Ubuntu desktop, the equivalent is the GNOME Keyring, reached through `libsecret`. Git ships the libsecret credential helper as source (not a prebuilt binary on Debian/Ubuntu), so you compile it once: ```bash # Build deps for the helper sudo apt install -y libsecret-1-0 libsecret-1-dev libglib2.0-dev # Compile the helper that ships with git sudo make -C /usr/share/doc/git/contrib/credential/libsecret # Point git at the freshly built binary git config --global credential.helper \ /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret ``` After this, HTTPS credentials (e.g. a GitHub personal access token) are stored in the keyring on first use and reused silently afterward. > [!info] Headless or no keyring? > If you're on a server with no GNOME Keyring running, swap the helper for the cross-platform fallback `git config --global credential.helper "cache --timeout=3600"` (keeps credentials in memory for an hour) or `store` (plaintext in `~/.git-credentials` — convenient but unencrypted). On a desktop, prefer libsecret. #### Useful quality-of-life config ```bash # Auto-correct obvious typos like 'git stauts' → 'git status' git config --global help.autocorrect 20 # Prune deleted remote branches when fetching git config --global fetch.prune true # Show diff stats in commit message editor git config --global commit.verbose true # Better diff algorithm for code git config --global diff.algorithm histogram # Reuse conflict resolutions (magic — turn this on and forget about it) git config --global rerere.enabled true ``` #### SSH key for GitHub HTTPS with the credential helper works, but SSH is the conventional path for GitHub and avoids repeated auth prompts. ```bash # Generate a new ED25519 key ssh-keygen -t ed25519 -C "[email protected]" # Accept the default location (~/.ssh/id_ed25519) and set a passphrase # Start the ssh-agent for this session eval "$(ssh-agent -s)" # Configure ~/.ssh/config so the agent loads your key automatically cat >> ~/.ssh/config <<'EOF' Host github.com AddKeysToAgent yes IdentityFile ~/.ssh/id_ed25519 EOF # Add the key to the agent ssh-add ~/.ssh/id_ed25519 ``` > [!info] Remembering your passphrase across reboots > On macOS, `UseKeychain` stores the SSH passphrase in the Keychain. On Ubuntu desktop, GNOME Keyring's SSH agent does the same thing automatically the first time you `ssh` and check "remember." If you'd rather manage it yourself, the `keychain` package (`sudo apt install keychain`) keeps one agent alive across terminals — add `eval "$(keychain --eval --quiet id_ed25519)"` to `~/.bashrc`. Now copy the public key to your clipboard and paste it at <https://github.com/settings/keys>. Clipboard tools differ by display server: ```bash # Wayland (the Ubuntu 26.04 default session): sudo apt install -y wl-clipboard wl-copy < ~/.ssh/id_ed25519.pub # X11 (if you switched to an Xorg session): sudo apt install -y xclip xclip -selection clipboard < ~/.ssh/id_ed25519.pub ``` > [!tip] Which display server am I on? > Run `echo $XDG_SESSION_TYPE` — it prints `wayland` or `x11`. Ubuntu 26.04 defaults to Wayland. If a clipboard tool seems to do nothing, you're probably using the wrong one for your session. Then test: ```bash ssh -T [email protected] # Should say: "Hi yourusername! You've successfully authenticated..." ``` #### Verify ```bash git config --global --list ``` Should show everything you just set. If you ever need to edit these by hand, they all live in `~/.gitconfig`. ### Publishing a repo to GitHub `git` itself only manages local repositories and synchronization with remotes that already exist. It cannot create a new repository on GitHub's servers — that requires either the GitHub web UI or the `gh` CLI. The CLI is faster, scriptable, and keeps you in your terminal. #### Install and authenticate GitHub CLI (one-time) `gh` isn't in Ubuntu's default repos in a current-enough version, so add GitHub's official apt repository — it serves both `amd64` and `arm64`: ```bash # Add GitHub CLI's apt repository (architecture-aware) sudo mkdir -p -m 755 /etc/apt/keyrings wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg \ | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null sudo apt update sudo apt install -y gh ``` Then authenticate: ```bash gh auth login ``` `gh auth login` walks through an interactive prompt. Recommended answers: - **GitHub.com** (not Enterprise) - **HTTPS** as the Git protocol (the libsecret helper stores the credentials) - **Login with a web browser** (opens github.com, you paste a one-time code shown in the terminal, done) After auth, configure `gh` as git's credential helper so plain `git push` works for HTTPS remotes: ```bash gh auth setup-git ``` > [!info] SSH vs HTTPS for `gh` > If you already set up SSH keys in the previous section, you can choose SSH during `gh auth login` instead. Either works. HTTPS is slightly less friction because `gh` manages the credentials automatically; SSH is the GitHub convention for daily work and what most tutorials assume. #### Create a new GitHub repo from an existing local repo From inside any directory that already has a local git repo with at least one commit: ```bash gh repo create myproject --public --source=. --remote=origin --push ``` Flag breakdown: | Flag | Purpose | |------|---------| | `myproject` | Name of the new GitHub repo (owner defaults to your authenticated username) | | `--public` | Visibility. Use `--private` for private, `--internal` for org-only | | `--source=.` | Use the current directory's existing local repo as the source | | `--remote=origin` | Name the new remote "origin" (git convention) | | `--push` | Push the current branch immediately after creating the remote | Output looks like: ``` ✓ Created repository yourusername/myproject on GitHub ✓ Added remote https://github.com/yourusername/myproject.git ✓ Pushed commits to https://github.com/yourusername/myproject.git ``` Verify by opening it in your browser: ```bash gh repo view --web ``` #### The full new-project workflow Here's the complete sequence any time you start a new project, combining your language toolchain, git, and GitHub: ```bash # Create and initialize locally mkdir -p ~/projects && cd ~/projects mkdir myproject && cd myproject # <language-specific init> # Python: uv init --python 3.13 # Rust: cargo init # Go: go mod init github.com/you/myproject # Ruby: rv ruby pin 3.3 # C: touch main.c CMakeLists.txt # Typical .gitignore (language-specific; each language guide covers what to add) touch .gitignore git init git add . git commit -m "Initial commit" # Create on GitHub and push (assumes `gh` is authenticated) gh repo create myproject --private --source=. --remote=origin --push ``` A few commands, and you have a fully configured project: local environment, git history, and a GitHub remote. #### Day-to-day after the initial push No more `gh` needed for routine work — standard git handles it: ```bash # Edit files... git add . git commit -m "Add feature X" git push ``` Because your `.gitconfig` has `push.autoSetupRemote = true` from the previous section, the first push on any new branch automatically sets the upstream tracking. #### Alternative: plain git without `gh` If you don't want to install `gh`, or you need to work with a non-GitHub host (Bitbucket, GitLab, a self-hosted Gitea instance, etc.), the manual path is: **Step 1 — Create the empty repo on GitHub's web UI:** 1. Go to [github.com/new](https://github.com/new) 2. Enter the repository name 3. Choose Public or Private 4. **Leave all "Add a README/.gitignore/license" checkboxes unchecked** — otherwise you'll create a divergent history that's annoying to reconcile 5. Click "Create repository" **Step 2 — Wire it up locally:** ```bash # Using SSH (requires the SSH key setup above) git remote add origin [email protected]:yourusername/myproject.git # Or using HTTPS # git remote add origin https://github.com/yourusername/myproject.git # Verify git remote -v # Push and set upstream git push -u origin main ``` #### Useful `gh` commands ```bash gh repo view gh repo view --web gh repo clone owner/name gh repo list gh pr create gh pr list gh issue create gh issue list gh auth status ``` --- ## Part 1 — Installing Ghostty ### Install Ghostty landed in the official Ubuntu repositories with 26.04, so the simplest install is just apt — and it resolves the correct `amd64`/`arm64` build for you: ```bash sudo apt install -y ghostty ``` > [!info] Want a newer Ghostty than the repo ships? > The version in the 26.04 repos can lag behind upstream. For the latest, add the official PPA instead (it builds for both architectures): > ```bash > sudo add-apt-repository -y ppa:ghostty-dev/stable > sudo apt update > sudo apt install -y ghostty > ``` Launch it once from the Activities overview so the desktop registers it. ### Config file location Ghostty reads a single key-value file at: ``` ~/.config/ghostty/config ``` Create the directory and file if they don't exist: ```bash mkdir -p ~/.config/ghostty touch ~/.config/ghostty/config ``` > [!info] `~/.config/` is the standard location > Ghostty follows the XDG convention. The directory usually already exists on a desktop Ubuntu install, but `mkdir -p` is harmless if it doesn't. Ghostty falls back to built-in defaults until a config file exists. Reload config in-app with `Ctrl+Shift+,` after editing. No restart needed. ### Useful introspection commands Before customizing, these commands show you what's available: ```bash ghostty +list-themes ghostty +list-fonts ghostty +list-keybinds --default ghostty +show-config --default --docs ``` ### A recommended starter config Paste this into `~/.config/ghostty/config`. It's the [[Ubuntu Linux/_resources/configs/ghostty-config|companion Ghostty config]], tuned for Linux. Comments explain each section. ```ini # ── Appearance ──────────────────────────────────────────────── theme = Catppuccin Mocha font-family = "MesloLGM Nerd Font Mono" font-size = 12 window-padding-x = 12 window-padding-y = 12 window-padding-balance = true background-opacity = 0.97 background-blur-radius = 20 # ── Cursor ──────────────────────────────────────────────────── cursor-style = block cursor-style-blink = false # Shell integration forces a bar cursor at prompts by default; # this line preserves your cursor-style choice above. shell-integration-features = no-cursor,sudo,title # ── Linux / GTK ─────────────────────────────────────────────── gtk-titlebar = true gtk-tabs-location = top window-save-state = always # ── Scrollback & clipboard ──────────────────────────────────── scrollback-limit = 10000 clipboard-read = allow clipboard-write = allow copy-on-select = clipboard # ── Shell integration ───────────────────────────────────────── # 'detect' lets Ghostty inject the right bits for bash/zsh/fish/nu shell-integration = detect # ── Quality-of-life keybinds ────────────────────────────────── keybind = ctrl+shift+enter=toggle_split_zoom keybind = ctrl+shift+o=new_split:right keybind = ctrl+shift+e=new_split:down keybind = ctrl+shift+w=close_surface ``` ### Why each piece matters > [!info] Font > **MesloLGM Nerd Font Mono** includes programming glyphs (git branches, folder icons, language logos) that Starship uses. We install it in the next step. (Font size 12 is a touch smaller than the Mac guide's 14 — Linux font rendering tends to look a hair larger at the same nominal size; adjust to taste.) > [!info] No `macos-option-as-alt` here > That setting only exists on macOS. On Linux, `Alt` already behaves as `Alt` for word-wise motion (`Alt+B` / `Alt+F`), so there's nothing to fix. > [!info] Keybinds use `Ctrl+Shift` > The Mac config uses `Cmd`. Linux has no Command key, so the equivalents are bound to `Ctrl+Shift` (and these avoid clobbering the terminal's own `Ctrl+C`/`Ctrl+D`). > [!info] `shell-integration = detect` > Ghostty auto-injects shell integration code for **bash, zsh, fish, elvish, and nushell** — enabling Ctrl-click to jump to prompts, prompt markers, `ssh` terminfo handling, and more, with zero setup. ### Install the Nerd Font Nerd Fonts aren't in apt, but the font files themselves are architecture-independent — the same files work on `amd64` and `arm64`. Install MesloLG into your user fonts directory: ```bash mkdir -p ~/.local/share/fonts cd /tmp wget https://github.com/ryanoasis/nerd-fonts/releases/latest/download/Meslo.zip unzip -o Meslo.zip -d ~/.local/share/fonts/Meslo fc-cache -fv ``` Confirm the family is registered: ```bash fc-list | grep -i "MesloLGM Nerd Font" ``` Alternatives you might prefer (download the matching zip from the [Nerd Fonts releases](https://github.com/ryanoasis/nerd-fonts/releases) page): - `JetBrainsMono.zip` — clean, very popular - `FiraCode.zip` — programming ligatures - `Hack.zip` — dense, compact Swap the `font-family` line in the config accordingly. --- ## Part 2 — Installing and Configuring Starship ### What Starship is A cross-shell prompt written in Rust. It replaces the default bash prompt with one that shows **only what matters right now** — current directory, git branch/status, active language version (Python, Rust, Go, Ruby, Node, etc.), and more. It's fast enough to feel instantaneous, and it works identically on macOS and Linux. ### Install Starship's official installer detects your architecture (`amd64`/`arm64`) automatically: ```bash curl -sS https://starship.rs/install.sh | sh ``` > [!info] apt alternative > Ubuntu also packages Starship (`sudo apt install starship`), but the repo version can lag behind upstream. The official installer above always gives you the current release for your CPU. ### Enable in bash Ubuntu ships bash as the default shell. Add Starship's initialization to the **end** of `~/.bashrc`: ```bash echo 'eval "$(starship init bash)"' >> ~/.bashrc ``` Then reload: ```bash source ~/.bashrc ``` You should immediately see a new prompt. If glyphs look like boxes or question marks, your Ghostty font isn't a Nerd Font — revisit [[#Install the Nerd Font]] and confirm `font-family` in the Ghostty config. ### Configure Starship's config file lives at: ``` ~/.config/starship.toml ``` Create it with: ```bash mkdir -p ~/.config touch ~/.config/starship.toml ``` Paste in the [[Ubuntu Linux/_resources/configs/starship.toml|companion Starship config]] — it's identical to the Mac version, since Starship is cross-platform. A solid starting config for multi-language development: ```toml # ── Overall format ──────────────────────────────────────────── # Two-line prompt: info on top, clean input line below. format = """ $directory\ $git_branch\ $git_status\ $python\ $c\ $rust\ $golang\ $ruby\ $nodejs\ $cmd_duration\ $line_break\ $character""" # Prompt character (the bit you actually type after) [character] success_symbol = "[❯](bold green)" error_symbol = "[❯](bold red)" vimcmd_symbol = "[❮](bold green)" # Directory — keep it short [directory] truncation_length = 3 truncate_to_repo = true style = "bold cyan" # Git branch [git_branch] symbol = " " style = "bold purple" # Git status — dirty/clean indicators [git_status] style = "bold yellow" format = '([\[$all_status$ahead_behind\]]($style) )' # Language modules — each only shows when a relevant file is in the directory [python] symbol = " " style = "bold yellow" format = '[${symbol}${pyenv_prefix}(${version})(\($virtualenv\) )]($style)' [c] symbol = " " style = "149 bold" format = '[$symbol($version(-$name) )]($style)' [rust] symbol = " " style = "bold red" format = '[$symbol($version )]($style)' [golang] symbol = " " style = "bold cyan" format = '[$symbol($version )]($style)' [ruby] symbol = " " style = "bold red" format = '[$symbol($version )]($style)' # How long the last command took (only shows if > 2s) [cmd_duration] min_time = 2000 style = "bold yellow" format = "took [$duration]($style) " # Hide things not relevant to most dev work [aws] disabled = true [gcloud] disabled = true [nodejs] detect_files = ["package.json"] ``` ### Why the language modules matter When you `cd` into a project directory, Starship detects the language based on files present and shows: - **Python project** (has `.py`, `pyproject.toml`, or `.python-version`) → Python version + active venv - **C project** (has `.c` or `CMakeLists.txt`) → Compiler version - **Rust project** (has `Cargo.toml`) → Rust version - **Go project** (has `.go` or `go.mod`) → Go version - **Ruby project** (has `.rb`, `Gemfile`, or `.ruby-version`) → Ruby version Reading the prompt left-to-right tells you at a glance what language and version you're working with. No `which python`, `go version`, `ruby -v`, or `rustc --version` — the prompt tells you before you type. ### Useful Starship commands ```bash starship explain starship print-config starship module python starship preset list starship preset gruvbox-rainbow > ~/.config/starship.toml ``` --- ## Part 3 — How It All Fits Together Here's what a typical workflow looks like with the full stack: ``` ┌─────────────────────────────────────────────────────────────┐ │ Ghostty (GPU-rendered GTK terminal, amd64 or arm64) │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ bash (Ubuntu default shell) │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ │ │ Starship prompt │ │ │ │ │ │ ~/projects/demo main <lang version> │ │ │ │ │ │ ❯ <your commands> │ │ │ │ │ │ ┌───────────────────────────────────────────┐ │ │ │ │ │ │ │ Language toolchain (uv, cargo, go, etc.) │ │ │ │ │ │ │ └───────────────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ### A day-in-the-life example Regardless of which language guide you follow next, the pattern is the same: ```bash # Create a new project cd ~/projects mkdir demo && cd demo # <language-specific init> (uv init, cargo new, go mod init, etc.) # Prompt shows: projects/demo <lang version> ❯ git init git add . git commit -m "Initial commit" # After editing files, the prompt updates to show dirty state: # projects/demo main [!] <lang version> ❯ # Commit, push, and the prompt returns to clean git add . && git commit -m "Add feature X" gh repo create demo --private --source=. --remote=origin --push ``` Every piece of the prompt has a job: - **Directory** → where am I - **Git branch + status** → what's the repo state - **Language version** → which toolchain will run my next command --- ## Part 4 — Colors: Terminal vs Shell vs Prompt A common point of confusion: **setting a Ghostty theme does not, by itself, control how `ls` colors directories, executables, and symlinks.** These are separate layers, and each one is configured independently. ### The three layers | Layer | What it controls | Configured in | |-------|------------------|---------------| | **Terminal palette** | The 16 ANSI color slots + foreground/background. "When a program asks for color 34, render it as *this blue*." | Ghostty `theme = ...` | | **File-type colors** | Which color `ls` uses for directories, symlinks, executables, etc. | `LS_COLORS` (via `dircolors`) or `eza` | | **Syntax coloring at prompt** | Highlighting of commands as you type them (green = valid command, red = typo) | a bash line-editor add-on (ble.sh) | > [!info] Good news for Linux: `ls` is colorful out of the box > Unlike macOS (which ships BSD `ls`), Ubuntu uses **GNU coreutils**, and the default `~/.bashrc` already contains `alias ls='ls --color=auto'` plus a `dircolors` block. So directories show blue, executables green, and symlinks cyan with no extra work. The sections below are about *customizing* that, plus adding the command-line syntax highlighting that GNU `ls` doesn't provide. ### Customizing `ls` colors with `dircolors` GNU `ls` reads the `LS_COLORS` environment variable. To customize it, generate a `dircolors` database, edit it, and source it from `~/.bashrc`: ```bash # Write out the default database to edit dircolors -p > ~/.dircolors # Tell bash to load it (add to ~/.bashrc if not already present) echo 'eval "$(dircolors -b ~/.dircolors)"' >> ~/.bashrc source ~/.bashrc ``` Edit `~/.dircolors` to change, say, the color for directories (`DIR`) or specific extensions (`.tar`, `.jpg`). Each entry is a name plus an ANSI color code. This is the GNU equivalent of macOS's `LSCOLORS` string — more readable, and the same mechanism every Linux distro uses. ### Replacing `ls` with `eza` (recommended) `eza` is a modern `ls` replacement with richer colors, a git-status column, and file-type icons. It's in apt: ```bash sudo apt install -y eza ``` Then add to `~/.bashrc`: ```bash alias ls='eza --group-directories-first --icons' alias ll='eza -lah --group-directories-first --git --icons' alias tree='eza --tree --level=3 --git-ignore --icons' ``` With `eza`, directories are colored, executables are colored, git status shows as an extra column (`N` = new, `M` = modified, `I` = ignored), and file-type icons appear next to filenames (requires the Nerd Font you installed in Part 1). ### Command coloring at the bash prompt with ble.sh By default, commands you type into bash are all one color. zsh users get this from `zsh-syntax-highlighting` and `zsh-autosuggestions` — but those are zsh-only. The bash equivalent is **ble.sh** (Bash Line Editor), which provides both: - **Green** for valid commands on your `PATH`, **red** for typos / unknown commands - **Grey ghost text** suggesting completions from history (press `→` to accept) - Plus better multi-line editing and vim/emacs modes Install it (it's pure bash + a build step; needs `git`, `make`, and `gawk`, all already present): ```bash sudo apt install -y gawk git clone --recursive --depth 1 https://github.com/akinomyoga/ble.sh.git /tmp/ble.sh make -C /tmp/ble.sh install PREFIX=~/.local ``` Then wire it into `~/.bashrc`. ble.sh has a specific two-line pattern — one line **near the top**, one **at the very end**: ```bash # --- Near the TOP of ~/.bashrc (before other interactive setup) --- [[ $- == *i* ]] && source ~/.local/share/blesh/ble.sh --attach=none # ... the rest of your ~/.bashrc (aliases, starship init, etc.) ... # --- At the very END of ~/.bashrc --- [[ ! ${BLE_VERSION-} ]] || ble-attach ``` Reload with `source ~/.bashrc` (or just open a new Ghostty window). You'll immediately see: ``` ❯ git status ← all green (valid commands + args) ❯ gti status ← "gti" in red (typo) ❯ git sta ← "git" green, "sta" grey ghost text (press → to accept "status") ``` > [!warning] ble.sh ordering matters > The `source ... --attach=none` line must come **before** Starship's `eval "$(starship init bash)"`, and `ble-attach` must be the **last** interactive line in `~/.bashrc`. ble.sh integrates with Starship automatically when loaded in this order. ### Testing your color setup To confirm Ghostty is rendering the full 256-color palette correctly: ```bash # Quick 16-color test for i in {0..15}; do printf "\e[48;5;${i}m %2d \e[0m" "$i"; done; echo # 256-color test (nice gradient) for i in {0..255}; do printf "\e[48;5;${i}m \e[0m"; done; echo # True color (24-bit) test awk 'BEGIN{ for (i=0; i<77; i++) { r=255-(i*255/76); g=(i*510/76); b=(i*255/76); if (g>255) g=510-g; printf "\033[48;2;%d;%d;%dm ", r,g,b } printf "\033[0m\n" }' ``` If all three produce smooth color strips, Ghostty supports full truecolor out of the box. ### Summary of what you get from each piece | Result | Requires | |--------|----------| | A dark, pleasant background and nice base colors | Ghostty `theme = Catppuccin Mocha` | | `git status` showing red/green for changes | Nothing — git emits ANSI, Ghostty renders it | | `ls` showing blue directories, green executables | Nothing — GNU `ls --color=auto` is on by default | | Customized `ls` colors | `dircolors` + `LS_COLORS` | | File-type icons next to filenames | `eza --icons` + a Nerd Font | | Green/red coloring as you type commands | ble.sh | | Grey ghost-text command suggestions | ble.sh | | `~/projects/demo main 3.13.2` prompt | Starship + Nerd Font | The theme is just the paint palette. The shell tells each tool which colors to reach for. --- ## Part 5 — Optional Enhancements ### Modern CLI replacements ```bash sudo apt install -y eza bat ripgrep fd-find fzf zoxide direnv ``` > [!warning] Debian/Ubuntu renames two of these binaries > To avoid clashes with unrelated existing commands, Ubuntu ships **`bat` as `batcat`** and **`fd-find` as `fdfind`**. Add aliases (or symlinks) so the usual names work: > ```bash > mkdir -p ~/.local/bin > ln -sf "$(command -v batcat)" ~/.local/bin/bat > ln -sf "$(command -v fdfind)" ~/.local/bin/fd > ``` > Make sure `~/.local/bin` is on your `PATH` (Part 7 adds it for Claude Code; if you're not doing Part 7, add `export PATH="$HOME/.local/bin:$PATH"` to `~/.bashrc`). Then add to `~/.bashrc`: ```bash # Modern replacements alias ls='eza --group-directories-first' alias ll='eza -lah --group-directories-first --git' alias tree='eza --tree --level=3 --git-ignore' alias cat='bat --style=plain' # zoxide (smarter cd — learns your most-visited dirs) eval "$(zoxide init bash)" alias cd='z' # fzf (fuzzy finder — powers Ctrl+R history, Ctrl+T file picker) eval "$(fzf --bash)" ``` After running this, `Ctrl+R` becomes a fuzzy-searchable command history, and `z proj` jumps to the most-used directory matching "proj". > [!info] `fzf --bash` needs a current fzf > The `fzf --bash` integration shipped in fzf 0.48+. Ubuntu 26.04's `fzf` is new enough. On older systems you'd source `/usr/share/doc/fzf/examples/key-bindings.bash` instead. ### direnv — auto-activate per-project environments `direnv` was installed above. Hook it into bash: ```bash echo 'eval "$(direnv hook bash)"' >> ~/.bashrc ``` direnv reads an `.envrc` file in a project directory and loads it whenever you `cd` in, then unloads it when you leave — so each project gets its own environment (a Python virtualenv, toolchain env vars, a project-local `PATH`) with no manual activation. After creating an `.envrc`, run `direnv allow` once to trust it. The contents of `.envrc` are language-specific. Each language setup guide has a ready-to-use example: [[Python_Development_Ubuntu_Setup]], [[Go_Development_Ubuntu_Setup]], [[Rust_Development_Ubuntu_Setup]], [[Ruby_Development_Ubuntu_Setup]], and [[C_Development_Ubuntu_Setup]]. --- ## Part 6 — Visual Studio Code ### Install Add Microsoft's official apt repository — it carries `amd64`, `arm64`, and `armhf` builds, so the same steps work on any Ubuntu VM: ```bash # Microsoft GPG key + repo wget -qO- https://packages.microsoft.com/keys/microsoft.asc \ | gpg --dearmor | sudo tee /etc/apt/keyrings/packages.microsoft.gpg > /dev/null sudo chmod go+r /etc/apt/keyrings/packages.microsoft.gpg echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" \ | sudo tee /etc/apt/sources.list.d/vscode.list > /dev/null sudo apt update sudo apt install -y code ``` This installs VS Code and the `code` CLI shim, so you can open files and folders from Ghostty: ```bash code . code myfile.py code -d old.py new.py ``` > [!info] Why the apt repo, not Snap? > Ubuntu also offers VS Code as a Snap (`sudo snap install code --classic`), which works on both architectures too. The apt repo is preferred here because it integrates with `apt upgrade` alongside the rest of your stack and avoids Snap's confinement quirks (slower first launch, occasional issues with the integrated terminal's environment). Either is fine; pick one. ### Essential general-purpose extensions Install these from the command line so they're reproducible. These apply regardless of which languages you work in: ```bash # Better TOML (for editing pyproject.toml, Cargo.toml, starship.toml) code --install-extension tamasfe.even-better-toml # YAML (for GitHub Actions, docker-compose, Kubernetes) code --install-extension redhat.vscode-yaml # GitLens — richer git integration than the built-in code --install-extension eamodio.gitlens # EditorConfig — respects .editorconfig files in projects code --install-extension editorconfig.editorconfig ``` Language-specific extensions are covered in each language's individual setup guide. ### Configure VS Code — `settings.json` On Linux, VS Code stores its user settings at: ``` ~/.config/Code/User/settings.json ``` Open it from inside VS Code via `Ctrl+Shift+P` → "Preferences: Open User Settings (JSON)". Paste in the [[Ubuntu Linux/_resources/configs/vscode-settings.json|companion VS Code settings]], or merge with: ```json { // ── Editor appearance ───────────────────────────────────── "editor.fontFamily": "'MesloLGM Nerd Font Mono', 'Ubuntu Mono', monospace", "editor.fontSize": 13, "editor.fontLigatures": false, "editor.lineNumbers": "on", "editor.renderWhitespace": "boundary", "editor.rulers": [100], "editor.bracketPairColorization.enabled": true, "editor.guides.bracketPairs": "active", "editor.minimap.enabled": false, "editor.cursorBlinking": "solid", // ── Editor behavior ─────────────────────────────────────── "editor.formatOnSave": true, "editor.tabSize": 4, "editor.insertSpaces": true, "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, "files.trimFinalNewlines": true, // ── Terminal (integrated) ───────────────────────────────── "terminal.integrated.defaultProfile.linux": "bash", "terminal.integrated.fontFamily": "'MesloLGM Nerd Font Mono'", "terminal.integrated.fontSize": 13, "terminal.integrated.cursorBlinking": false, "terminal.integrated.cursorStyle": "block", "terminal.integrated.inheritEnv": true, // ── Files & search ──────────────────────────────────────── "files.exclude": { "**/.git": false }, "search.exclude": { "**/node_modules": true, "**/dist": true, "**/build": true, "**/target": true, "**/.venv": true }, // ── Git ─────────────────────────────────────────────────── "git.autofetch": true, "git.confirmSync": false, "git.enableSmartCommit": true, "git.suggestSmartCommit": false, // ── Workbench & theme ───────────────────────────────────── "workbench.colorTheme": "Default Dark Modern", "workbench.iconTheme": "vs-seti", "workbench.startupEditor": "none", "workbench.editor.enablePreview": false, // ── Telemetry ───────────────────────────────────────────── "telemetry.telemetryLevel": "off", // ── AI: disable built-in AI features ────────────────────── // This disables Copilot prompts and any built-in AI so Claude Code // is the only AI surface. See Part 7 for the rationale. "chat.disableAIFeatures": true } ``` ### Why each block matters > [!info] Font matching > Using the same **MesloLGM Nerd Font Mono** as Ghostty means your integrated terminal inside VS Code looks identical to your standalone Ghostty windows. The fallback `'Ubuntu Mono'` covers the case where the Nerd Font isn't found. > [!info] `terminal.integrated.defaultProfile.linux: bash` > This is the Linux equivalent of the Mac config's `...osx: zsh`. It makes VS Code's integrated terminal open bash — the same shell (with the same Starship prompt and ble.sh) you use in Ghostty. > [!info] Language-specific settings go in per-language guides > `settings.json` supports language-scoped blocks like `"[python]": { ... }` that only apply to that language's files. Each language guide adds its own block to this file. They don't conflict. --- ## Part 7 — Claude Code as the Only AI (Ghostty + VS Code) > [!important] AI assistance is entirely optional > **Everything in Parts 1–6 stands on its own.** Ghostty, Starship, Git, GitHub CLI, VS Code with language extensions, linters, formatters, and debuggers form a complete professional development environment. You can stop after Part 6 and have a fully functional setup. Skip this part entirely if you don't want an AI in your workflow, or come back to it later. > [!note] If you use a different AI tool > This guide configures Claude Code specifically. **The general principle — install your AI of choice, configure VS Code so it doesn't fight other AI tools — still applies, but the specific commands differ.** Quick pointers for the major alternatives: > > - **GitHub Copilot**: Install via the `github.copilot` and `github.copilot-chat` VS Code extensions. Sign in through VS Code's GitHub account integration. **Remove `"chat.disableAIFeatures": true` from settings.json** — Copilot uses VS Code's built-in chat UI that this setting hides. > - **Cursor**: Cursor is a separate editor (a fork of VS Code). It ships Linux `amd64`/`arm64` AppImage builds from cursor.com. Your VS Code extension list and settings.json mostly port over. > - **Continue**: Open-source, multi-provider. Install the `continue.continue` VS Code extension and configure your model provider (Anthropic API, OpenAI, local Ollama, etc.). > - **Cline**: Install the `saoudrizwan.claude-dev` VS Code extension; bring your own API key. > - **Aider**: Terminal-based, like Claude Code. Install with `uv tool install aider-chat` and configure with your provider's API key. > > Whichever you pick, the "uninstall competing extensions" advice still applies: pick one AI surface and remove the others. This section sets up Claude Code so it's your single AI surface across both the terminal (Ghostty) and the editor (VS Code). ### What you're setting up | Surface | How Claude Code appears | |---------|-------------------------| | **Ghostty** | Run `claude` inside any project directory → interactive terminal agent with file edits, shell commands, git operations | | **VS Code** | Spark icon in Activity Bar → sidebar chat with inline diffs, `@`-file mentions, plan mode, accept/reject buttons | Both surfaces share the **same auth**, **same `~/.claude/` config**, and **same `CLAUDE.md` project files**. ### Prerequisites - An **Anthropic account** with access to Claude Code. Claude Pro or Claude Max is the straightforward path; API credits via Anthropic Console also work. - **VS Code** (covered in Part 6). - **Ghostty** (covered in Part 1). > [!warning] The free Claude.ai plan does not include Claude Code > Any paid Claude subscription (Pro, Max, Teams, Enterprise) does, and so does Anthropic Console with API credits. ### Install Claude Code Anthropic ships a **native binary** as the recommended install — no Node.js dependency, auto-updates in the background, and the installer detects your architecture (`amd64`/`arm64`): ```bash curl -fsSL https://claude.ai/install.sh | bash ``` The binary lands at `~/.local/bin/claude`. Make sure that directory is on your PATH by adding this to `~/.bashrc`: ```bash export PATH="$HOME/.local/bin:$PATH" ``` Then `source ~/.bashrc` and verify: ```bash which claude claude --version ``` > [!info] Why not apt? > There's no official apt package for Claude Code. The native installer auto-updates silently in the background, which is what you want for an AI tool that improves weekly. The npm method (`npm install -g @anthropic-ai/claude-code`) still works but is deprecated — Anthropic recommends against it now. The native install supports Ubuntu 20.04+ on both architectures. ### First-run authentication From Ghostty, in any project directory: ```bash cd ~/projects claude ``` On first launch Claude Code opens a browser window for OAuth login. Sign in with the same Anthropic account as your Claude Pro/Max subscription. The token is saved to `~/.claude/` and reused across both Ghostty and VS Code. ### Using Claude Code in Ghostty Inside any project, start a session with `claude`. Useful built-in commands: ``` /help List all slash commands /init Generate a CLAUDE.md for this project (do this first!) /clear Clear conversation context /rewind Restore to a checkpoint (undo Claude's changes) /plugins Browse and install plugins /terminal-setup Auto-configure Shift+Enter for multi-line prompts /exit Leave the session ``` Claude can read and edit files, run shell commands (with your permission per-command), use `git`, and manage its context automatically. Every code change is checkpointed — press **Esc twice** or run `/rewind` to undo. > [!tip] Make CLAUDE.md your first step in any project > `/init` scans your project and writes a `CLAUDE.md` with project structure, conventions, and commonly-used commands. Claude loads this file at the start of every session. Commit it to git so it's shared with anyone else working on the repo. ### Installing the VS Code extension **Path A — From inside VS Code (recommended):** 1. `Ctrl+Shift+X` to open Extensions 2. Search **"Claude Code"** — install the one published by **Anthropic** (avoid look-alikes) 3. Reload VS Code if prompted **Path B — From Ghostty:** ```bash code --install-extension anthropic.claude-code ``` Or just run `claude` inside a VS Code integrated terminal once — Claude Code auto-installs its extension when it detects a VS Code environment. ### First use in VS Code After install, you'll see new UI elements: a **Spark icon** in the Activity Bar (left sidebar), a **Spark icon** in the top-right editor toolbar, and **"✱ Claude Code"** in the status bar. Click any of them; first launch reuses the same Anthropic auth as the CLI. Once signed in: - Type into the prompt box at the bottom of the sidebar - `@filename` to attach specific files as context - Highlight code → right-click → "Add to Claude Code context" - Changes appear as **inline diffs** — accept per-hunk or per-file ### Making Claude Code the only AI **1. Disable VS Code's built-in AI** (done in Part 6 via `settings.json`): ```json "chat.disableAIFeatures": true ``` **2. Don't install (or uninstall) competing extensions:** ```bash code --uninstall-extension github.copilot code --uninstall-extension github.copilot-chat code --uninstall-extension continue.continue code --uninstall-extension saoudrizwan.claude-dev code --uninstall-extension sourcegraph.cody-ai ``` **3. In Ghostty, don't wire in competing CLIs.** Claude Code is sufficient — avoid installing Aider, Gemini CLI, or similar alongside it if the goal is a single AI. ### Ghostty vs VS Code — when to use which | Use **Ghostty + `claude`** when | Use **VS Code extension** when | |---------------------------------|--------------------------------| | Exploring a new repo you haven't opened yet | Reviewing changes with inline diffs | | Bulk refactors spanning many files | Editing a specific function with tight feedback | | Running tests/builds interactively | Using `@mentions` to pull specific files into context | | SSH'd into a remote machine | You want to pair with Claude while you edit | They aren't mutually exclusive — it's common to have `claude` running in a Ghostty pane while VS Code is open on the same project. ### Useful extras **Multi-line prompts in VS Code's integrated terminal** — run this once inside Claude Code: ``` /terminal-setup ``` **Checkpoints** — Claude automatically checkpoints before each change. Undo with `Esc` twice (in terminal) or `/rewind`. Checkpoints only cover Claude's edits — keep using git commits for the real backup. --- ## Troubleshooting > [!warning] Glyphs show as boxes or `?` in the prompt > Your font isn't a Nerd Font. Reinstall it (Part 1) and confirm `font-family = "MesloLGM Nerd Font Mono"` in `~/.config/ghostty/config`, then run `fc-cache -fv`. > [!warning] Ghostty won't launch / shows a GTK or GL error > Ghostty needs GPU/GL access. In a VM, make sure 3D acceleration is enabled in the hypervisor (VirtualBox/VMware/UTM) or use a virtio-gpu display. As a fallback you can run any other terminal and still use the rest of this stack — the shell config is what matters. > [!warning] `command not found` for a tool right after installing > Open a new Ghostty window or run `source ~/.bashrc`. If a tool installed to `~/.local/bin` (Claude Code, uv tools) still isn't found, confirm `export PATH="$HOME/.local/bin:$PATH"` is in `~/.bashrc`. > [!warning] `bat`/`fd` say "command not found" but they're installed > On Ubuntu they're `batcat`/`fdfind`. Create the aliases/symlinks shown in Part 5. > [!warning] ble.sh broke my prompt or pasting > Confirm the ordering: `source ... --attach=none` near the top of `~/.bashrc`, `ble-attach` as the very last line, and `starship init bash` between them. If something's badly broken, comment out the two ble.sh lines and reload to get a clean bash. > [!warning] `git push` asks for username/password every time > You're using HTTPS without a working credential helper. Either set up the libsecret helper (Prerequisites → Credential storage) or run `gh auth setup-git`, or switch the remote to SSH. > [!warning] Starship language version not showing > Starship only shows a language module when it detects a matching project — you need the relevant file (e.g. `pyproject.toml`, `go.mod`, `Cargo.toml`) in the directory. This is intentional, to avoid clutter. > [!warning] `claude: command not found` after install > The native installer puts the binary at `~/.local/bin/claude`. Add `export PATH="$HOME/.local/bin:$PATH"` to `~/.bashrc` and `source` it. A stale npm install can shadow the native binary — check with `which -a claude`. --- ## Summary — the complete install sequence > [!warning] This is a checklist, not a script > The block below is **not a shell script you can save and run.** It's a numbered sequence of commands to **copy and paste into Ghostty (or GNOME Terminal) one block at a time**, in order. Several steps depend on the previous one having finished, and three steps require you to **manually edit files** before continuing: > > - **Step 11** asks you to paste the recommended **Ghostty config** into `~/.config/ghostty/config` > - **Step 11** also asks you to paste the recommended **Starship config** into `~/.config/starship.toml` > - **Step 11** also asks you to paste the recommended **VS Code settings** into `~/.config/Code/User/settings.json` > - **Step 9** asks you to add the **ble.sh two-line pattern** to `~/.bashrc` > > Two later steps (12 — `gh auth login`; 13 — `claude` first run) **open a browser window** and require you to complete OAuth login interactively before continuing. ```bash # 1. Update + build basics sudo apt update && sudo apt upgrade -y sudo apt install -y build-essential curl wget git ca-certificates gnupg pkg-config gawk unzip # 2. Core CLI tools (note: bat→batcat, fd-find→fdfind) sudo apt install -y eza bat ripgrep fd-find fzf zoxide direnv # 3. Terminal sudo apt install -y ghostty # 4. Nerd Font mkdir -p ~/.local/share/fonts && cd /tmp wget https://github.com/ryanoasis/nerd-fonts/releases/latest/download/Meslo.zip unzip -o Meslo.zip -d ~/.local/share/fonts/Meslo && fc-cache -fv # 5. GitHub CLI (official apt repo) sudo mkdir -p -m 755 /etc/apt/keyrings wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg \ | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null sudo apt update && sudo apt install -y gh # 6. VS Code (official apt repo) wget -qO- https://packages.microsoft.com/keys/microsoft.asc \ | gpg --dearmor | sudo tee /etc/apt/keyrings/packages.microsoft.gpg > /dev/null sudo chmod go+r /etc/apt/keyrings/packages.microsoft.gpg echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" \ | sudo tee /etc/apt/sources.list.d/vscode.list > /dev/null sudo apt update && sudo apt install -y code # 7. Starship (official installer — architecture-aware) curl -sS https://starship.rs/install.sh | sh # 8. ble.sh (bash syntax highlighting + autosuggestions) git clone --recursive --depth 1 https://github.com/akinomyoga/ble.sh.git /tmp/ble.sh make -C /tmp/ble.sh install PREFIX=~/.local # 9. Git config (REPLACE name/email) git config --global user.name "Your Name" git config --global user.email "[email protected]" git config --global init.defaultBranch main git config --global pull.rebase false git config --global push.autoSetupRemote true git config --global color.ui auto git config --global core.editor "code --wait" git config --global fetch.prune true git config --global commit.verbose true git config --global diff.algorithm histogram git config --global rerere.enabled true git config --global help.autocorrect 20 # Credential helper (compile libsecret once): sudo apt install -y libsecret-1-0 libsecret-1-dev libglib2.0-dev sudo make -C /usr/share/doc/git/contrib/credential/libsecret git config --global credential.helper \ /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret # 10. General-purpose VS Code extensions code --install-extension tamasfe.even-better-toml code --install-extension redhat.vscode-yaml code --install-extension eamodio.gitlens code --install-extension editorconfig.editorconfig # 11. Claude Code (native installer — architecture-aware) curl -fsSL https://claude.ai/install.sh | bash code --install-extension anthropic.claude-code # 12. Wire up ~/.bashrc — add these lines. # IMPORTANT: ble.sh has a top line and a bottom line (see Part 4). # Near the TOP of ~/.bashrc: # [[ $- == *i* ]] && source ~/.local/share/blesh/ble.sh --attach=none # Then (anywhere after, in this order): echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc mkdir -p ~/.local/bin ln -sf "$(command -v batcat)" ~/.local/bin/bat ln -sf "$(command -v fdfind)" ~/.local/bin/fd echo 'eval "$(starship init bash)"' >> ~/.bashrc echo 'eval "$(zoxide init bash)"' >> ~/.bashrc echo 'eval "$(direnv hook bash)"' >> ~/.bashrc echo 'eval "$(fzf --bash)"' >> ~/.bashrc echo "alias ls='eza --group-directories-first --icons'" >> ~/.bashrc echo "alias ll='eza -lah --group-directories-first --git --icons'" >> ~/.bashrc echo "alias tree='eza --tree --level=3 --git-ignore --icons'" >> ~/.bashrc echo "alias cat='bat --style=plain'" >> ~/.bashrc echo "alias cd='z'" >> ~/.bashrc # At the VERY END of ~/.bashrc: echo '[[ ! ${BLE_VERSION-} ]] || ble-attach' >> ~/.bashrc # 13. Paste the Ghostty / Starship / VS Code configs into place # (see Parts 1, 2, and 6 for the recommended contents) mkdir -p ~/.config/ghostty ~/.config touch ~/.config/ghostty/config ~/.config/starship.toml # 14. Authenticate GitHub CLI (interactive — HTTPS, browser login) gh auth login gh auth setup-git # 15. First launch of Claude Code (interactive OAuth in browser) # Run `claude` in Ghostty — a browser window opens for login. ``` Open a fresh Ghostty window, and you're done with the general setup. Pick a language guide to continue: - [[Python_Development_Ubuntu_Setup]] - [[C_Development_Ubuntu_Setup]] - [[Ruby_Development_Ubuntu_Setup]] - [[Go_Development_Ubuntu_Setup]] - [[Rust_Development_Ubuntu_Setup]] --- ## Related notes **Same setup on macOS:** - [[General_Development_Mac_Tahoe_Setup]] — the Apple Silicon counterpart to this guide **Language-specific setup (build on this general guide):** - [[Python_Development_Ubuntu_Setup]] - [[C_Development_Ubuntu_Setup]] - [[Ruby_Development_Ubuntu_Setup]] - [[Go_Development_Ubuntu_Setup]] - [[Rust_Development_Ubuntu_Setup]] **Topic references:** - [Ubuntu 26.04 LTS release notes](https://documentation.ubuntu.com/release-notes/26.04/) - [bash Reference Manual](https://www.gnu.org/software/bash/manual/) - [ble.sh](https://github.com/akinomyoga/ble.sh) - [Git Cheat Sheet](https://git-scm.com/cheat-sheet) - [Claude Code Tips](https://code.claude.com/docs/en/best-practices) - [CLAUDE.md Templates](https://code.claude.com/docs/en/memory)