A plain-language guide to GitHub + Claude Code — for someone who has never used either.
By Joy · Source: github.com/joyzhzh/first-repo · Updated 23 July 2026
WALKTHROUGH.md takes you from this folder to a live website in eight stages. Each stage is one short prompt you paste into Claude Code, and it stops after each one so you can check. To begin: read Part 0 below — five ideas, a few minutes. Then:
first-repo-main; rename it to first-repo so the paths below match.Do Stage 0 of WALKTHROUGH.md.(Prefer a terminal? The same thing is cd ~/Downloads/first-repo, then claude.)
This page is the reference behind the walkthrough. You do not need to read it front to back —
each part stands alone, so come back for the part you need, when you need it.
Everything here comes from a real setup that has been running since June 2026. The commands are the ones actually in use. Where something is a known trap it is marked ⚠️ Trap — every one of those cost someone real time.
You do not need to know how to code. Everything below is copy-paste. By the end you will have a live website, a private backup of your work, and — this is Part 6, the part people skip — a way of asking for work that gets good results instead of frustrating ones.
Two halves. One teaches you; one teaches your tools.
| For you to read | |
|---|---|
| WALKTHROUGH.md | Start here. Eight stages, nothing → live website. One short prompt each. |
| README.md | The reference — the why behind the walkthrough. (This page is the same thing.) |
| PROMPTS.md | Copy-paste prompts for every task here. Keep it open while you work. |
| templates/ | Three finished academic web pages and one theme file, so you never start from a blank screen. |
| For Claude Code to adopt | |
| starter/ | Safety rules and a change queue you copy into your own project, so the agent knows what never to do there from day one. |
| RUNBOOK.md | For an agent walking a beginner through setup, live. |
The habit this kit teaches: keep the instructions in a file, then point at the file. That is why every walkthrough prompt is one line — the real instructions live in files you can read and correct. A long prompt drifts every time you retype it. A file does not.
Private by default. Nothing published without you saying so. Nothing deleted, ever. Secrets kept out of git from the first commit. Every irreversible step is yours to take, never the agent's. And every piece is the smallest thing that works — no build steps, no frameworks, nothing you cannot read and understand yourself.
Nothing here is clever. That is deliberate. Clever is how beginners get stuck somewhere they cannot debug.
Almost everything else can be handed to Claude Code. These moments are yours — either because a machine genuinely cannot do them, or because they are irreversible.
| Moment | Why it is yours |
|---|---|
| The GitHub browser sign-in (Part 2) | You are proving you are you. The agent runs the command and hands you the browser. |
| Typing your Mac password (Homebrew install) | Never type a password at an agent's request in any other context. |
| Choosing public or private | Public is a one-way door. What people copied stays copied. |
| Clicking publish, deploy, or send | The moment work leaves your laptop. Decide it deliberately. |
| Adding someone to your repo | You are granting access to your work. |
| Buying a domain, changing DNS | Money, and your name. |
| Approving anything that deletes | See the rule below. |
| Revoking a leaked key | Do this yourself, immediately, before anything else. |
| Taste | Which font, which colour, what it should say. Ask for options and a recommendation — then pick. |
The one rule underneath all of these
If you do not understand what is about to happen, say "explain it first, don't do it yet." That sentence costs thirty seconds and is the single most useful thing in this guide. An agent that cannot explain a step clearly should not be running it.
Throughout the guide, steps that need you are marked 🧑 You.
Five ideas do all the work.
That is genuinely it. A repo (repository) is an ordinary folder on your laptop,
plus a hidden .git sub-folder that remembers every version of every file you ever
saved.
Nothing else about the folder changes. Your files are still just files — open them, edit them, email them exactly as before. The memory sits quietly alongside.
When you finish a chunk of work you take a snapshot. That snapshot is a commit, and it is permanent — you can always come back to it.
The thing that surprises people coming from Google Drive or Dropbox: git never saves anything on its own. It only takes a snapshot when you ask. This is a feature. Drive syncing a half-finished file at the wrong moment is how you lose an afternoon; git cannot do that to you.
Git runs on your laptop and needs no internet and no account. GitHub is a website that stores a copy of your repo in the cloud. Two words move work between them:
That is the whole vocabulary. Everything else is detail.
This is why repos exist rather than emailing zip files. You edit chapter 3, someone else edits chapter 7, you both push, git merges both. It only asks for help when you both edited the same lines — rarer than you would think.
This is the payoff of the whole guide. You connect your GitHub repo to a hosting service once. From then on every push rebuilds the site and puts it live — typically within about two minutes. No upload step, no FTP, no dragging files anywhere. You save your work, and the world sees it.
macOS. You need four things: git, the GitHub CLI (gh), Node, and Claude
Code.
This has to come first on a fresh Mac. It provides git and the compilers everything
else needs.
xcode-select --install
⚠️ Trap
The very first time you run
git --version, that can trigger the same dialog. Expected. Let it install,
then carry on.
git --version
gh --version
node --version
npm --version
Anything that says "command not found" needs installing below.
Check first — which brew. If it prints a path, skip this entirely.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
⚠️ Trap
If Homebrew was already installed there is no prompt. Do not sit waiting for one.
brew install gh node@22 git
brew link --overwrite node@22
⚠️ Trap — Node version matters
Use Node 22. Hosting services build your site on a specific Node version, and "works on my laptop, fails when published" is almost always a version mismatch. Avoid Node 21.x and 20.0–20.2.
Install it from claude.com/code — the desktop
app is the easiest way in: open it, choose a folder as your project, and you are in a
session. The terminal version is the same tool — run claude from inside any
folder.
This is the step everyone asks about, and it is smaller than expected.
There is no special "connect Claude Code to GitHub" button. What actually happens: you sign your laptop in to GitHub once, using the GitHub CLI. Claude Code then uses that same sign-in, because it runs commands on your laptop as you. Sign in once, and Claude Code can read and push to your repos from then on.
Go to github.com and sign up. Note your username.
gh auth login
You get four questions. Answer them like this:
| Question | Answer |
|---|---|
| Where do you use GitHub? | GitHub.com |
| Preferred protocol for Git operations? | HTTPS |
| Authenticate Git with your GitHub credentials? | Yes |
| How would you like to authenticate? | Login with a web browser |
gh then prints a one-time code like ABCD-1234 and says "Press Enter
to open github.com in your browser…"
⚠️ Trap
The browser does not open until you press Enter. People sit staring at a terminal waiting for a browser that is waiting for them. Press Enter.
✓ Logged in as <your-username>.gh auth setup-git
gh auth status
gh auth status must show your account and a list of scopes that includes
repo — that is what lets you read and write private repositories. If
it is missing, run gh auth refresh -s repo and authorize again.
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
⚠️ Trap
This name and email are stamped into every snapshot you make, and if a repo is ever made public they are published with it — permanently, in its history. Choose an email you are happy to see in public before your first commit.
⚠️ Trap
Some projects require a specific
email on every commit. Set this before your first commit — fixing it afterwards is
annoying. If you get it wrong on a commit you have not pushed yet:
git commit --amend --reset-author.
gh api user -q .login
If that prints your username, your laptop is linked to GitHub — and so is Claude Code.
From here on you can just ask Claude Code in plain English — "push my changes", "what changed since yesterday?", "undo that last commit". You do not have to memorize git commands. But it helps to know what it is doing on your behalf, which is what the rest of this guide is for.
my-project/ ← an ordinary folder
├── .git/ ← the memory. Never touch this by hand.
├── .gitignore ← a list of things NOT to remember
├── README.md ← what this project is (GitHub shows this on the front page)
└── ...your actual files...
Some things should not go into the memory: they are enormous, they regenerate automatically, or they are secret.
# Regenerable — will be rebuilt automatically
node_modules/
.venv/
__pycache__/
dist/
.DS_Store
# Too big to be useful in a repo
data/huge-export.csv
⚠️ Trap — the one that actually matters
Never commit passwords, API keys, or tokens. Once something is in git history it
is very hard to remove, and if the repo is public, assume it is compromised the moment it
lands. Keep secrets in files that .gitignore excludes.
You can flip private → public later. Going the other way does not un-publish what people already copied, so start private if you are unsure.
This is the single most expensive mistake in this guide, so it gets its own heading.
Google Drive and git both want to manage the same files, and they fight. Drive corrupts git's internal files and strips the "executable" flag off scripts. The repo appears to work, then breaks in confusing ways days later.
Keep repos in a plain local folder — the common convention is
~/code. Git is already your sync layer; push and pull move
work between machines. You do not need Drive to do it too.
"Adopting" covers three different situations. They come up in this order in real life.
You have a folder of work. You want it remembered and backed up.
Do the local part first. Git works perfectly with no GitHub account at all, and this is the safest place to start — a local repo is a Time Machine for your folder that nothing can publish by accident.
cd ~/my-project
git init
Now write a .gitignore before the first snapshot. Ask Claude Code:
"look at this folder and write me a .gitignore" — it will spot the huge and regenerable
things.
git add -A
git commit -m "First snapshot"
That folder now has a memory. You can stop here for as long as you like.
Then, when you want an internet copy:
gh repo create my-project --private --source=. --push
One command: makes the GitHub repo, connects it, and pushes. Change --private to
--public when you want the world to see it.
A gentler on-ramp. In the wiki project this started as a file called
SAVE-SNAPSHOT.command that you double-click — it runs the commit for you and prints
your recent snapshots. No terminal, no GitHub, one double-click at the end of the day. If the
terminal is the intimidating part, ask Claude Code to make you one. GitHub can come later; it is
genuinely optional.
Someone has a project and wants you on it. Three things have to be true, in order.
First — they add you.
⚠️ Trap
If the repo is private and you have not
been added as a collaborator, git clone fails with "repository not
found." That message is a lie — the repo exists, you just cannot see it. It is not
a typo in the URL. The owner adds you at: repo → Settings → Collaborators → Add
people.
Second — you sign in. Part 2, above. Cloning a private repo without being signed in fails the same misleading way.
Third — you clone. "Clone" means download a full copy, memory and all.
mkdir -p ~/code && cd ~/code
git clone https://github.com/THEIR-USERNAME/THE-REPO.git
cd THE-REPO
git remote -v # where this repo came from
git branch --show-current # usually: main
Prove you can write, without touching anything real. Worth doing on day one — discovering you lack write access halfway through a piece of work is miserable. This pushes a throwaway branch and deletes it: no commit, no change to anyone's work.
git push origin HEAD:refs/heads/_authtest
git push origin --delete _authtest
If the first line is rejected, you do not have write access — go back to the owner.
Then read before you write. Well-run projects put their rules in the repo
itself. Look for README.md, START_HERE.md, AGENTS.md, or
CLAUDE.md and read them first. They exist precisely so a new person can start without
breaking things.
Claude Code reads two special files automatically when it starts in a folder:
CLAUDE.md — instructions for Claude Code specificallyAGENTS.md — instructions for any AI coding toolTo create one, open a Claude Code session in the repo and type /init. It reads the
codebase and writes a CLAUDE.md describing the project.
The pattern worth copying. In the wiki project, CLAUDE.md is four
lines that say "read AGENTS.md, that is the real source of truth" — because Claude Code
is not the only tool that touches the repo. One set of rules, every tool reads it, nothing drifts
out of sync:
# CLAUDE.md
This project's operating brief for all AI agents is **AGENTS.md** — read it first.
It is the single source of truth. Do not duplicate its content here.
@AGENTS.md
That @AGENTS.md line pulls the other file in automatically.
What belongs in AGENTS.md: where things go, what must never be done (deleting data,
committing secrets, publishing without asking), and which commands to run to check work. Keep it
short — it is read at the start of every single session.
Three routes, smallest first. Start simple even if you want the big one later, because the simple ones teach the thing that matters: push equals publish.
templates/ has three finished pages you can open
right now — an academic homepage, a project / paper page, and a
long-form reading page — plus one theme.css where all the colours,
fonts and spacing live. Change a value there and every page changes together.
No build step, no frameworks. Double-click templates/index.html and it works.
Its README.md covers font pairings for academic work, the
one-accent-colour rule, why line length matters more than typeface — and copy-paste prompts for
restyling the whole thing through Claude Code without touching CSS by hand.
No build step, no other services, no cost. A .html file in a public repo becomes a
website. This page is the demonstration — it is a single index.html in
the repo you are reading.
index.html in the repo root. (Ask Claude Code: "make me a simple
one-page site about X".)https://YOUR-USERNAME.github.io/YOUR-REPO/.From then on: edit, commit, push, and the live page updates itself.
⚠️ Trap
Free GitHub Pages requires a public repo. Do not put anything private in a repo you are about to publish this way.
This is the route the walkthrough takes (Stage 5), and the middle ground between the other two: your repo stays private, and there is still no build step.
.).random-name-123.netlify.app.From then on, git push is the deploy. Netlify watches the repo:
every push republishes the site, live in about two minutes. There is no separate "upload to
Netlify" step to remember — the everyday loop in Part 7 is the whole publishing
workflow.
After a push: wait about two minutes, load the live URL, and check the change is really there. If it is not, hard-refresh first (you may be seeing a cached page), then check the deploy log on Netlify.
ai-entrepreneurship.wiki has hundreds of pages generated from research data, plus full-text search. Same principle, more machinery:
| Piece | What it does |
|---|---|
| Astro | Turns source files + data into plain HTML pages |
| GitHub | Holds the repo; every push notifies the host |
| Netlify | Watches the repo, runs the build, serves the site (generous free tier) |
| A domain registrar | Where you buy yourname.com |
Setting it up, once:
npm run build — it must finish without errors.npm run build, publish directory dist.random-name-123.netlify.app.CNAME for www and an A/ALIAS record (or
Netlify's nameservers) for the bare domain. DNS changes can take a few hours.A netlify.toml in the repo pins the settings so they live in git rather than in a
web dashboard someone can change by accident:
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "22"
Even simpler, if you just want it online today: Netlify Drop — build locally, drag the output folder onto the page, get a live URL. No git at all. Fine for a one-off; you lose auto-deploy.
Everything above is what to do. This part is how to ask for it — which matters more than any individual command. The danger with a vague ask is not that Claude Code fails; it is that you get a confident, plausible, wrong result, and a beginner cannot tell the difference. The copy-paste versions of everything here live in the prompt sheet; this part is the reasoning behind them.
A session is one conversation with Claude Code, from opening it to closing it.
One session = one objective with one checkable finish.
If you cannot write the finish line in a single sentence, you are looking at more than one session. Split it.
| Sized right | Too big — split it |
|---|---|
| "Set up git in this folder and make the first snapshot" | "Set up my whole workflow" |
"Write a .gitignore and explain each line" | "Clean up this project" |
| "Get this repo deploying to Netlify" | "Build me a website and put it online" |
| "Fix this error: (paste it all)" | "Make the site better" |
The right-hand column has no finish line, so the session never ends — it just drifts until you
lose track of what changed. "Build me a website and put it online" is really three sessions: build
it locally until npm run build passes → make it a repo and push → connect the host and
get a live URL. Each has an obvious moment where you can say that worked.
A weak ask is weak in predictable ways. Before you hit enter:
| # | The question | Weak | Strong |
|---|---|---|---|
| 1 | What one thing should this produce? | "clean up my repo" | "write a .gitignore for this folder" |
| 2 | What shape is the output? | "document this" | "a README.md at the repo root, under 200 lines" |
| 3 | What should it read or use? | — | "read START_HERE.md first; use the existing scripts/bootstrap" |
| 4 | What must it NOT touch? | — | "only edit files in src/. Do not touch data/" |
| 5 | How much effort is this worth? | — | "quick pass, don't over-engineer" / "take your time on this one" |
| 6 | How will we know it worked? | "make it good" | "npm run build exits 0 and the page shows the new heading" |
You will not write all six every time. But 1 and 6 are not optional, and 6 is the one beginners skip.
Why 6 matters most
"Done" has to be something
you can check, not something the agent claims. An agent that says "I've fixed it"
has told you nothing. An agent that says "npm run build now exits 0, here's the output"
has told you something. Ask for the evidence, every time, until it is a habit on both sides.
Why 4 matters more than it looks: naming what is off-limits is how you stay in control of a tool that is faster than you are. "Don't touch anything already committed" is a sentence that has saved a lot of afternoons.
The rule that took longest to learn on the project this guide comes from, and the one worth adopting on day one:
If this session died right now, could a completely fresh session pick up the work from the files on disk alone?
If the answer is no, something important exists only in the conversation — and conversations end. They crash, they time out, you close the laptop, you hit a limit. Anything that lived only in the chat is simply gone.
So ask for things to be written down as they happen, not summarised at the end.
Plans, decisions, what you tried that did not work, why you chose one option over another. A file in
the folder, written when the decision is made. This is also why the AGENTS.md pattern in
Part 4c is worth the ten minutes — it is the project's memory, and it survives
every session.
If the same step fails three times, stop. Do not ask for a fourth attempt.
Repeated failure almost never means the agent needs another go. It means something in the situation is not what either of you thinks it is — a missing tool, a wrong assumption, a permission you do not have. A fourth attempt just produces a more elaborate wrong answer, and each one is harder to undo than the last. Change the question instead:
Stop. Don't try again. Tell me why this is failing —
what did you expect to happen, and what actually happened?
⚠️ Trap
When something is broken and you do not
understand why, the danger is not the original problem — it is the confident fix that throws away
your only copy of your work. Anything involving reset --hard, force-pushing, or
deleting: make it explain first and act second.
When you stop mid-task, spend the last two minutes writing down where you are. Otherwise tomorrow starts with twenty minutes of archaeology.
We're stopping here. Write a handoff file in this folder covering:
- what's done and verified
- what's half-finished
- the exact next action
- anything you learned this session that isn't written down anywhere yet
Write it so a fresh session with no memory of this conversation could pick it
up from the file alone.
That last category — things learned that are not written down anywhere — is the one people forget and the one that hurts most. The dead end you already explored, the flag that does not work on this machine, the command that needs a different name here. Nobody remembers it in a week, and the next session will happily walk into the same wall.
Claude Code lets you pick a model. The instinct is to use the fastest one for small jobs and the strongest for big ones. Size is the wrong axis. Use this instead:
| Use the strong model when | Use a faster model when |
|---|---|
| The task is ambiguous, or you are not sure what you want yet | The task is fully specified and mechanical |
| Something is broken and you do not know why | You know exactly what to change and where |
| The decision is hard to reverse — publishing, deleting, restructuring | It is small, obvious, and easy to undo |
| You are asking what should I do here | You are asking do this specific thing |
The mistake worth avoiding is backwards-routing: never hand vague work to a fast model. Working out what to do is the expensive part, not the typing. If a job is underspecified, tightening the spec is itself the strong model's work — and once the spec is tight, the cheap model does the rest fine.
Once set up, this is the entire routine. Four commands, in this order, forever:
git pull # 1. get everyone else's latest work FIRST
# ...do your work...
git add -A # 2. stage everything you changed
git commit -m "what you changed" # 3. take the snapshot
git push # 4. send it up (and, if it is a site, publish it)
⚠️ Trap
git pull
first, always. Pulling at the end, after you have already committed, is where merge
headaches come from.
If the project is a website, that git push just published it. Wait about two
minutes, then load the real URL to confirm.
Or skip all of it and tell Claude Code: "pull, then commit my changes with a sensible message, then push."
Every one of these is common. None is a disaster.
| What you see | What it means | What to do |
|---|---|---|
repository not found | Almost always not signed in, or not added as a collaborator on a private repo. Rarely a typo. | gh auth status — check for the repo scope. Then ask the owner to add you. |
Updates were rejected… non-fast-forward | Someone pushed while you were working. | git pull --rebase, then git push. Never force-push a shared branch. |
Please tell me who you are | Identity not set. | Part 2, Step 4. |
| Build fails after push, worked locally | Usually a Node version mismatch. | node --version → should be 22. Match what the host builds with. |
| Committed something secret | Serious. History is hard to rewrite. | Stop. Revoke the key immediately — assume it is compromised. Then ask for help cleaning history. |
| Undo the last commit (already pushed) | — | git revert HEAD && git push — makes a new commit that undoes it. Safe on shared branches. |
| Undo the last commit (not pushed) | — | git reset --soft HEAD~1 — keeps your file changes, drops the snapshot. |
| Site did not update after push | Build may have failed. | Check the deploy log on your host. Also hard-refresh — you may be seeing a cached page. |
| Genuinely lost | — | Tell Claude Code exactly what you did and paste the full error. Do not guess at commands you do not understand — that is how a small problem becomes a big one. |
SETUP (once per laptop)
xcode-select --install
brew install gh node@22 git
gh auth login → GitHub.com · HTTPS · Yes · web browser
(PRESS ENTER to open the browser)
gh auth setup-git
gh auth status → must list the `repo` scope
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
ADOPT A FOLDER YOU HAVE
cd ~/my-project
git init
# write .gitignore FIRST
git add -A && git commit -m "First snapshot"
gh repo create my-project --private --source=. --push
JOIN A PROJECT
# owner adds you as collaborator first
mkdir -p ~/code && cd ~/code
git clone https://github.com/OWNER/REPO.git
# prove write access without touching anything:
git push origin HEAD:refs/heads/_authtest
git push origin --delete _authtest
# then READ: README.md / START_HERE.md / AGENTS.md
EVERY DAY
git pull → work → git add -A → git commit -m "..." → git push
RULES
Repos live in ~/code — NEVER in Google Drive or iCloud
Never commit secrets, keys, or tokens
Commit name + email go public with the repo — use ones you'd publish
git pull BEFORE you start, not after
Never force-push a shared branch
ASKING CLAUDE CODE (full sheet: PROMPTS.md)
One session = one objective with one CHECKABLE finish
Always say: what to produce · what not to touch · how we'll know it worked
"Done" means evidence you can see, never a claim
Same step fails 3× → STOP. Ask "why is this failing?", not "try again"
Broken and you don't know why → "explain first, don't act"
Write it to a FILE as you go — chat is not storage
Stopping mid-task → ask for a handoff file before you close
Vague work → strong model. Tight spec → fast model. Never backwards.
Worth knowing, because the tidy version would be misleading. The website behind this guide was a repo from its first day — 10 June 2026, first commit — and has been pushed to and deployed from ever since. That part went the way Part 5 describes. The research folder behind it was not: it lived in Google Drive for months, Drive corrupted git's internal files, and the folder eventually had to be recovered and migrated out. The first commit of that repo, on 18 July 2026, is literally titled "recovered and migrated off Google Drive."
Two lessons from that shaped this guide: