Claude Code runs in a terminal. If you have never opened one professionally, that is where this guide starts. This is how I started. By the end, you will have a working installation (on your Mac), a first project, and a repo structure solid enough to build on for months.
All commands below run in the Terminal app on Mac. Open it with Spotlight (Cmd + Space, then type “Terminal”).
Step 1: Install Homebrew
Homebrew is a package manager for Mac. It lets you install developer tools with a single command. Claude Code depends on Node.js, and Homebrew is the cleanest way to get it.
Open Terminal and run:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
The installer will ask for your Mac password. Type it and press Enter. You will not see characters appear as you type. That is normal.
Verify the installation:
brew --version
You should see a version number. If you do, Homebrew is installed.
Step 2: Install Node.js
Claude Code is built on Node.js. You need it before you can install Claude Code.
brew install node
Verify:
node --version
You should see something like v22.x.x.
Step 3: Install Claude Code
npm install -g @anthropic-ai/claude-code
Verify:
npm list -g @anthropic-ai/claude-code
If the command claude is not found after installation, your terminal does not know where npm installed it. Fix it by adding npm’s global bin to your PATH:
export PATH="$PATH:$(npm bin -g)"
To make this permanent, add that line to your ~/.zshrc file (if you use zsh, which is the default on modern Macs).
Launch Claude Code from any folder:
claude
The first launch will ask you to log in with your Anthropic account.
Step 4: Install VS Code
VS Code is a code editor. For a non-technical user, it serves one purpose above all: visibility. You can see every file Claude creates or modifies, watch the project grow in real time, and read changes before they go further.
Download it and install it like any Mac application.
Once installed, open any project folder in VS Code with Cmd + O and select the folder. You can also open it from the terminal if you prefer:
code .
The . means “this folder”. Run it from inside the project folder.
Step 5: Install Python
Python is used by many automation scripts and is worth having regardless.
brew install python
Step 6: Install claude-mem
claude-mem is a persistent memory system for Claude Code. It stores observations across sessions so Claude remembers what was decided, what was tried, and what the project context is. Without it, every new session starts from scratch.
npm install -g claude-mem
Step 7: Install tmux
tmux is a terminal multiplexer. It lets you run multiple terminal sessions inside one window, and keeps them alive in the background even when you close the Terminal app.
brew install tmux
Start a named session:
tmux new -s myproject
Detach from it without stopping what is running: Ctrl + B, then D.
Reattach later:
tmux attach -t myproject
The repo: the most important part
The tools above are table stakes. The repo structure is what determines whether a project stays manageable over time.
What a repo is
A repo is a folder that Git tracks. Every file change, every addition, every deletion is recorded with a message explaining why. You can see the full history of a project, revert a mistake, and understand what changed between any two points in time.
A repo has two parts: a local copy on your machine, and a remote copy on GitHub. They stay in sync when you push your changes. GitHub is where the project lives safely, outside your machine.
Create a GitHub account at github.com if you do not have one. Then create a new repo from the GitHub interface: give it a name, keep it private, and click Create. GitHub will give you a command to clone it locally:
git clone https://github.com/your-username/my-project.git
cd my-project
Open the folder in VS Code with Cmd + O.
Who should make changes in the repo
You can edit files directly in VS Code or in the terminal. There is nothing stopping you. If you aren’t confident enough, you can let Claude Code handle changes, especially early on.
Claude knows what was built, why a file is structured a certain way, and what else might break if something changes. Claude will write commit messages that describe what changed and why, which makes the history readable six months later. When you edit directly, you proceed manually with that check and writing.
A good habit: if you want to change something in the project, open a Claude Code session and describe what you want. Claude will make the change, verify it, and commit it. If you edit a file yourself, tell Claude what you did so it can update its understanding of the project.
Create a new repo from scratch:
mkdir my-project
cd my-project
git init
CLAUDE.md: the project brain
CLAUDE.md is a plain text file at the root of your repo. Claude Code reads it at the start of every session. It is where you write the rules, the context, and the constraints for that project.
A minimal CLAUDE.md looks like this:
# My project
## What this is
A pipeline that pulls data from [source] and outputs [result].
## Rules
- Never delete files without asking
- Always commit after completing a task
- Use Python for all scripts
## Key files
- main.py — entry point
- config.json — settings
The more specific you are, the better the sessions go. Write it as if you are briefing a new team member who is very capable but knows nothing about your project.
The .claude directory
.claude/ is the control centre for your project. Everything Claude needs to know about how to behave lives there.
.claude/
settings.json ← permissions and behaviour, committed to Git
settings.local.json ← your personal overrides, gitignored
commands/ ← custom slash commands
rules/ ← modular instruction files
skills/ ← auto-invoked workflows
agents/ ← subagent personas
settings.json controls what Claude is allowed to do: which tools it can use, which commands it can run, and which behaviours are on or off. settings.local.json is for your personal preferences on top of the shared config. It is gitignored so your overrides do not affect teammates.
You rarely need to edit these files directly. But knowing they exist matters. If Claude asks for a permission it should already have, the settings file is where to look first.
Commands: custom slash commands
Files in .claude/commands/ become slash commands inside a session. A file called fix-issue.md becomes /project:fix-issue. A file called deploy.md becomes /project:deploy.
A command file is plain Markdown containing the instruction:
Review the current branch for issues.
Check for broken imports, missing error handling, and logic errors.
Report findings as a numbered list before making any changes.
Commands are for repeatable tasks you run often. Write them once, use them in every session.
Rules: modular instructions
.claude/rules/ holds instruction files that are included in the project context automatically. Use this to separate concerns: one file for coding style, one for testing conventions, one for API patterns.
This keeps CLAUDE.md from growing unwieldy. Instead of a single file with every rule, you have targeted files Claude loads and applies to the relevant work.
Skills: auto-invoked workflows
Skills in .claude/skills/ are workflows Claude triggers automatically based on what it detects, without you typing a command. A security review skill, for example, can run whenever Claude is about to write code that touches authentication.
Agents: subagent personas
.claude/agents/ defines specialised agents Claude can spawn as subagents for complex tasks. A code-reviewer.md agent has different instructions and a different stance than the main agent. Useful on larger projects where different types of work benefit from different behaviours.
CLAUDE.local.md
Beyond .claude/, there is also CLAUDE.local.md at the root of the project. This is a personal overrides file, gitignored, for instructions that apply only to your machine. Use it for local paths, personal preferences, or anything you do not want committed to the shared repo.
What a solid repo structure looks like
Here is a starting point that scales:
my-project/
CLAUDE.md ← project brain, committed, read every session
CLAUDE.local.md ← personal overrides, gitignored
README.md ← what the project is, for your future self
CHANGELOG.md ← log of every meaningful change, in plain English
.claude/
settings.json ← permissions and behaviour, committed
settings.local.json ← personal permissions, gitignored
commands/ ← slash commands for repeatable tasks
rules/ ← modular instruction files
skills/ ← auto-invoked workflows
agents/ ← subagent personas
src/ ← scripts and code
data/ ← inputs and outputs
docs/ ← decisions, references, notes
.gitignore ← files Git should not track (credentials, etc.)
CHANGELOG.md is a plain text log of what changed and when, written for a human reader rather than a machine. It answers the question “what happened to this project last week?” without reading through individual commits. Ask Claude to update it at the end of each session. It takes ten seconds and saves a lot of confusion later.
The most common mistake is starting without CLAUDE.md. Claude will still work, but each session begins without context. It guesses at constraints, repeats decisions already made, and occasionally undoes work from a previous session.
Write CLAUDE.md before the first session. Update it when something important changes. Treat it as the single source of truth for the project.
Security: protecting your keys before you start
This section is not optional. The most common way to create a serious problem early is to commit an API key to Git.
Once a key is committed, even if you delete it in the next commit, it stays in the Git history. Anyone who clones the repo can find it. This applies to your Anthropic API key, your Strava token, your database password, and anything else that grants access to a service.
The .env file
A .env file stores secrets locally. It never leaves your machine.
Create one at the root of your project:
touch .env
Open it in VS Code and add your keys in this format:
ANTHROPIC_API_KEY=sk-ant-...
STRAVA_CLIENT_SECRET=abc123...
DATABASE_URL=postgres://user:password@host/db
One key per line. No quotes needed. No spaces around the =.
To use these values in a Python script, install python-dotenv:
pip install python-dotenv
Then load the file at the top of your script:
from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv("ANTHROPIC_API_KEY")
In Node.js, the same pattern works with the dotenv package:
npm install dotenv
require('dotenv').config();
const apiKey = process.env.ANTHROPIC_API_KEY;
The .gitignore file
.gitignore tells Git which files to never track. Your .env must always be in it.
Create a .gitignore at the root of the project:
touch .gitignore
Add these lines:
.env
.env.local
*.env
__pycache__/
node_modules/
.DS_Store
Git will now ignore these files entirely. They will never appear in a commit, never be pushed to GitHub, and never be visible to anyone else.
Verify it is working:
git status
Your .env file should not appear in the list. If it does, the .gitignore is either missing or incorrectly written.
One API key per project
Create a dedicated API key for each project. Most AI providers let you create multiple keys in the same account. Use that.
The reason is containment. If one key is compromised, you revoke it without affecting anything else. If you use one key for everything and it leaks, every project is exposed at once.
For Anthropic keys, go to console.anthropic.com and create a new key named after the project. Copy it immediately. You will not be able to see it again.
A virtual card with a spending cap
API costs are billed per use. If a key leaks and someone runs a large number of requests against your account, the bill is yours.
The protection is a virtual bank card dedicated to each project, with a monthly spending cap set to something acceptable if it were lost. If the card is charged beyond what you expect, you notice immediately and the exposure is capped.
Revolut and similar services let you create virtual cards in seconds. Set a monthly limit before you connect the card to any API account.
This combination, a project-specific key plus a capped card, means a compromised key costs you a known amount at most. It does not become an open bill.
That is the setup. The rest is sessions.