Learn structured concurrency by building a multiplex HTTP proxy
Ever written async code that leaked connections, orphaned timers, or left servers running after Ctrl+C? You're not alone. JavaScript's async/await feels great—until it doesn't.
Effection is a structured concurrency library that fixes this by guaranteeing:
- No operation runs longer than its parent - automatic cleanup
- Every operation exits fully -
finallyblocks always run - It's just JavaScript - use
if,for,while,try/catchas normal
By the end of this tutorial, you'll build a multiplex HTTP proxy that dynamically spawns Express servers and routes requests through a switchboard - all managed by Effection.
| Chapter | Topic | Run Examples |
|---|---|---|
| 01 | The Problem with Promises | npx tsx chapters/01-*/leaky-race.ts |
| 02 | Operations | npx tsx chapters/02-*/countdown.ts |
| 03 | Actions - Bridging Callbacks | npx tsx chapters/03-*/sleep-with-logging.ts |
| Chapter | Topic | Run Examples |
|---|---|---|
| 04 | Spawn - Child Operations | npx tsx chapters/04-*/spawn-example.ts |
| 05 | Combinators - all() and race() | npx tsx chapters/05-*/timeout-pattern.ts |
| 06 | Resources - Long-running Services | npx tsx chapters/06-*/resource-socket.ts |
| Chapter | Topic | Run Examples |
|---|---|---|
| 07 | Channels | npx tsx chapters/07-*/channel-basics.ts |
| 08 | Signals - Events from Callbacks | npx tsx chapters/08-*/signal-basics.ts |
| 09 | Streams - The Unifying Concept | npx tsx chapters/09-*/stream-vs-subscription.ts |
| 10 | Context - Sharing Values | npx tsx chapters/10-*/context-basics.ts |
| Chapter | Topic |
|---|---|
| 11 | Scope API - Embedding Effection in Express, React, etc. |
| Section | Topic |
|---|---|
| Overview | Architecture and what we're building |
| Server Resource | Wrapping Express as a resource |
| Server Pool | Managing dynamic servers |
| Switchboard | Routing requests |
| Final Assembly | Putting it all together |
# Clone and install
git clone https://github.com/thefrontside/hydra.git
cd hydra
npm install
# Start the tutorial
cd chapters/01-problem-with-promises
cat README.md
# Run an example
npx tsx leaky-race.ts
# Run the capstone project
cd ../../capstone
npx tsx start.ts- Solid JavaScript/TypeScript knowledge
- Familiarity with
async/await - Basic understanding of Node.js
- Experience with Express is helpful but not required
hydra/
├── chapters/ # Tutorial chapters (concepts + examples)
│ ├── 01-problem-with-promises/
│ │ ├── README.md # Chapter content
│ │ ├── leaky-race.ts # Runnable example
│ │ └── ...
│ ├── 02-operations/
│ ├── ...
│ └── 11-scope-api/
│
├── capstone/ # The multiplex proxy project
│ ├── README.md # Architecture overview
│ ├── docs/ # Implementation guides
│ ├── src/ # Source code
│ └── start.ts # Entry point
│
└── README.md # You are here
This tutorial has been validated against:
- Effection AGENTS.md contract (API correctness)
- Official Effection documentation (best practices)
- Frontside voice guidelines (writing style)
When contributing to this tutorial:
- Follow the Effection contract - See AGENTS.md for API correctness rules
- Use Frontside voice - Conversational-expert tone, sustained metaphors, brief conclusions
- Test all examples - Every code block should be runnable with
npx tsx - Validate changes - Check against official Effection docs before submitting
| Pattern | Correct | Incorrect |
|---|---|---|
| Existing promises | yield* until(promise) |
yield* call(() => promise) |
| New async work | yield* call(async () => {...}) |
N/A |
| Error boundaries | yield* scoped(function*() {...}) |
Uncontained errors |
| Operation messaging | Channel |
Signal (use Signal for callbacks) |
Start with Chapter 01: The Problem with Promises
MIT