Starten met Claude Code in november 2026: de complete gids voor Python, IDE en database
Twintig klanten boeken tegelijk dezelfde stoel, en alle twintig komen erin. Zo begin je met Claude Code en Python: installatie, abonnement, IDE-keuze, SQLite of PostgreSQL, CLAUDE.md en rechten, met gemeten resultaten en een echte sessie.

Twintig mensen proberen op hetzelfde moment stoel 1 te boeken bij een kapsalon, zaterdag 10:00. Hoeveel afspraken komen er in de database? Ik heb het getest met de code die je krijgt als je "kijk eerst of het vrij is, sla het dan op" letterlijk opschrijft. Het antwoord was twintig. In vijf van de vijf pogingen.
Code die "eerst kijkt, dan opslaat" ziet er voor een taalmodel net zo verstandig uit als voor jou, en elke test met één gebruiker slaagt. Claude Code schrijft je zo'n functie in een halve minuut, met keurige tests erbij. Of die tests het juiste controleren, bepaal jij. Daarover gaat deze gids. Claude Code schrijft in november 2026 aantoonbaar goede Python. Of het resultaat deugt, hangt af van drie dingen die jij regelt voordat de eerste regel code bestaat: welke controles Claude moet halen, wat het mag doen op je computer, en welke database je kiest.
Alles in dit artikel is nagelopen of gemeten op 3 november 2026: Claude Code 2.1.317 met Opus 5.5, Python 3.14.10, uv 0.13.7, SQLite en PostgreSQL 18.6. Het voorbeeldproject is een kleine API voor afspraken bij een kapsalon. Claude Code heeft er in een echte sessie een functie aan toegevoegd. Wat daarbij goed en fout ging, staat er ook in.
Kort antwoord. Installeer Claude Code met de native installer en neem minimaal een Pro-abonnement ($20 per maand). Start een Python-project met
uv init, en zet inCLAUDE.mdprecies welke commando's "klaar" betekenen: tests, ruff en een typechecker. Kies SQLite tot je meerdere servers hebt of veel gelijktijdige schrijvers, en kies dan PostgreSQL. In beide gevallen laat je de database dubbele boekingen tegenhouden, niet je Python-code. Elke IDE werkt, want Claude Code draait in de terminal. De VS Code-extensie is het verst ontwikkeld, de JetBrains-plugin is nog beta.
Wat Claude Code is, en wat het verschil maakt met een chatvenster
Claude Code is een programma in je terminal dat Claude laat werken in je projectmap. Het leest je bestanden, past ze aan, draait commando's zoals pytest, leest de uitvoer en probeert opnieuw. Een chatbot geeft je code om te plakken. Claude Code plakt hem zelf, draait de tests en ziet wat er faalt.
Dat klinkt als een detail, maar het bepaalt hoe je ermee werkt. De kwaliteit hangt minder af van hoe slim je je vraag formuleert, en meer van wat Claude kan controleren. Anthropic zegt het in de eigen best practices ook: geef Claude een controle die slaagt of faalt, en vraag om bewijs, dus het commando en de uitvoer. Een project zonder tests is voor Claude Code als een keuken zonder proeflepel.
Welk abonnement heb je nodig voor Claude Code?
Met het gratis plan kun je Claude Code niet gebruiken. De goedkoopste instap is Pro. De prijzen op claude.com/pricing staan in dollars en zonder btw:
| Plan | Prijs per maand | Gebruik | Voor wie |
|---|---|---|---|
| Pro | $20 ($17 bij jaarbetaling) | limiet per 5 uur en per week | leren, een avond per week bouwen |
| Max | $100 | 5 keer Pro | dagelijks werk |
| Ultra | $200 | 10 keer Pro per week, geen limiet per 5 uur | lange sessies, meerdere agents tegelijk |
| Team / Enterprise | per seat | verschilt | organisaties met centraal beheer |
| API (Console) | per token | geen vaste limiet | automatisering, CI |
Lees je een oudere gids? Het plan dat daar "Max 20x" heet, is nu Ultra.
Om een idee te geven van de kosten: de functie die Claude Code verderop in dit artikel bouwde, kostte in twee runs samen $0,60 tegen API-tarief. Daarin zaten 15 beurten en ongeveer een minuut rekentijd. Op een abonnement betaal je dat niet los. Het telt mee voor je limiet.
Welk model gebruikt Claude Code?
Op alle betaalde plannen is Opus 5.5 het standaardmodel. Met /model wissel je naar sonnet, haiku, fable of opusplan. Die laatste plant met Opus en voert uit met Sonnet. Met /effort bepaal je hoe lang het model nadenkt: low, medium, high, xhigh of max. In Claude Code staat dat standaard op medium.
| Model | API-prijs per miljoen tokens (in / uit) | Wanneer |
|---|---|---|
| Fable 5.1 | $10 / $50 | het zwaarste denkwerk; nergens de standaard |
| Opus 5.5 | $4 / $20 | de standaard, voor vrijwel alles |
| Sonnet 5.5 | $2 / $10 | veel kleine taken, krappe limiet |
| Haiku 5.5 | vanaf $0,10 / $0,50 | subagents die zoeken en samenvatten |
Alle vier hebben een contextvenster van een miljoen tokens. Daar past een middelgrote codebase in zijn geheel in. Toch is "alles in de context" geen werkwijze, zoals verderop blijkt. Mijn advies voor beginners: laat het model op de standaard staan. Een sessie wordt zelden beter van een ander model. Ze wordt wel beter van een betere controle.
Claude Code installeren op Windows, macOS en Linux
De aanbevolen route is de native installer. Die werkt zichzelf daarna automatisch bij.
# macOS, Linux en WSL
curl -fsSL https://claude.ai/install.sh | bash
# Windows (PowerShell)
irm https://claude.ai/install.ps1 | iex
# daarna, in je projectmap
claude Liever een pakketbeheerder? Dat kan met Homebrew (claude-code), WinGet (Anthropic.ClaudeCode) of npm (@anthropic-ai/claude-code, met Node 22 of hoger). Ze installeren allemaal dezelfde binary. Na de installatie controleert claude doctor of alles klopt.
Gebruik je Windows? Installeer dan ook Git for Windows. Het is niet verplicht, maar met Git Bash draait Claude Code zijn shellcommando's in bash. Zonder Git Bash valt het terug op PowerShell. Dat werkt, maar de meeste voorbeelden in documentatie en op forums zijn bash. Wil je de sandbox gebruiken, die Claude Code afschermt van de rest van je systeem? Dan heb je WSL 2 nodig: de sandbox bestaat niet op native Windows.
Python in november 2026: uv, 3.14 en de gereedschapskist
Voor een nieuw Python-project is er in 2026 weinig reden om nog met pip, venv en een losse requirements.txt te beginnen. uv van Astral installeert Python zelf, maakt de virtuele omgeving, beheert dependencies en draait commando's. Dat in één programma.
Voor Claude Code is dat een groter voordeel dan het lijkt. Met uv is er precies één manier om iets te draaien: uv run pytest, uv run ruff. Claude hoeft niet te raden of de venv actief is. Dat scheelt de bekende foutmelding ModuleNotFoundError, die anders drie beurten kost voordat het model doorheeft dat het de verkeerde Python gebruikt.
uv init --package --python 3.14 kapsalon
cd kapsalon
uv add fastapi "uvicorn[standard]"
uv add --dev pytest httpx ruff ty Welke Python-versie? Python 3.15.0 verscheen op 9 oktober 2026, met onder meer lazy imports en standaard UTF-8. Voor dit project heb ik 3.14 gekozen. Die versie is een jaar oud, free-threading wordt er officieel in ondersteund, en hij krijgt updates tot oktober 2030. Neem 3.15 als al je dependencies er wheels voor hebben. Het verschil merk je in een webapplicatie als deze nauwelijks.
De rest van de gereedschapskist, met de versies die ik gebruikte:
| Taak | Gereedschap | Versie | Opmerking |
|---|---|---|---|
| tests | pytest | 9.2.0 | de controle waar alles om draait |
| lint en opmaak | ruff | 0.17.3 | vervangt flake8, isort en black |
| types | ty | 0.0.96 | snel, maar nog beta; pyrefly 1.4 is stabiel |
| web-API | FastAPI | 0.162.0 | met Pydantic 2.14.2 voor validatie |
Waarom een typechecker als je al tests hebt? Omdat Claude Code soms een functie aanroept met een argument dat niet bestaat, op een plek die geen test raakt. De typechecker vindt dat in een seconde. De gebruiker die toevallig dat pad neemt, vindt het pas in productie.
Welke IDE is het beste voor Claude Code?
De eerlijke conclusie: de IDE doet er minder toe dan je denkt. Claude Code draait in de terminal en werkt dus naast elke editor. De integraties voegen vooral twee dingen toe: je ziet wijzigingen als diff in je eigen editor, en wat je selecteert, gaat automatisch mee als context.
| IDE | Integratie | Sterk in | Let op |
|---|---|---|---|
| VS Code | extensie "Claude Code" (anthropic.claude-code) | plan bekijken en aanpassen voor je akkoord geeft, inline diffs met accepteren of weigeren per wijziging, @-mentions met regelbereik, checkpoints | vereist VS Code 1.94 of nieuwer |
| PyCharm (en andere JetBrains-IDE's) | plugin "Claude Code [Beta]" | diffs in de diffviewer van de IDE, je selectie gaat mee, Claude leest de inspecties van de IDE | beta; de CLI installeer je apart, verbinden met /ide |
| Cursor en andere VS Code-forks | dezelfde extensie, via Open VSX | als je Cursor al gebruikt | twee AI-assistenten in één venster werken elkaar soms tegen |
| Zed | "Claude Agent" via ACP | snelle editor, agent in een paneel | apart inloggen met /login |
| Geen IDE | terminal, desktop-app, claude.ai/code | werkt overal, ook op een server | geen inline diff |
Mijn keuze voor iemand die begint met Python en Claude Code is VS Code met de extensie. Dat is geen oordeel over de editor, maar over de integratie. Die is het verst uitgewerkt, en vooral de planweergave helpt: je leest wat Claude van plan is en past het aan voordat er een bestand verandert. Werk je al in PyCharm, stap dan niet over. Sinds versie 2025.1 is PyCharm één product met een gratis kern, en de debugger en databaseweergave zijn sterker dan wat VS Code standaard biedt. De JetBrains-plugin doet het belangrijkste goed. Hoe dat in de praktijk werkt, staat in mijn eerdere artikel over Claude Code in PhpStorm. Voor PyCharm werkt het hetzelfde.
Welke database kies je voor een Python-project met Claude Code?
Hier gaat het in de meeste beginnersgidsen mis. Ze vergelijken databases op snelheid en populariteit. Voor een applicatie die Claude Code voor je schrijft, telt vooral één vraag: wie bewaakt de regels van je data? Een taalmodel schrijft logica die in een test met één gebruiker klopt. Dat iets onder gelijktijdig gebruik misgaat, ziet het niet vanzelf, en jij ook niet tot het gebeurt.
Terug naar de kapsalon. De regel is eenvoudig: op één stoel mogen geen twee afspraken overlappen. Ik liet twintig threads tegelijk stoel 1 boeken voor zaterdag 10:00 tot 10:30, op vier manieren, en herhaalde elke variant meerdere keren.

Wat er gebeurt, per variant:
- Eerst SELECT, dan INSERT, zonder transactie. Alle twintig threads zien een lege agenda, en alle twintig slaan hun afspraak op. Negentien dubbele boekingen, en dat in 5 van de 5 rondes. Een test met één gebruiker slaagt gewoon.
- Dezelfde code in een gewone
BEGIN. De data klopt nu: er staat één afspraak. Maar de negentien anderen krijgen binnen 0,03 seconde de foutdatabase is locked, ondanks een busy_timeout van vijf seconden. De oorzaak: een transactie die begon met lezen en daarna wil schrijven, kan in WAL-modus niet wachten. Zijn momentopname is verouderd. Voor de klant betekent dat een 500-fout in plaats van "deze tijd is al bezet". BEGIN IMMEDIATE. De schrijfvergrendeling gaat dicht vóór de controle. De threads wachten op elkaar, één boekt, de rest krijgt netjes "bezet". Dit is de code hieronder.- PostgreSQL 18 met alleen een constraint. De database weigert zelf elke overlap, en de data was in alle 20 rondes correct. Maar in 3 van de 20 rondes eindigde de race in een keten van deadlocks. De negentien verliezers kregen
DeadlockDetectedin plaats van een nette weigering, en de ronde duurde 18 tot 19 seconden. Bij elke deadlock wacht PostgreSQL eerst een seconde (deadlock_timeout), en die wachttijden stapelen. - PostgreSQL 18 met constraint plus een advisory lock per stoel. In 20 van de 20 rondes: één boeking, negentien keer "bezet", ongeveer 0,09 seconde per ronde.
Geen van deze problemen komt aan het licht in een gewone test. Ik heb er daarom een test bij gezet die twintig threads laat boeken, en een regel in CLAUDE.md die uitlegt waarom BEGIN IMMEDIATE verplicht is. Zo leest Claude Code de valkuil in elke sessie opnieuw.
SQLite: de juiste keuze tot je een tweede server nodig hebt
SQLite zit in Python ingebouwd, heeft geen server nodig en past in één bestand. Dat bestand kan Claude Code in een test in een tijdelijke map aanmaken en weer weggooien. Voor een applicatie op één server met een redelijk aantal gebruikers is het een volwaardige keuze, mits je drie dingen instelt: WAL-modus, een busy_timeout, en STRICT-tabellen. Die laatste weigeren tekst in een kolom die een getal moet zijn. Zonder STRICT slaat SQLite die tekst gewoon op.
Eén ding verrast veel mensen. De sqlite3-module opent standaard nog steeds zelf transacties, op een manier die je niet verwacht. Sinds Python 3.12 bestaat het argument autocommit, en de documentatie raadt aan het in te stellen. De standaard verandert pas "in een toekomstige versie". Ik zet het op True en schrijf BEGIN en COMMIT zelf uit. Dan staat in de code wat er gebeurt.
src/kapsalon/db.py
"""Opslag van afspraken in SQLite. Eén verbinding per request of per thread."""
import sqlite3
from pathlib import Path
SCHEMA = """
CREATE TABLE IF NOT EXISTS afspraak (
id INTEGER PRIMARY KEY,
stoel INTEGER NOT NULL,
klant TEXT NOT NULL,
begin TEXT NOT NULL, -- ISO 8601, bijvoorbeeld 2026-11-14T10:00
eind TEXT NOT NULL,
CHECK (eind > begin)
) STRICT;
CREATE INDEX IF NOT EXISTS afspraak_stoel_begin ON afspraak (stoel, begin);
"""
class Bezet(Exception):
"""De stoel is in (een deel van) dit tijdvak al geboekt."""
def verbind(pad: str | Path) -> sqlite3.Connection:
# autocommit=True (Python 3.12+): de module opent zelf geen transacties meer,
# dus BEGIN en COMMIT doen we expliciet.
conn = sqlite3.connect(pad, autocommit=True, timeout=5, check_same_thread=False)
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode = WAL")
conn.execute("PRAGMA busy_timeout = 5000")
conn.executescript(SCHEMA)
return conn
OVERLAP = "SELECT 1 FROM afspraak WHERE stoel = ? AND begin < ? AND eind > ?"
INVOEGEN = "INSERT INTO afspraak (stoel, klant, begin, eind) VALUES (?, ?, ?, ?)"
def boek(
conn: sqlite3.Connection, stoel: int, klant: str, begin: str, eind: str
) -> int:
"""Boek een afspraak, of gooi Bezet. BEGIN IMMEDIATE pakt de schrijfvergrendeling
vóór de controle, zodat geen tweede boeking tussen controle en INSERT kan glippen."""
conn.execute("BEGIN IMMEDIATE")
try:
if conn.execute(OVERLAP, (stoel, eind, begin)).fetchone():
raise Bezet(f"stoel {stoel} is bezet tussen {begin} en {eind}")
rij_id = conn.execute(INVOEGEN, (stoel, klant, begin, eind)).lastrowid
conn.execute("COMMIT")
except BaseException:
conn.execute("ROLLBACK")
raise
assert rij_id is not None
return rij_id
def annuleer(conn: sqlite3.Connection, afspraak_id: int) -> bool:
"""Verwijder een afspraak. Geeft False als die niet bestond. Eén losse DELETE is
atomair (geen controle-dan-schrijven), dus BEGIN IMMEDIATE is hier niet nodig."""
return (
conn.execute("DELETE FROM afspraak WHERE id = ?", (afspraak_id,)).rowcount > 0
)
def afspraken_op(conn: sqlite3.Connection, dag: str) -> list[dict]:
rijen = conn.execute(
"SELECT id, stoel, klant, begin, eind FROM afspraak "
"WHERE begin >= ? AND begin < date(?, '+1 day') ORDER BY stoel, begin",
(dag, dag),
)
return [dict(r) for r in rijen] Een detail om te onthouden: de Python 3.14.10 die uv installeerde, bevat SQLite 3.50.4. De nieuwste SQLite is 3.54.1. Welke SQLite je hebt, hangt af van je Python-build, niet van wat er op sqlite.org staat. Controleer het met sqlite3.sqlite_version voordat Claude een functie gebruikt die jouw versie nog niet kent.
PostgreSQL: als meerdere processen tegelijk schrijven
Draait je applicatie op meer dan één server, of hebben veel gebruikers tegelijk schrijfrechten nodig, kies dan PostgreSQL. De huidige versie is 18; versie 19 staat gepland voor 19 november 2026. PostgreSQL 18 kan iets wat in dit voorbeeld goed van pas komt: temporal constraints. Met WITHOUT OVERLAPS in de primaire sleutel weigert de database zelf elke overlappende afspraak op dezelfde stoel. Hoe slordig de applicatiecode ook is, dubbel boeken lukt niet meer.
pg_boek.py
"""Boeken in PostgreSQL 18. De constraint garandeert dat er nooit twee afspraken
op één stoel overlappen; de advisory lock zorgt dat gelijktijdige boekingen voor
dezelfde stoel netjes achter elkaar gaan in plaats van elkaar te deadlocken."""
import psycopg
from psycopg import errors
SCHEMA = """
CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE TABLE IF NOT EXISTS afspraak (
stoel int NOT NULL,
klant text NOT NULL,
tijd tstzrange NOT NULL,
PRIMARY KEY (stoel, tijd WITHOUT OVERLAPS)
);
"""
class Bezet(Exception):
pass
def boek(
conn: psycopg.Connection, stoel: int, klant: str, begin: str, eind: str
) -> None:
try:
with conn.transaction():
conn.execute("SELECT pg_advisory_xact_lock(%s)", (stoel,))
conn.execute(
"INSERT INTO afspraak (stoel, klant, tijd) VALUES (%s, %s, tstzrange(%s, %s))",
(stoel, klant, begin, eind),
)
except errors.ExclusionViolation as fout:
raise Bezet(f"stoel {stoel} is bezet") from fout De constraint garandeert de juistheid. De advisory lock zet gelijktijdige boekingen voor dezelfde stoel in een rij, waardoor de deadlocks uit de meting verdwijnen. Boekingen voor verschillende stoelen hinderen elkaar niet.
MySQL en DuckDB
Heb je al MySQL draaien, dan kun je dat blijven gebruiken. Let dan op de versie: MySQL 8.0 krijgt sinds april 2026 geen updates meer, en 8.4 en 9.7 zijn de LTS-versies. Een constraint zoals WITHOUT OVERLAPS heeft MySQL niet, dus daar regel je het met SELECT ... FOR UPDATE op een rij per stoel. Hoe je AI en databases verder combineert, staat in mijn artikel over AI en databases in webapplicaties. DuckDB (2.0) is uitstekend voor analyse op grote bestanden, maar niet bedoeld als database achter een webapplicatie waar veel gebruikers tegelijk schrijven.
| Situatie | Kies | Waarom |
|---|---|---|
| Prototype, interne tool, één server | SQLite | geen server, tests in een tijdelijk bestand, Claude kan alles zelf draaien |
| Meerdere servers of workers die schrijven | PostgreSQL 18 | gelijktijdig schrijven, constraints zoals WITHOUT OVERLAPS |
| Bestaande MySQL-omgeving | MySQL 8.4 of 9.7 | niet migreren zonder reden; vergrendelen met FOR UPDATE |
| Rapportages over miljoenen regels | DuckDB naast je hoofddatabase | snel voor analyse, niet voor veel gelijktijdige schrijvers |
Het project inrichten: CLAUDE.md, rechten en een hook
Bij elke sessie leest Claude Code eerst het bestand CLAUDE.md in de root van je project. Wat daarin staat, hoef je nooit meer te herhalen. Met /init maakt Claude een eerste versie. Anthropic geeft een duidelijke richtlijn: houd het kort, onder de 200 regels, en zet er alleen in wat Claude niet zelf uit de code kan halen. Dat zijn de commando's, de afspraken en de valkuilen. Een beschrijving van de architectuur hoort er niet in. Die leest Claude zelf wel.
CLAUDE.md
# Kapsalon-afsprakenplanner
FastAPI + SQLite, Python 3.14, beheerd met uv. Vier stoelen; een afspraak valt binnen één dag.
## Commando's
- Tests: `uv run pytest -q`
- Lint en opmaak: `uv run ruff check --fix` en `uv run ruff format`
- Types: `uv run ty check`
- Server: `uv run fastapi dev src/kapsalon/app.py`
## Regels
- Schrijf eerst een falende test in `tests/`, dan de code. Klaar = alle drie de checks groen.
- Alle SQL staat in `src/kapsalon/db.py`, met `?`-parameters. Nooit f-strings in SQL.
- Schrijven dat eerst controleert en dan invoegt: altijd binnen `BEGIN IMMEDIATE`
(zie `db.boek`). Een gewone `BEGIN` geeft onder gelijktijdige boekingen
"database is locked" in plaats van een nette 409.
- Tijden zijn ISO 8601 zonder tijdzone, lokale tijd van de salon. Intervallen zijn halfopen: [begin, eind).
- Voeg geen dependencies toe zonder het te vragen. Kijk naar de regel over BEGIN IMMEDIATE. Die staat er niet om de code uit te leggen, maar omdat de juiste keuze niet uit de code zelf te halen is. Zonder die regel ziet een gewone BEGIN er net zo verstandig uit.
Regels die altijd moeten gelden, horen niet in CLAUDE.md. Een taalmodel leest die als advies. Wat altijd moet, regel je in .claude/settings.json, in de vorm van rechten en hooks:
.claude/settings.json
{
"permissions": {
"allow": [
"Bash(uv run pytest *)",
"Bash(uv run ruff *)",
"Bash(uv run ty check *)",
"Bash(git status)",
"Bash(git diff *)"
],
"deny": [
"Read(./.env)",
"Read(./*.db)",
"Bash(uv add *)",
"Bash(git push *)"
]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "uv run ruff check --fix --quiet && uv run ruff format --quiet"
}
]
}
]
}
} De allow-regels laten Claude de checks draaien zonder dat het steeds om toestemming vraagt. De deny-regels gelden altijd, in elke modus: .env lezen, een dependency toevoegen of pushen kan dus niet. De PostToolUse-hook draait na elke bewerking ruff. Opmaak is daardoor nooit meer iets waar jij of Claude op hoeft te letten.
Een valkuil die ik zelf tegenkwam. In de eerste run met dit bestand mocht Claude Code uv run pytest niet uitvoeren, ondanks de allow-regel. De debuglog gaf de reden: "Dropped 5 project-scoped permissions.allow entries — workspace not yet trusted". Een map die je nog nooit interactief hebt geopend en goedgekeurd, mag zichzelf geen rechten geven. De deny-regels gingen wel meteen in. Dat is precies goed: een repository die je net hebt gekloond, kan niet ongemerkt zijn eigen commando's toestaan. Open een nieuw project dus eerst één keer met claude en bevestig dat je de map vertrouwt.
Sinds versie 2.1.283 starten interactieve sessies standaard in auto mode. Daarin beoordeelt een classifier riskante acties, zodat je niet voor elk commando hoeft te klikken. Met Shift+Tab wissel je tussen de modi: auto, handmatig, bewerkingen automatisch accepteren, en plan mode. Voor een nieuwe feature begin ik in plan mode. Claude leest dan alleen code en schrijft een plan, en jij leest dat plan voordat er iets verandert.
Een feature laten bouwen: wat er in een echte sessie gebeurde
Met de boekingen en het dagoverzicht af, gaf ik Claude Code één opdracht, zonder verdere uitleg:
Klanten moeten een afspraak kunnen annuleren. Voeg DELETE /afspraken/{id} toe: 204 als het lukt, 404 als de afspraak niet bestaat. Een geannuleerde tijd moet daarna weer boekbaar zijn. Werk volgens CLAUDE.md: eerst falende tests, dan de code, en sluit af met de drie checks.
De eerste run duurde 34 seconden, 10 beurten. Claude schreef vijf tests en een functie annuleer. Daarna liep het vast op de rechten, zie de valkuil hierboven, en het eindverslag was eerlijk: Ik heb DELETE /afspraken/{id} met de tests geschreven, maar er is nog niets uitgevoerd. [...] Het is dus nog niet "klaar" volgens CLAUDE.md. Het meldde de tests niet als groen, maar als niet gedraaid. Dat verschil telt.
De tweede run, nu met toestemming voor de checks, duurde 27 seconden. Claude zette de nieuwe code tijdelijk opzij met git stash en liet zien dat vier van de vijf nieuwe tests dan faalden. Daarna zette het de code terug: 15 tests groen, ruff schoon, ty schoon. En het meldde zelf iets wat ik over het hoofd had gezien. De test "onbekend id geeft 404" slaagde ook zonder de nieuwe code, omdat FastAPI zonder route zelf al 404 geeft. Die test bewijst dus niets. Dat vond het model omdat CLAUDE.md vroeg om eerst falende tests. Zonder die regel was het niemand opgevallen.
De code die het schreef, is klein en klopt:
@app.delete("/afspraken/{afspraak_id}", status_code=204)
def annuleer_afspraak(afspraak_id: int, conn: Conn) -> None:
if not db.annuleer(conn, afspraak_id):
raise HTTPException(status_code=404, detail="afspraak niet gevonden") Het legde ook uit waarom hier geen BEGIN IMMEDIATE nodig is: één losse DELETE controleert niet eerst iets, dus er valt niets tussen te glippen. Het paste de regel uit CLAUDE.md dus toe met begrip, en niet blind.
Eén ding ging mis, en dat lag bij mij. Voor de tweede run gebruikte ik claude -p --continue. Dat pakt de meest recente sessie in de map. Dat was niet de bouwsessie, maar een korte testsessie die ik ertussen had gedraaid om de rechten te onderzoeken. Claude begon dus zonder geheugen van zijn eigen werk. Het merkte dat zelf op ("die wijzigingen komen niet van mij") en werkte gewoon verder vanaf wat in de bestanden stond. Wil je een bepaalde sessie voortzetten, gebruik dan --resume met het sessie-id.
De werkwijze die standhoudt
Er zijn honderd tips over Claude Code. Deze vijf bepalen of je na een maand nog plezier hebt van je codebase.
Eén taak per sessie, en /clear ertussen
Een miljoen tokens context betekent niet dat het verstandig is om alles in één gesprek te doen. Elke mislukte poging, elk foutbericht en elk gelezen bestand blijft erin staan en beïnvloedt wat Claude daarna doet. Anthropic raadt aan om na twee mislukte correcties /clear te gebruiken en opnieuw te beginnen, met een betere opdracht. Met /context zie je wat er in de context zit, en /compact vat het gesprek samen zonder het te wissen.
Plan eerst, bouw daarna in een schone sessie
Voor alles wat groter is dan een kleine functie: laat Claude je in plan mode eerst vragen stellen. Laat het het resultaat opslaan in een bestand zoals SPEC.md, en begin de bouw in een nieuwe sessie die alleen dat bestand leest. Je verliest twee minuten. Je wint een sessie die niet vol staat met verworpen ideeën.
Terugdraaien kan, maar niet alles
Met twee keer Esc of /rewind ga je terug naar een eerder punt in de sessie, inclusief de bestanden. Wat Claude via een shellcommando heeft veranderd, valt daar niet onder. Een gewiste database of een git reset haal je met /rewind niet terug. Commit dus voordat je Claude aan iets groots zet. Git is je echte vangnet.
Werk parallel in worktrees
Met claude --worktree naam krijgt een sessie een eigen git-worktree, een aparte kopie van je repository op een eigen branch. Zo kan de ene sessie aan de annuleringen werken en de andere aan e-mailbevestigingen, zonder dat ze elkaars bestanden overschrijven. Voor wie meer zelfstandig wil laten werken, staat het verder uitgewerkt in Claude Code autonoom laten werken.
Subagents, skills en MCP: pas als je ze mist
Claude Code kan veel meer. Subagents in .claude/agents/ doen deeltaken met een eigen context. Skills in .claude/skills/ zijn vaste werkwijzen. Via MCP koppel je externe systemen, zoals je database, met claude mcp add. En met claude -p draait Claude Code zonder interactie, bijvoorbeeld in een GitHub Action. Begin daar niet mee. Een goede CLAUDE.md, een testsuite en twee deny-regels leveren in de eerste weken meer op dan tien skills. Voeg een skill pas toe als je merkt dat je dezelfde instructie voor de derde keer typt.
De fouten die beginners met Claude Code het vaakst maken
- Geen controle opgeven. "Bouw een boekingssysteem" levert code op die er goed uitziet. "Bouw een boekingssysteem; klaar is als
uv run pytestslaagt, inclusief een test met twintig gelijktijdige boekingen" levert code op die werkt. - Tests die niets bewijzen. Een test die ook zonder de nieuwe code slaagt, is decoratie. Laat Claude eerst de falende test laten zien. Dat ving in de sessie hierboven precies zo'n test.
- Regels in CLAUDE.md die een hook of deny-regel moeten zijn. "Commit nooit .env" is een wens.
"deny": ["Read(./.env)"]is een regel. - Bedrijfsregels alleen in Python. Wat nooit mag, zoals een dubbele boeking, een negatief saldo of een e-mailadres dat twee keer voorkomt, laat je de database bewaken met een constraint. Python-code die "eerst kijkt" gaat stuk zodra twee verzoeken tegelijk komen.
- Eén eindeloze sessie. Na een uur heen en weer weet het model van alles over je eerste drie ideeën, en dat zit het vierde in de weg.
Veelgestelde vragen
Kan ik Claude Code gratis gebruiken?
Nee. Je hebt minimaal een Pro-abonnement nodig ($20 per maand), of een Console-account waarmee je per token betaalt. Met het gratis plan van Claude heb je geen toegang tot Claude Code.
Moet ik goed kunnen programmeren om Claude Code te gebruiken?
Je moet code kunnen lezen en beoordelen. Claude Code schrijft de functie, maar jij beslist of de tests het juiste testen. De race in de kapsalon zie je niet als je niet weet dat hij kan bestaan. Hoe het vak verschuift, beschreef ik in PHP en AI in 2027. Voor Python geldt hetzelfde.
Werkt Claude Code goed met Python?
Ja. Python met uv, pytest en ruff is een van de makkelijkste omgevingen voor Claude Code: één commando om te testen, één om op te maken, en foutmeldingen die precies zeggen wat er mis is. In de test hierboven bouwde het een complete functie met tests in een halve minuut.
SQLite of PostgreSQL voor een nieuw project?
Begin met SQLite als je applicatie op één server draait, en stel WAL, een busy_timeout, STRICT en BEGIN IMMEDIATE in. Stap over naar PostgreSQL zodra meerdere processen of servers tegelijk schrijven. Zet in beide gevallen je harde regels in de database zelf.
Heb ik VS Code nodig?
Nee. Claude Code werkt in elke terminal, naast elke editor. De VS Code-extensie en de JetBrains-plugin maken diffs en context prettiger, maar het werk gebeurt in de CLI.
Wil je morgen beginnen? Kies dan één kleine functie in een project dat al tests heeft. Schrijf in drie regels in CLAUDE.md welke commando's "klaar" betekenen, en vraag Claude Code eerst de falende test te laten zien. Werkt dat, dan heb je de belangrijkste les al binnen. De rest zijn instellingen.
Verder lezen op deze site
- Claude Code in PhpStorm: installatie, plugin en de gewoontes die werken
- Claude Code autonoom laten werken: auto mode, Ralph-loop en tmux
- Claude Code effectief gebruiken: wat echt werkt in 2026
- Wat AI met databases voor webapplicaties deed, van Oracle tot SQLite
- Claude Code voor Windows-onderhoud: wat het vond, waar het de fout in ging en welke grenzen werken
- Gratis afbeeldingen van hoge kwaliteit maken in Claude Code: het beste model en de opzet (november 2026)
- Herdr, Caprock en ccdeck vergeleken: zo houd je meerdere codeeragents bij (november 2026)
Bronnen
- Anthropic, Claude Code-documentatie: installatie, best practices, permission modes, modelconfiguratie, VS Code, JetBrains; changelog (versie 2.1.317)
- Anthropic, prijzen, uitleg over het Ultra-plan en modeloverzicht, geraadpleegd 3 november 2026
- Python Software Foundation, downloads en ondersteuningstermijnen en sqlite3-documentatie; Astral, uv
- JetBrains, PyCharm als één product; Zed, external agents
- PostgreSQL, release notes 18 en PostgreSQL 19 RC 1; SQLite; Oracle, MySQL EOL-notice
- Eigen test, 3 november 2026: Claude Code 2.1.317 met Opus 5.5 (twee headless runs), Python 3.14.10 met SQLite 3.50.4, uv 0.13.7, FastAPI 0.162.0, pytest 9.2.0, ruff 0.17.3, ty 0.0.96, PostgreSQL 18.6 in Docker, psycopg 3; twintig threads per ronde


