Voordat je een regel code schrijft — een quality-first Python-project opzetten met Claude Code

Zeven bestanden, zeven prompts, nul regels applicatiecode. Hoe je linting, formatting, testing en projectstructuur opzet voordat Claude Code je eerste feature schrijft.

Voordat je een regel code schrijft — een quality-first Python-project opzetten met Claude Code
Ook beschikbaar in het English, Deutsch, Français, Español.

Wanneer Claude Code je project schrijft, verandert je rol. Je bent geen typist. Je bent een architect en een reviewer. De code komt snel — soms sneller dan je kunt lezen. Goede tooling is je review-infrastructuur. Het vangt op wat jij mist.

Dit is Deel 1 van een driedelige serie over het opzetten van Python-projectkwaliteit wanneer Claude Code je developer is. We behandelen hier de basis: de bestanden en configuratie die moeten bestaan vóórdat er applicatiecode geschreven wordt.

Het patroon voor elke aanbeveling: wat de tool doet, een prompt die je in Claude Code kunt plakken, en wat je daarna verifieert.

pyproject.toml — de grondwet van je project

Elke Python-tool leest pyproject.toml. Ruff, pytest, mypy, build-backends — ze kijken allemaal hier voor configuratie. Eén bestand, één bron van waarheid.

Nog belangrijker voor AI-ondersteunde ontwikkeling: Claude Code leest het ook. Wanneer je project een goed geconfigureerde pyproject.toml heeft, begrijpt Claude je conventies. Regellengte, linting-regels, testpaden — het pikt deze automatisch op en genereert code die daaraan voldoet.

De prompt:

Create a pyproject.toml for a Python 3.11 project. Configure ruff
(line-length 120, select E/F/W/I/UP/B/SIM rules) and pytest
(testpaths = tests, quiet output with short tracebacks).

Wat te verifiëren: Het bestand bestaat in de projectroot. ruff check . draait zonder configuratiefouten. pytest --co vindt de testdirectory.

Het gegenereerde bestand ziet er ongeveer zo uit:

[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"

[tool.ruff]
line-length = 120

[tool.ruff.lint]
select = ["E", "F", "W", "I", "UP", "B", "SIM"]

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q --tb=short"

Directorystructuur met schone imports

Projectindeling bepaalt of imports werken of breken. Doe het één keer goed en vergeet het daarna.

De verdeling: src/ voor applicatiecode, tests/ voor tests, scripts/ voor operationele scripts die geen onderdeel zijn van het package. Een conftest.py in de testdirectory regelt de import-padconfiguratie zodat tests je broncode kunnen vinden.

De prompt:

Set up the project directory structure: src/ for application code
with __init__.py, tests/ with a conftest.py that adds src/ to
sys.path, scripts/ for operational scripts, and docs/ for
documentation.

Wat te verifiëren: python -c "import src" werkt vanuit de projectroot. Tests kunnen applicatiemodules importeren zonder sys.path-hacks verspreid door elk testbestand.

.gitignore — compleet vanaf het begin

Claude Code genereert bestanden. Ruff maakt een cache aan. Pytest schrijft coverage-data. Virtuele omgevingen bevatten duizenden bestanden. Geen van deze hoort in versiebeheer.

Stel .gitignore in vóór al het andere, want een repository opschonen die al gegenereerde bestanden trackt is vervelend werk.

De prompt:

Create a .gitignore for a Python project. Include __pycache__,
.venv, .env, dist, build, .ruff_cache, .mypy_cache, htmlcov,
.coverage, .DS_Store, *.egg-info, and .pytest_cache.

Wat te verifiëren: Draai git status na het aanmaken en activeren van een virtuele omgeving. Er verschijnen geen .venv/-bestanden.

.editorconfig — consistentie over alle tools heen

Verschillende editors, verschillende standaardinstellingen. Claude Code genereert code met één inspringstijl, je editor herformatteert het met een andere, en de diff is ruis.

.editorconfig standaardiseert witruimteregels over elke tool die je bestanden aanraakt. De meeste editors respecteren het standaard of via een plugin.

De prompt:

Create an .editorconfig: UTF-8, LF line endings, 4-space indent
for Python, tab indent for Makefile, 2-space for YAML. Trim
trailing whitespace.

Wat te verifiëren: Het bestand bestaat in de projectroot. Open een Python-bestand in je editor — de inspringing moet 4 spaties zijn.

Ruff — linter en formatter vóór regel één

Ruff vervangt flake8, isort, pyupgrade en Black in één enkele tool. Het is snel genoeg om bij elke opslag te draaien zonder dat je het merkt.

Waarom dit nog belangrijker is bij AI-gegenereerde code: Claude produceert soms ongebruikte imports, inconsistente formatting of geshadowde variabelen. Dit zijn geen bugs — het is ruis die zich ophoopt. Ruff vangt ze automatisch op en houdt de codebase schoon, ongeacht wie (of wat) de code schreef.

De prompt:

Install ruff and run it on the project. Fix any issues automatically.
Show me the results.

Wat te verifiëren: ruff check . geeft nul bevindingen terug. ruff format --check . meldt dat er geen wijzigingen nodig zijn.

Ruff draaien na elke Claude Code-generatieslag wordt een gewoonte. Zie het als een spellingchecker voor codestijl.

Makefile — je commandopalet

Een Makefile geeft elke veelvoorkomende operatie een korte, makkelijk te onthouden naam. In plaats van python -m pytest tests/ -q --tb=short te onthouden, typ je make test.

Dit is belangrijk voor AI-ondersteunde ontwikkeling omdat je Claude Code kunt vertellen "draai make check" en het precies dezelfde lint-dan-test-reeks uitvoert die jij lokaal draait. Consistente commando's, consistente resultaten.

De prompt:

Create a Makefile with these targets: install (pip install -r
requirements.txt), test (pytest), lint (ruff check), fmt (ruff
format + ruff check --fix), check (lint then test). All targets
should be .PHONY.

Wat te verifiëren: make check draait lint gevolgd door tests. Beide slagen.

De gegenereerde Makefile:

.PHONY: install test lint fmt check

install:
    pip install -r requirements.txt

test:
    pytest

lint:
    ruff check .

fmt:
    ruff format .
    ruff check --fix .

check: lint test

requirements.txt — dependencies bijhouden vanaf het begin

Twee bestanden: requirements.txt voor productie-dependencies, requirements-dev.txt voor ontwikkeltools. Het dev-bestand includeert het productiebestand zodat je niet dezelfde lijst twee keer onderhoudt.

Minimale versiepins (bijv. requests>=2.31) voorkomen stille breuk wanneer een dependency een nieuwe major versie uitbrengt. Pin vroeg — versiepins achteraf toevoegen aan een project met 30 niet-vastgezette dependencies is een middag waar je niet van zult genieten.

De prompt:

Create requirements.txt for production dependencies and
requirements-dev.txt that includes -r requirements.txt plus
pytest, pytest-cov, and ruff.

Wat te verifiëren: pip install -r requirements-dev.txt slaagt in een verse virtuele omgeving. pytest --version en ruff --version werken beide.

De dag-één-checklist

Zeven bestanden, zeven prompts, nul applicatiecode:

  1. pyproject.toml — toolconfiguratie, projectmetadata
  2. src/__init__.py + tests/conftest.py — schone directorystructuur
  3. .gitignore — houd gegenereerde bestanden buiten versiebeheer
  4. .editorconfig — consistente witruimte over alle tools heen
  5. Ruff geconfigureerd en groen — linter en formatter actief
  6. Makefile — standaard commando-interface
  7. requirements.txt + requirements-dev.txt — dependencies bijgehouden

Elk bestand hier dient hetzelfde doel: je vertrouwen geven in code die je niet zelf met de hand hebt geschreven. Wanneer Claude Code morgen een module genereert, zal ruff het linten, pytest het testen, en make check verifiëren dat het hele project nog werkt.

In Deel 2 voegen we het vangnet toe: tests, CI, pre-commit hooks en secret scanning.


Waar draai je dit

Elk project heeft een machine nodig om CI te draaien en staging-omgevingen te hosten. Hetzner geeft je een CX22 voor €4,85/maand met €10 starttegoed — meer dan genoeg voor GitHub Actions self-hosted runners, een stagingserver, of beide.

Als Claude Code je project bouwt en je wilt dat de AI-agentlaag voor je beheerd wordt, draait xCloud OpenClaw hosted — zodat je je kunt richten op prompts en code in plaats van infrastructuur.

(Affiliatelinks — we ontvangen een kleine vergoeding als je je aanmeldt, zonder extra kosten voor jou.)

Als je een AI-assistent gebruikt om een project als dit op te zetten, plak dan de URL van dit bericht in het gesprek. Het pikt de toolkeuzes en promptpatronen op en past ze toe op jouw specifieke setup.