Skip to main content
This tutorial builds Linkly, a link shortener, one worker at a time. You start with a single function that turns /s/abc into a redirect, and finish with a multi-tenant link platform that has durable execution, storage, analytics, a live click stream, bulk imports, and permission gated untrusted browser workers that have all the same functionality and observability as the base system. Each chapter adds one capability by adding a worker to your existing system. The point is not the link shortener itself, but the pattern: a real system on iii is a set of small workers that invoke each other’s functions and triggers. You add capability without needing to refactor existing functionality.
New to iii? Install it before you begin.

Choose your path

Both paths will build the same system.
  • Agentic gives an AI agent one prompt per chapter and reviews what it writes.
  • Exploration writes each chapter by hand, with the reasoning behind every step.

An overview of the chapters

The agentic path contains all of these chapters on a single page while the exploration path divides them into separate sections.

Ch. 1: Foundations

Build a custom link worker with link::create and link::resolve, store links in memory, then expose them over HTTP with http as POST /links and GET /s/:code.

Ch. 2: Observe everything

Use the engine-injected iii-observability functions for logs and traces, and open the console to inspect functions, triggers, and live invocations.

Ch. 3: Persist everything

Add a database worker (SQLite) so links and click events are stored durably and survive restarts, with state kept in front as a fast read cache.

Ch. 4: Make it durable

Push click events onto queue so redirects stay fast, and publish link.created events with pubsub that a cache and an analytics function each subscribe to.

Ch. 5: Stream live clicks

Push every click to subscribers in real time from a dedicated click-streamer worker with iii-stream.

Ch. 6: Move bulk data with channels

Bulk-load links from a CSV in a single streamed upload over a channel.

Ch. 7: Bring in the browser

Turn a browser tab into a worker with the browser SDK: invoke link::create directly, subscribe to the click stream, and register a browser-side function the server can call.