Skip to main content

Course Overview

WIP

Build 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.

Loading diagram...

Who it's for

  • Developers new to @gentleduck/upload who 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

ChapterTopicKey API
1Your First UploadcreateUploadStore, Contracts.Api.Me, dispatch, phases, events
2Strategies & BackendsPostStrategy, createStrategyRegistry, presigned URLs
3React IntegrationUploadProvider, useUploader, dropzone, progress bars
4Multipart UploadsmultipartStrategy, signPart, completeMultipart, cursors
5Pause, Resume & Retrypause/resume/cancel/retry, config.retryPolicy
6Persistence & OfflineIndexedDBAdapter, rebind, resume across reloads
7Validation & PluginsContracts.ValidationRules, validateFile, Engine.Plugin, hooks
8Production PatternsTyped R, dedupe, multiple purposes, testing

Each chapter ends with a checkpoint (the full code so far) and an FAQ.