Claude Code Introduction - Full Crash Course (1 HOUR)
Timestamps
- - Intro
- - Install Claude Code
- - Getting Started
- - Create Your CLAUDE.md
- - Make Your First Commit
- - Create a Vault
- - Obsidian
- - Models & Credits
- - Usage
- - Skills
- - Permissions
- - Deny Rules
- - Commit Hooks
- - Let's Build
- - Basic v1 Spec
- - Creating the Spec
- - Auto Mode
- - Headless Browsers
- - Hooks
- - MCP
Claude Code is an agent that runs in your terminal. It reads your files, edits them, and runs commands, which is a different thing than autocomplete in your editor.
I've been running my whole platform with it for the last six months, and it's saved me hundreds, probably thousands of hours. This crash course is the follow-along version: we start from nothing, install it, and try a small example of every piece, so you can put it to work whether or not you write code for a living.
These are the free notes for the video, with the commands and code so you can follow along without pausing every ten seconds. When you want the full system, how I actually run software and a business on this every day, that's my Agentic AI course.
Installing
There's a download button on the Claude Code page that gives you a desktop app, and it's fine, but I run everything from the terminal. That's where Claude Code is at its best.
Before you install, make a folder and work from there instead of your home directory. Permissions get scoped to wherever you launch Claude, and you don't want your whole home folder as its playground.
mkdir claude-code
cd claude-code
Grab the install command off the setup docs. I'm on macOS, and the command I copied was the native installer:
curl -fsSL https://claude.ai/install.sh | bash
There's an npm install too if you already live in Node, and on Windows you run the installer from PowerShell or the command prompt:
npm install -g @anthropic-ai/claude-code
Check it landed:
claude --version
First Run
Start it by typing claude:
claude
First time in, you authenticate. If you're ever signed out later, /login reconnects you to your Anthropic account, where you pick your monthly subscription or API credits (there are a couple of third-party options too, but it's usually just the subscription).
Now type / and a menu of everything pops up, arrow keys and enter to run one. Poke around in there, that's how you find things like hooks later.
Two survival basics. To quit, run /exit, or hit Ctrl+C twice. And whenever you close Claude it forgets every permission you approved for that session, so instead of closing and relaunching to start over, use /clear. It wipes the conversation and leaves you where you are. Do it any time you switch topics.
CLAUDE.md
CLAUDE.md is a markdown file Claude reads at the start of every session: what the project is, conventions, rules you're tired of repeating. Don't write it by hand. Run:
/init
Even on our empty folder it generates one, a basic template telling future Claude to fill it in as the project grows. On a real codebase it scans the code and writes something with actual structure in it. It'll ask permission first, say yes (and yes-don't-ask-again this session, which is the same as shift+tab).
Open it and read it:
less CLAUDE.md
One thing to get straight early: the CLAUDE.md is guidance, not a guarantee. Claude follows it most of the time, not all of the time, and the bigger the file and the project get, the more it slips. So anytime you can actually prevent a mistake instead of asking nicely, do that. Don't write "don't drop the database" in here and call it safe, set a rule that makes it impossible. We'll get to those.
Directing Claude
Let's get the basic project files in. I'll ask for a repo, a readme, a gitignore, and a first commit:
initialize a repo with a readme and a gitignore and make the first commit.
keep the readme empty until we start a real project.
It stages everything and commits. Read the message it wrote: mine came out as "initial commit" with a "Generated with Claude Code, co-authored by Claude" footer.
Say I don't want that footer. The move is not to go edit anything myself, it's to tell Claude to change how it works:
add a rule to CLAUDE.md: commit messages should be lean, no attribution or co-authored-by lines.
Commit again and the next message comes out clean. That loop, notice something you don't like and write the rule down, is what the file is for. Anytime you want to change Claude's behavior, tell Claude, don't reach in yourself unless you really want to.
A vault
The CLAUDE.md should stay thin. It's a pointer, not a dumping ground. So for everything beyond it I have Claude make a vault, which is just a folder of markdown files.
create a vault folder for project info beyond CLAUDE.md.
keep it simple for now: one architecture.md, a folder for specs and features, and a file for quality checks.
CLAUDE.md should just point here.
For a bigger project you'd build this out per area of the app, but that's the shape. To actually read and edit these I use Obsidian, which is kind of like Notion mixed with a markdown editor, a little easier to see everything than raw files in your editor. Install it, open a folder as a vault, point it at your project's vault folder, and you can flip any file between edit and read mode.
Status and diagnostics
Before going further, /status shows your diagnostics: version, and any problems with the install. /doctor runs a similar check.
Mine flagged multiple installations, an older version shadowing the one I just installed. Instead of untangling that myself, I had Claude do it:
help me diagnose this and switch to the latest version I installed via curl. delete the old one.
It worked out that the old copy came in through npm, uninstalled it, and handed me one command it couldn't run itself. claude --version after confirmed the latest. Most of you won't hit this on a first install, the point is that Claude can debug its own environment, not just write your code.
Models
Run /model:
/model
The exact model names change fast (Fable 5 is the hot one as I record this, and it'll probably be old news in a couple of days), so don't anchor on versions, anchor on the use case. The menu describes them that way: most capable for your hardest and longest-running tasks, best for everyday complex work, efficient for routine stuff, fastest for quick answers. A tiny change like "make the background darker"? The fast one is fine. Speccing out real software? Reach for the capable one.
The tradeoff is money, the smarter the model the faster it burns your usage, and on a cheap plan the top model empties your credits quick. If you're not sure, leave it on default and it picks per task.
There's also an effort level down at the bottom you can nudge left and right, medium is a fine default. And /usage shows how much you've spent this week and this session, worth glancing at so you're not caught off guard.
Skills
A skill is a reusable prompt you invoke with a slash command. You write a workflow down once and type /whatever-you-named-it instead of retyping it. People sell these like they're magic, but they're just words pulled in to context, and Claude can write them for you.
Let's make one that commits. Notice I have to say "create a skill", or Claude just does the task instead of saving it:
create a skill called /commit. before committing, stage all changes and check for large files
or anything that shouldn't be tracked. if you find something, update the .gitignore and tell me.
That last bit is a self-improvement trigger, so the skill tightens up the project a little every time it runs. Claude writes a SKILL.md that looks about like this:
---
name: commit
description: Stage all changes and commit, checking for anything that shouldn't be tracked
---
1. Check for large files or anything that shouldn't be committed.
2. If you find something, add it to .gitignore and notify me.
3. Stage all changes and commit.
When it saves, it asks where to put it. The default is ~/.claude/skills/, your user level, available in every project. I'd rather keep this one attached to the repo, so I tab over and put it in .claude/skills/ instead, checked in and shared with anyone who clones it. Use the user level for skills you want everywhere.
A new skill might not show up until you restart Claude the first time. Then /commit runs it. Look at where it lives:
ls -la .claude
There's a skills/commit/SKILL.md. You can drop scripts in that same folder and the skill can call them, which is how these get more reliable as you invest in them. Mine drift over time. On one project I made the commit skill do so many checks it got bloated and I stopped reaching for it, so I made a lean commit-fast that just stages and commits and nothing else. Adjust yours to whatever you actually use.
Permissions and settings.json
Those allow/allow/allow prompts get old fast. Let's make some permanent. I just ask:
summarize the permissions this skill needs and add them to my allow rules so it stops asking.
Claude can edit your config for you. When it did mine, it also called out two rules already on my allow list that were risky, git checkout and git reset, and offered to remove them. I took it. git reset wiping out work I've been on for an hour is exactly what I don't want it reaching for on its own.
The rules live in a settings file. Three of them, broadest to narrowest:
~/.claude/settings.json: global, every project.claude/settings.json: this project, checked in and shared.claude/settings.local.json: your personal overrides, gitignored
The interesting part is the permissions block:
{
"permissions": {
"allow": [
"Bash(git add:*)",
"Bash(git commit:*)"
],
"deny": [
"Bash(git reset:*)",
"Bash(git checkout:*)",
"Bash(rm -rf:*)"
]
}
}
Allow the commands you'd approve every time anyway. Deny the ones that destroy work: resets, a checkout that clobbers a file you've been editing, rm -rf. There's never a moment the model needs to run rm -rf on its own.
Two things worth knowing about deny. It's not a hard wall, Claude can find another route to a goal, so a deny nudges it toward the less destructive path rather than making the outcome impossible. And you can't tell it to ignore a deny rule for one moment, deny means deny, so if you want "block by default but let me override" put that command in the ask list instead.
The caveat that matters: the deny list prevents accidents, not attacks. If the model really wanted to wreck your stuff it could work around these, so don't lean on it as a security boundary. Where it earns its keep is the "oops, shouldn't have done that" kind of mistake, and deny something once and Claude stops trying it every session.
One aside on git commit hooks, the kind that block a commit until it passes checks. I tried those and found them so annoying (my commit wouldn't meet the rule, so I just wouldn't commit, and ended up with giant commits) that I gave up. I'd rather not block a commit at all. If you want protection, put it on what gets deployed, or require it only for merges into main.
You'll also hear about the flag that skips all permission prompts. It's real and I use it, but only inside an isolated Docker container that can't reach anything sensitive. On your laptop with your real credentials, keep the prompts on and build an allow list instead. That's step one.
Building something real
Everything up to here was setup, so let's actually use it on something. First /clear, always, when you change topics, so the old conversation doesn't pollute the new one.
/clear
I'm not going to spec out a giant project on camera. We'll do a small V1: a media-processing app that takes a local video, transcribes it, and generates diagrams from what's being explained (actual mermaid diagrams, not screen grabs), plus a little HTML page to browse the results. Wrapped as scripts and a skill, run locally, nothing uploaded.
The trick with a spec is to not let it write the whole thing at once:
create a spec for this. don't write the full thing yet, go back and forth with questions first.
do external research on the tools we'd need before recommending anything.
Making it research first anchors the answer to what people are actually using now, instead of whatever it half-remembers. Then it asks its questions and I answer: local video files, transcription with something offline like whisper or whisper.cpp, no API keys, mermaid for the diagrams (renders natively in Obsidian, GitHub, and Claude).
While it works you'll see little tasks pile up at the bottom marked general purpose. Those are subagents, Claude spawning another Claude to go do a focused job. The reason to care is context: a subagent reads the fifty files or does the research in its own separate chat and hands back just the conclusion, so your main conversation stays clean. Claude reaches for these general-purpose ones on its own when a task calls for it, and you can also just tell it to delegate something to a subagent.
Two things showed up while it ran. shift+tab cycles the mode under the prompt, and auto mode is one of those modes: it uses a classifier to auto-approve the safe prompts, a gentler middle ground than the skip-everything flag. And /resume picks a past session back up where you left off, which is how I ran this one overnight and came back to it the next day.
This is where isolating Claude pays off. When it has to stop and ask me something every minute, I can't shift my focus to anything else. When it's boxed in an environment where it can't break anything, I can fire off a task, let it run for two or three hours, and review the whole thing at the end.
Verifying its own work
Next day, I opened the repo in VS Code to see what it built. It named the thing VidGraph: drop in a video, get a transcript plus AI-drawn mermaid diagrams, transcription running about 6x faster than real time, fully offline.
One detail I liked: on a test video the audio said "root handler" but a frame showed "route handler", and because the tool peeks at video frames and not just the audio, it caught the right spelling. That's the whole reason to look at the frames and not just the transcript, and it happened on the very first test.
The gap was verification. It drew a diagram but couldn't confirm the HTML page actually rendered it, "that's the only thing I couldn't check myself." So I wired it a browser:
you can use Chromium through Playwright to open the page and verify it visually. do that.
It ran the browser from a scratch directory so nothing landed in the project, confirmed the render, and offered to save that as a reusable verify-hub.sh the pipeline runs every time. That's the pattern I keep coming back to: push effort off myself and onto the agent. I'd rather it run long and hand me something that actually works than stop early and tell me it hopes the thing works but didn't get to check.
Hooks
So far everything has been instructions, and instructions get skipped now and then. A hook is code that ties into Claude's loop at fixed points, so unlike a CLAUDE.md rule it just runs every time, kind of like middleware in a web request.
There's a list of events, but the useful ones are PreToolUse and PostToolUse (before and after Claude runs a tool) and Stop (when Claude is about to finish a response, which can send it back to do more before it's allowed to end the turn).
For VidGraph I had it add a PostToolUse hook that validates every mermaid file the moment it's written, so a broken diagram never slips through. Hooks live in the same settings.json. To prove the wiring first, it started the hook off just echoing "fired" into a file every time it ran, then swapped that for the real validation:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/validate-mermaid.sh"
}
]
}
]
}
}
The matcher picks which tool fires it, here only Write or Edit. The command is a script, not a prompt, whatever you can run from a terminal, and what it writes back gets fed to Claude.
A newly added hook only goes live once the settings get reloaded. It worked for me because settings.json already existed when the session started. If you add one and it seems dead, run /hooks (which also lists everything wired up) or restart to reload. The hooks docs have the full event list.
Navigating hooks in the menu is a little clunky, so I usually just ask Claude what hooks are active or read the file directly.
MCP
Last piece, and I'm only going to touch it briefly since it really deserves its own lesson. MCP is basically APIs built for AI. A plain API is a bunch of endpoints, an MCP server wraps those with the extra context an LLM needs, so each tool comes with built-in documentation telling the model what it does and when to use it. Databases, browsers, other apps, if it has an MCP server, Claude can drive it.
Inside a session, /mcp shows what you've got connected:
/mcp
I connected my own platform, Course Catalyst, which exposes 72 tools, roughly one per API endpoint. So from the same terminal I build in, I can tell Claude to publish to my live site:
take the joins video, create a page at /joins with the video embedded and a code sample below it,
using the course catalyst MCP.
It pulled the block types it needed off my site (a video block, an image block, custom HTML, and rich text), uploaded the video, and published the page. That upload path is built into the MCP and described there, so any client knows how to do it without me explaining it. One snag it hit: an SVG image wouldn't render, so it rasterized to PNG, and that's the kind of fix I'd fold back in to the skill so it never has to think about it again. Turning a repeated step into a script is always the goal, it saves a pile of tokens versus re-figuring it out every time.
When you want to connect your own, claude mcp add wires one up in a line, and the MCP docs walk through servers you can try in a minute or two.
Where to go next
That was a tour of the different pieces of Claude Code and the workflows I lean on. We barely scratched the surface with the app, the real work from here is iterating on it, adding tests, keeping the quality up. But if you can do what we did in this video, you've got a working knowledge of Claude Code and you're ready for the more intermediate and advanced stuff. I go a lot deeper on the whole system, the operational side of running software and a business on this, in the Agentic AI course. See you in the next one.