This course is about building a backend service from behavior, not implementation.
We will use Test-Driven Development (TDD) — writing a failing test before any production code — to build a URL shortener API with TypeScript, Fastify, PostgreSQL, Jest, and Docker.
By the end, you'll be able to take a feature from a failing test all the way to production-ready code, without losing control as the system grows.
Early in my career, I kept hearing that tests mattered. But on real projects, they were usually the first thing cut once deadlines got tight. That gap — between what teams say and what they do — is a big reason I made this course.
Node.js is a great place to learn TDD because the feedback loop is short:
That makes the Red → Green → Refactor cycle something you feel, not just understand.
The course stays practical. We build one service from start to finish, keep the scope clear, and add real problems only when we actually need them.
A quick note: TDD does feel slower at first, and you'll sometimes wonder whether the test-first step is worth it. That's normal. The goal here is to shorten that awkward phase through repeated practice on a single project.
This course is for engineers who know backend basics and want a better testing workflow.
You don't need prior Fastify or PostgreSQL experience, but you should already be comfortable with:
async / awaitclone, checkout, and commitIf you're brand new to Node.js, this will move too fast. But if you can already read backend code and want a more disciplined way to write it, you're in the right place.
All source code lives on GitHub:
👉 test-driven-development-tdd-with-nodejs-course
Most hands-on chapters have two branches:
| Branch | What it is |
|---|---|
xx-chapter-name-start | The starting point, before we write the chapter's code |
xx-chapter-name-finish | The completed state, after we finish the chapter |
Workflow: start from the start branch, write the code yourself, and use the finish branch only to compare or recover if you get stuck.
A few notes on numbering:
01-what-is-tdd-start.main branch holds the final version of the project.We're building a URL shortener API — a service that:
The idea is simple, which is exactly what makes it a good TDD project. The behavior is easy to describe, but the implementation still leaves room to practice real backend work:
We'll start with a tiny example in plain Node.js so the TDD loop is easy to see. Then we move into the real project: a Fastify API in TypeScript, backed by PostgreSQL, built step by step as the system grows.
The progression is deliberate:
The project stays understandable from start to finish. We add complexity in layers, and the test suite tells us whether each step was safe.
This is not a course where we write code first and bolt tests on later. The test comes first whenever the behavior is clear enough to describe.
Expect to see:
That's not a flaw in the process — that is the process.
In production, this gives you more than coverage. It gives you fast feedback: when a change breaks behavior, you know quickly; when a refactor is safe, you know quickly.
Next up: we'll make TDD concrete with a tiny Node.js example before moving into the Fastify application.