Welcome! Taskflow teaches backend engineering fundamentals using only Node.js—no frameworks, no magic.
You'll build a real task queue system step-by-step, learning core concepts as you go.
Frameworks hide how things work. This project shows you exactly what happens:
- How HTTP requests are parsed
- How data is stored and retrieved
- How middleware chains work
- How to handle errors and scale efficiently
- How real-time updates work with WebSockets
By the end, you'll understand backend systems deeply and be able to debug or build anything.
A real-time task management app with:
- Task creation, updates, deletion
- Priority-based scheduling
- Dependency tracking between tasks
- Parallel job processing with Worker Threads
- Memory management and monitoring
- Live updates via WebSockets
- Data streaming (CSV/NDJSON export)
You need Node.js 18+. Download from nodejs.org.
Check you have it:
node --versioncd se-taskflow-nodejscp .env.example .envThis file stores your API tokens (used for testing authentication).
node server.jsYou should see:
Environment variables loaded natively.
[timestamp] TaskFlow server started on http://localhost:3000
Listening for requests...
Create a task:
curl -X POST http://localhost:3000/tasks \
-H "Authorization: Bearer secret-admin-123" \
-H "Content-Type: application/json" \
-d '{"title":"Learn backend","priority":9}'List all tasks:
curl http://localhost:3000/tasks \
-H "Authorization: Bearer secret-user-123"Start at Step 1 and progress sequentially. Each step builds on the previous one.
| Step | Topic | What You Learn |
|---|---|---|
| 1 | Raw HTTP Server | How Node's http module works, routing, request/response |
| 2 | In-Memory Storage | Hash maps, O(1) lookups, the singleton pattern |
| 3 | Priority Queues | Heaps, O(log N) operations, scheduling algorithms |
| 4 | Dependency Chains | Linked lists, O(N) traversal, recursive resolution |
| 5 | Middleware Chains | The Chain of Responsibility pattern, authentication |
| 6 | Error Handling | Structured error responses, request correlation |
| 7 | Memory Management | Heap vs stack, garbage collection, memory leaks |
| 8 | Worker Threads | Parallelism, offloading CPU work, avoiding blocking |
| 9 | Streaming Data | Readable streams, backpressure, chunked responses |
| 10 | WebSockets | Real-time two-way communication, frame encoding |
→ Start with Step 1
After understanding the concepts, run everything together:
# Terminal 1: Start the server
node server.js
# Terminal 2 (optional): Watch live task events
node scripts/websocket-client.js
# Terminal 3: Run the full demo
bash scripts/full-demo.shThis script demonstrates all 10 concepts in action.
server.js # The main HTTP server
.env.example # Copy to .env before running
learner/ # 10 step-by-step guides
├── 01-http-server.md # Start here!
├── 02-task-store.md
├── ...
└── 10-websockets.md
src/ # Implementation code
├── store/ # Data structures
├── middleware/ # Request handlers
├── services/ # Worker pools, WebSockets, memory
├── workers/ # CPU-heavy background jobs
└── utils/ # Logging, errors
scripts/ # Demo and benchmark scripts
├── full-demo.sh # Run this after learning
├── dependency-resolver-demo.sh
├── websocket-client.js
└── benchmarks/
docs/ # API reference and operation guides
Data Structures:
- Map (hash table): O(1) lookups
- Max-Heap: O(log N) priority ordering
- Linked List: O(1) append, O(N) traversal
Patterns:
- Middleware Chain of Responsibility
- Singleton (shared state)
- Worker pools (task queues)
Operations:
- HTTP routing with manual parsing
- WebSocket frame protocol
- Request/response correlation
- Memory bounded caches
# Start server
node server.js
# Run full demo (all 10 concepts at once)
bash scripts/full-demo.sh
# Benchmark: Map vs Array lookup speed
node scripts/map-vs-array-benchmark.js
# Benchmark: Main thread vs worker threads
node scripts/worker-benchmark.js
# Dependency resolver demo
bash scripts/dependency-resolver-demo.sh
# Live WebSocket client
node scripts/websocket-client.jsAll endpoints require authentication header:
-H "Authorization: Bearer secret-admin-123" # Admin (can create/update/delete)
-H "Authorization: Bearer secret-user-123" # User (can only view)Tasks:
POST /tasks # Create a task
GET /tasks # List all tasks
GET /tasks/:id # Get one task
PUT /tasks/:id # Update a task
DELETE /tasks/:id # Delete a task
GET /tasks/next # Get highest priority task
GET /tasks/resolve # Resolve full dependency order
GET /tasks/:id/resolve # Resolve dependencies for one taskReal-Time:
WS /ws/tasks # Connect for live updatesMonitoring:
GET /tasks/system/memory # Memory usage stats
GET /tasks/system/ws # WebSocket connection count
GET /tasks/reports/stats # Worker pool statisticsStreaming:
GET /tasks/export.csv # Download tasks as CSV
GET /tasks/stream.ndjson # Stream tasks as NDJSONFor full API details, see docs/api-reference.md.
Port already in use?
# Kill the process using port 3000
lsof -ti:3000 | xargs kill -9Getting 401 Unauthorized? Add the auth header:
-H "Authorization: Bearer secret-admin-123"Server crashes on startup?
Make sure your node --version shows 18+:
node --version- Read Step 1: Raw HTTP Server
- Build it: Follow the exercises in each guide
- Run scripts: Use the demo scripts to see it all working
- Experiment: Modify the code and see what breaks—that's learning!
- Re-read the specific guide for that concept
- Look at the working code in
src/ - Run a demo script to see the live behavior
- Add
console.log()statements to trace execution
- Runtime: Node.js (no TypeScript, no Babel)
- Database: In-memory hash map (resets on restart)
- Real-time: Native WebSocket protocol (no external library)
- External packages: None (everything from Node.js stdlib)
This is intentional—you'll see exactly what you're using and why.
Open source, learn freely.
Ready? → Start with Step 1: Raw HTTP Server
Taskflow is a real-time, collaborative task queue system built to teach backend engineering from first principles.
This repository intentionally avoids backend frameworks so learners can understand exactly what happens under the hood in production systems. Routing, request parsing, state management, and API behavior are implemented manually using core Node.js APIs.
Most tutorials start with frameworks and hide core mechanics. Taskflow does the opposite:
- Build with core Node.js first.
- Understand architecture and tradeoffs before abstractions.
- Learn data structures and algorithmic complexity in context.
- Introduce advanced capabilities (streaming, worker threads, WebSockets) progressively.
The result is a learning-first codebase that teaches both implementation and reasoning.
The code now includes Parts 1 through 10:
- Step 1: Raw Node.js HTTP server with manual routing
- Step 2: In-memory task store using JavaScript Map (O(1) Hash Map) and Singleton export
- Step 3: Priority Queue (Max-Heap) for O(log N) prioritized scheduling
- Step 4: Linked-List Task Dependency Chains with O(N) automated garbage collection (sweep)
- Step 5: OOP Middleware Chain of Responsibility (Authentication, Roles, Data Validation)
- Step 6: Global error handling with structured logging and request correlation
- Step 7: Memory leak detection, bounded caches, and memory observability
- Step 8: Worker Thread CPU offloading with a reusable worker pool
- Step 9: Streaming CSV / NDJSON exports with backpressure-safe pipelines
- Step 10: WebSocket live updates with heartbeats and task broadcast
Planned parts are documented in the roadmap below and expanded in the learner guides.
- Runtime: Node.js (No Babel, No TypeScript)
- Current external npm packages: none (zero-dependency design)
- WebSocket support is implemented natively with the Node.js
upgradepath and manual frame handling
Everything else is built natively.
server.js: HTTP server, route handling, JSON parsing, middleware execution, streaming, memory demos, and WebSocket upgrade handlingscripts/full-demo.sh: Unified end-to-end demo script covering all major conceptsscripts/demo-live-events.sh: Emits create/update/delete events for live WebSocket observationscripts/map-vs-array-benchmark.js: Big O demonstration (Array.find vs Map.get)scripts/worker-benchmark.js: Worker Thread benchmark for blocking vs parallel CPU workscripts/dependency-resolver-demo.sh: Recursive dependency resolution and cycle detection demoscripts/websocket-client.js: Terminal WebSocket client for live update demosdocs/full-demo.md: Full demo instructions and integrated endpoint mapsrc/store/TaskStore.js: Singleton in-memory state enginesrc/store/PriorityQueue.js: Max-Heap Queue data structure for ordering Tasks by prioritysrc/store/DependencyList.js: Singly Linked List data structure for Task prerequisite linkingsrc/services/MemoryManager.js: Bounded memory tracking, leak demo batches, and cleanupsrc/services/WorkerPool.js: Managed Worker Thread pool for CPU-heavy jobssrc/services/WebSocketHub.js: Native WebSocket broadcast and heartbeat managersrc/middleware/: Chain of Responsibility implementation for Auth, Permissions, and Validationssrc/config/env.js: Zero dependency.envparserlearner/README.md: Learning path and deep-dive documentation indexdocs/full-demo.md: End-to-end terminal demo instructions
- Node.js 18+ recommended (crypto.randomUUID support)
Create your .env file based on the example to supply the API tokens for the Middleware Chain:
cp .env.example .envnode server.jsExpected startup output:
Environment variables loaded natively.TaskFlow server is running on http://localhost:3000Listening for requests... (Press Ctrl+C to stop)
Full integrated demo:
bash scripts/full-demo.shDependency resolver focused demo:
bash scripts/dependency-resolver-demo.shData-structure benchmark:
node scripts/map-vs-array-benchmark.jsWorker benchmark:
node scripts/worker-benchmark.jsYou should observe significantly faster Map lookup timing compared to Array.find for large collections.
Base URL: http://localhost:3000
Returns all tasks. Users and Admins can access this.
Returns the Max-Heap queue array structure highlighting task priority ordering.
Returns the absolute highest priority task without dequeuing it. O(1) read time.
Creates a new task. Requires Admin Token.
Request body (title and priority are validated):
{
"title": "Prepare sprint board",
"priority": 5,
"dependencies": []
}Updates an existing task by merging provided fields. Validates the payload and organically updates the Priority Queue and Dependency Linked List. Requires Admin Token.
Deletes a task and performs an O(N) sweep across all other tasks to cleanly remove its ID from their linked list dependencies to prevent ghost links! Requires Admin Token.
Streams all tasks as CSV using backpressure-safe streaming.
Streams all tasks as NDJSON for incremental consumption.
Returns the next highest-priority task candidate from the queue without dequeuing it.
Resolves dependency-safe execution order for all tasks using recursive DFS/topological ordering.
Resolves dependency-safe execution order for one task subtree. Returns 409 when a cycle is detected.
Starts a Worker Thread powered task analytics report job and returns a jobId.
Fetches report job status and output.
Returns report worker pool runtime statistics.
Returns current bounded memory manager and process memory statistics.
Creates an intentional retained batch (for leak demonstration).
Creates a bounded cache batch that trims automatically.
Clears memory demo caches.
Returns WebSocket hub statistics.
Real-time task event stream (task.created, task.updated, task.deleted).
Lightweight endpoint for latency checks before and after heavy CPU work.
Runs CPU work on the main thread so you can demonstrate event loop blocking.
Runs the same CPU work in a Worker Thread and waits for completion.
Queues a Worker Thread job and returns a job ID for polling.
Returns heap, rss, external, and array buffer memory usage.
Creates an intentional leak batch for demonstration.
Creates a bounded cache batch that gets trimmed automatically.
Returns WebSocket hub statistics.
curl -i -X POST http://localhost:3000/tasks \
-H "Authorization: Bearer secret-admin-123" \
-H "Content-Type: application/json" \
-d '{"title":"Implement auth middleware","priority":10}'Replace TASK_A_ID with the ID generated in the last command! This automatically injects it into a native Linked List.
curl -i -X POST http://localhost:3000/tasks \
-H "Authorization: Bearer secret-admin-123" \
-H "Content-Type: application/json" \
-d '{"title":"Secondary Task","priority":5,"dependencies":["TASK_A_ID"]}'curl -i -H "Authorization: Bearer secret-user-123" http://localhost:3000/taskscurl -i -X PUT http://localhost:3000/tasks/TASK_A_ID \
-H "Authorization: Bearer secret-admin-123" \
-H "Content-Type: application/json" \
-d '{"priority":100}'curl -i http://localhost:3000/tasks/peekcurl -i -X DELETE http://localhost:3000/tasks/TASK_A_ID \
-H "Authorization: Bearer secret-admin-123"Each task currently contains:
id: UUID string generated by crypto.randomUUIDtitle: stringdescription: stringstatus: string (pending, in-progress, completed)priority: integer (higher number = higher execution urgency)dependencies: Array serialization of the activeDependencyListSingly Linked ListcreatedAt: ISO timestamp stringupdatedAt: ISO timestamp string
- Node HTTP server accepts request.
src/config/envparses.envmanually into global variables.- Stream body is read into JSON format globally for mutating requests.
- Middleware Chain of Responsibility executes: Auth -> Permission -> Validation.
- If the chain yields, URL/method handles endpoints.
TaskStoreprocesses updates:- Sets the O(1) Memory map.
- Safely sweeps and parses arrays to
DependencyList. - Modifies positions linearly in the
PriorityQueueMax Heap.
- JSON response sent explicitly.
Taskflow’s intended progression covers:
- Raw HTTP API in Node.js without frameworks (Done!)
- In-memory task store with Hash Map and complexity benchmark (Done!)
- Priority queue for prioritized scheduling (Done!)
- Linked-list dependency chains and recursive dependency resolution with cycle detection (Done!)
- Middleware chain (authentication, authorization, validation) (Done!)
- Global error handling and structured logging (Done!)
- Intentional memory leak demonstration and remediation (Done!)
- Worker Thread report generation for CPU-heavy processing (Done!)
- Streaming CSV export via Node streams (Done!)
- WebSocket live updates using native Node.js upgrade handling (Done!)
This repository currently has Steps 1 through 10 completely implemented natively!
- Data Structures: Priority Queues, Binary Heaps, Singly Linked Lists, Hash Maps (O(1) Time vs O(N) vs O(log N)).
- Design Patterns: Singleton State Stores, Object-Oriented Chain of Responsibility, Interceptors.
- Event Loop internals (Timers, Poll, Check phases)
- Call Stack and libuv responsibilities
Detailed guides are available in learner/README.md and docs/full-demo.md.
Run server on a free port by changing PORT in server.js.
Since Step 5 was introduced, modifying commands explicitly require an ADMIN_TOKEN placed inside the Authorization: Bearer <token> header as seen in the .env file.
Expected behavior. This is currently an in-memory repository designed to teach data structures without database overhead!