Interactive network protocols learning platform β Visualize, simulate, and master network protocols through hands-on experimentation.
This is a learning project where we build an interactive platform to understand network protocols (like how your browser talks to websites).
But the goal isn't just to build it β it's to LEARN while building it!
Every tool, every file, every concept is documented so you understand:
- π What it does β Core functionality
- π€ Why we use it β Problem it solves
- π§ How it works β Key concepts
- π Alternatives β What else could we use
This project uses a monorepo structure. Let's break down what that means:
Mono = One, Repo = Repository
Instead of having 5 separate folders/projects on your computer, we have ONE folder that contains multiple related projects. This makes it easier to:
- Share code between projects
- Keep everything in sync
- Run all projects with one command
protocol-lab/ π THE ROOT - Everything lives here
β
βββ π¦ apps/ π APPLICATIONS (things users interact with)
β β
β βββ π± web/ π THE WEBSITE (what you see in browser)
β β βββ app/ # Pages of the website
β β β βββ layout.tsx # The "frame" around every page (header, footer)
β β β βββ page.tsx # The home page (what you see at localhost:3000)
β β β βββ globals.css # Styles for the whole website
β β βββ components/ # Reusable UI pieces (buttons, cards, etc.)
β β βββ lib/ # Helper functions
β β βββ public/ # Static files (images, icons)
β β βββ package.json # Lists what this app needs to run
β β βββ tsconfig.json # TypeScript settings
β β
β βββ π₯οΈ server/ π THE API (backend that powers the website)
β βββ src/
β β βββ index.ts # Entry point - where the server starts
β βββ package.json # Lists what this app needs
β βββ tsconfig.json # TypeScript settings
β
βββ π packages/ π SHARED CODE (used by multiple apps)
β β
β βββ π¨ ui/ π Shared UI components
β β βββ src/ # Button, Card, etc. used by both apps
β β
β βββ π protocols/ π Protocol simulation logic
β β βββ src/
β β βββ index.ts # State machines for TCP, TLS, etc.
β β
β βββ π types/ π Shared data definitions
β β βββ src/
β β βββ index.ts # "What does a Packet look like?"
β β
β βββ βοΈ config/ π Shared configuration
β β βββ biome.json # Linting/formatting rules
β β
β βββ π typescript-config/ π Shared TypeScript settings
β βββ base.json # Common compiler options
β
βββ π Configuration Files (ROOT LEVEL)
β β
β βββ package.json # π ROOT package.json (manages the whole monorepo)
β βββ pnpm-workspace.yaml # π Tells pnpm which folders are "packages"
β βββ turbo.json # π Turborepo config (how to build/run things)
β βββ biome.json # π Code style rules (formatting, linting)
β βββ README.md # π You are here! π
β
βββ π Generated Folders (DON'T EDIT THESE)
βββ node_modules/ # Downloaded dependencies (auto-generated)
βββ .next/ # Next.js build output (auto-generated)
βββ dist/ # Server build output (auto-generated)
βββ .turbo/ # Turborepo cache (auto-generated)
| Problem | Solution |
|---|---|
| "I have duplicate code in frontend and backend" | Put shared code in packages/ |
| "My types don't match between apps" | Share types via packages/types/ |
| "Building is slow" | Turborepo caches builds, only rebuilds changed code |
| "I need to run 5 terminals" | pnpm dev runs everything at once |
{
"name": "protocol-lab", // Project name
"private": true, // Don't publish to npm (this is our project)
"scripts": {
"dev": "turbo run dev", // π Runs ALL apps in development mode
"build": "turbo run build", // π Builds ALL apps for production
"lint": "biome check ." // π Checks code style
}
}What is package.json?
- It's like a recipe card for your project
- Lists all the "ingredients" (dependencies) your project needs
- Defines "scripts" β shortcuts for common commands
packages:
- "apps/*" # Everything in apps/ is a package
- "packages/*" # Everything in packages/ is a packageWhat does this do?
- Tells pnpm "hey, these folders are all part of the same project"
- Allows packages to import from each other with
workspace:*
{
"tasks": {
"build": {
"dependsOn": ["^build"], // Build dependencies first
"outputs": [".next/**"] // Cache these files
},
"dev": {
"persistent": true // Keep running (don't exit)
}
}
}What is Turborepo?
- It's a build orchestrator β it figures out what to run, in what order
- If you change
packages/types, it knows to rebuild everything that uses it - It caches builds β if nothing changed, it skips the build (super fast!)
{
"linter": { "enabled": true }, // Check for bugs
"formatter": { "enabled": true } // Make code pretty
}What is Biome?
- Linter: Finds bugs and bad practices (like
varinstead ofconst) - Formatter: Makes code look consistent (indentation, quotes, etc.)
- Replaces ESLint + Prettier (one tool instead of two!)
| Question | Answer |
|---|---|
| What is it? | A program that runs JavaScript/TypeScript code |
| What does "runtime" mean? | The engine that reads your code and executes it |
| Why not just use Node.js? | Bun is 3x faster and understands TypeScript natively |
| What's the catch? | It's newer, some packages might have issues |
# With Node.js, you need extra steps:
node app.js # Only runs JavaScript
tsc app.ts && node app.js # TypeScript needs compilation
# With Bun, it just works:
bun app.ts # Runs TypeScript directly!| Question | Answer |
|---|---|
| What is it? | Downloads and manages dependencies (external code) |
| What are dependencies? | Code written by others that we use (React, etc.) |
| Why not npm? | pnpm is faster and uses less disk space |
| How does it save space? | Uses "symlinks" β shortcuts instead of copies |
# What happens when you run:
pnpm install
# 1. pnpm reads package.json
# 2. Downloads all listed dependencies
# 3. Stores them in a global cache (~/.pnpm-store)
# 4. Creates symlinks in node_modules/What is a symlink? Think of it like a shortcut on your desktop. Instead of copying the same file 10 times, we have 10 shortcuts pointing to one file.
| Question | Answer |
|---|---|
| What is it? | Runs and builds multiple projects together |
| What's a "task"? | Something to run, like build, dev, lint |
| What's caching? | Remembering results so we don't redo work |
# Without Turborepo:
cd apps/web && npm run build # Build frontend
cd apps/server && npm run build # Build backend
cd packages/ui && npm run build # Build UI package
# ... and so on, manually, every time
# With Turborepo:
pnpm build # Does everything, in the right order, skipping unchanged!
| Question | Answer |
|---|---|
| What is React? | A library for building user interfaces with components |
| What is Next.js? | A framework built ON TOP of React, adds routing, SSR, etc. |
| What's the difference? | React = building blocks, Next.js = full house blueprint |
| What's App Router? | File-based routing β files become URLs automatically |
# File-based routing example:
app/
βββ page.tsx β localhost:3000/
βββ about/page.tsx β localhost:3000/about
βββ blog/[id]/page.tsx β localhost:3000/blog/123
| Question | Answer |
|---|---|
| What are types? | Labels that say what kind of data something is |
| Why do we need them? | Catches bugs before you run the code |
| What's the downside? | More code to write, learning curve |
// JavaScript - no types, errors happen at runtime (when users see them!)
function add(a, b) {
return a + b;
}
add("hello", 5); // Returns "hello5" - probably not what you wanted!
// TypeScript - types catch errors before running
function add(a: number, b: number): number {
return a + b;
}
add("hello", 5); // β Error: "hello" is not a number!| Question | Answer |
|---|---|
| What is CSS? | The language that styles web pages (colors, sizes, etc.) |
| What's different about Tailwind? | Instead of writing CSS files, you use classes |
| Why is that better? | Faster to write, no naming things, stays consistent |
<!-- Traditional CSS -->
<div class="my-card">Hello</div>
<style>
.my-card {
padding: 16px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
</style>
<!-- Tailwind CSS -->
<div class="p-4 bg-white rounded-lg shadow-md">Hello</div>
<!-- No separate CSS file needed! Classes describe the style -->| Question | Answer |
|---|---|
| What is a web server? | A program that responds to HTTP requests |
| What's HTTP? | The protocol browsers use to fetch web pages |
| Why Hono? | Super lightweight (14KB), fast, TypeScript-first |
| What about Express? | Express is 1.4MB, older, requires more setup |
// Simple Hono server
import { Hono } from 'hono'
const app = new Hono()
// When someone visits "/", send back "Hello!"
app.get('/', (c) => c.text('Hello!'))
// When someone visits "/api/users", send back JSON data
app.get('/api/users', (c) => c.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]))| Question | Answer |
|---|---|
| What is state? | The current "situation" of your app |
| What's a state machine? | A diagram of all possible states and how to move between them |
| Why use it for protocols? | Protocols have defined states (CONNECTING β CONNECTED β CLOSED) |
TCP Connection State Machine:
βββββββββββ SYN ββββββββββββ SYN-ACK βββββββββββββββ
β CLOSED β ββββββββΊ β SYN_SENT β βββββββββΊ β ESTABLISHED β
βββββββββββ ββββββββββββ βββββββββββββββ
| Question | Answer |
|---|---|
| What is validation? | Checking if data has the right format |
| When do we need it? | When receiving data from users or APIs |
| Why Zod? | Validates data AND gives TypeScript types |
import { z } from 'zod'
// Define what a "User" should look like
const UserSchema = z.object({
name: z.string(), // Must be text
age: z.number().min(0), // Must be number >= 0
email: z.string().email(), // Must be valid email
})
// Validate incoming data
const result = UserSchema.safeParse({
name: "Alice",
age: 25,
email: "alice@example.com"
})
if (result.success) {
console.log(result.data) // Safe to use!
} else {
console.log(result.error) // Show what's wrong
}# Install Bun (JavaScript runtime)
# This downloads and installs Bun on your computer
curl -fsSL https://bun.sh/install | bash
# Install pnpm (package manager)
# This downloads and installs pnpm
curl -fsSL https://get.pnpm.io/install.sh | sh -
# Restart your terminal or run:
source ~/.zshrc # macOS/Linux# Navigate to the project folder
cd protocol-lab
# Install all dependencies
# This reads package.json files and downloads everything needed
pnpm install# Start all apps in development mode
pnpm dev
# This starts:
# - Frontend at http://localhost:3000
# - Backend at http://localhost:3001- Open your browser
- Go to
http://localhost:3000 - You should see the app running!
| Command | What it does |
|---|---|
pnpm dev |
Start development servers (auto-reloads on changes) |
pnpm build |
Build for production (optimized, ready to deploy) |
pnpm lint |
Check code for errors and style issues |
pnpm lint:fix |
Automatically fix linting issues |
pnpm format |
Format code to look consistent |
- JavaScript.info β Learn JavaScript from scratch
- TypeScript Handbook β Official TypeScript guide
- React Tutorial β Official React tutorial
- Bun Documentation β Learn Bun
- Next.js Documentation β Learn Next.js
- Tailwind CSS β Learn Tailwind
- Hono Documentation β Learn Hono
- XState Documentation β Learn state machines
- Turborepo Handbook β Learn Turborepo
- pnpm Workspaces β Learn pnpm workspaces
Each tool needs its own configuration. It looks like a lot, but:
package.jsonβ What dependencies to installtsconfig.jsonβ How to compile TypeScriptturbo.jsonβ How to run buildsbiome.jsonβ How to format/lint code
- apps/ β Standalone applications (has an entry point, runs on its own)
- packages/ β Shared libraries (imported BY apps, doesn't run alone)
This tells pnpm "use the local package from this monorepo, not one from npm".
{
"dependencies": {
"@repo/types": "workspace:*" // Use local packages/types folder
}
}Transforming source code into optimized code browsers can run:
- TypeScript β JavaScript
- Modern JS β Compatible JS
- Many files β Bundled/minified files
MIT License β use this freely for learning!