Course Overview
WIPBuild PhotoDuck — a photo-sharing app with resumable uploads — from an empty folder to production.
What you'll build
This course builds PhotoDuck, a photo-sharing app, one upload feature at a time. You start
with a single file transfer and finish with a production setup: multipart uploads, pause/resume,
persistence, validation, plugins, typed results, and deduplication — all on the real
@gentleduck/upload API.
Who it's for
- Developers new to
@gentleduck/uploadwho want a guided path. - Teams evaluating the engine for real upload needs.
- Anyone who learns by building something concrete.
Prerequisites
- TypeScript basics (types, generics, async/await).
- React basics for Chapters 3+ (components, hooks, context).
- Node 22+ or Bun.
- Passing familiarity with S3/MinIO helps but isn't required.
The mental model you'll carry
Everything in the course rests on four type parameters — M (intent map), C (cursor
map), P (purpose), R (result). You define them once and they thread through the API,
the store, the events, and your components. Keep them in mind; each chapter adds to them.
Set up the project
Create and initialize a project:
mkdir photoduck && cd photoduck
npm init -y
npm install @gentleduck/upload typescript tsx
npx tsc --init
mkdir src
Start with Chapter 1: Your First Upload.
Course map
| Chapter | Topic | Key API |
|---|---|---|
| 1 | Your First Upload | createUploadStore, Contracts.Api.Me, dispatch, phases, events |
| 2 | Strategies & Backends | PostStrategy, createStrategyRegistry, presigned URLs |
| 3 | React Integration | UploadProvider, useUploader, dropzone, progress bars |
| 4 | Multipart Uploads | multipartStrategy, signPart, completeMultipart, cursors |
| 5 | Pause, Resume & Retry | pause/resume/cancel/retry, config.retryPolicy |
| 6 | Persistence & Offline | IndexedDBAdapter, rebind, resume across reloads |
| 7 | Validation & Plugins | Contracts.ValidationRules, validateFile, Engine.Plugin, hooks |
| 8 | Production Patterns | Typed R, dedupe, multiple purposes, testing |
Each chapter ends with a checkpoint (the full code so far) and an FAQ.