I Built a Real OS Inside Chrome (With Actual Memory Fragmentation)

Most "web OS" projects are just draggable windows with local state.

I wanted to see what happens when you force a browser to obey real operating system rules.

So I built WebOS: a fully simulated OS inside Chrome with modular kernel architecture, queue-based process management, round-robin CPU scheduling, first-fit memory allocation (with fragmentation), block-based virtual disk, Unix-inspired inode file system, and strict kernel → store → UI control flow.

Built with React, vanilla JavaScript, Zustand, GSAP, and react-rnd.

This isn't a UI skin. It's a constraint-driven system model running entirely inside a browser runtime.

What It Actually Looks Like

Multiple apps running simultaneously. Independent PIDs. Per-process CPU and memory tracking.

The UI reflects system state. It never invents it.

System Architecture: Kernel → Store → UI

Most web apps follow this pattern: UI → State → Render.

WebOS enforces: Kernel → Store → UI.

The UI has zero authority over system resources.

The Kernel (Vanilla JavaScript)

The kernel is composed of independent subsystems: ProcessManager, MemoryManager, Scheduler, FileSystem, StorageSystem.

All resource arbitration happens here.

The UI cannot allocate memory. The UI cannot spawn processes. The UI cannot write to disk.

Everything goes through the kernel first.

The State Bridge (Zustand)

Zustand acts as an authoritative synchronisation layer between the kernel and React.

When launching an app:

  1. UI triggers createApp()
  2. Kernel validates memory + CPU availability
  3. PID is allocated
  4. Memory block assigned
  5. Scheduler registers process
  6. Store syncs confirmed state
  7. React renders

If allocation fails, nothing renders.

The UI reacts to system state, it does not create it.

Process Management

The ProcessManager allocates PIDs, tracks process states (ready, running, waiting), coordinates with memory + scheduler, and ensures proper cleanup on termination.

A process cannot exist without memory. It cannot execute without CPU time. Subsystem coordination is strictly enforced.

Round Robin CPU Scheduling

The Scheduler implements fixed time quanta, context switching, CPU usage tracking, usage decay when idle, and overload protection.

If total CPU usage approaches a defined threshold, the kernel throws CPU_OVERLOAD and rejects new processes.

System stability is enforced at the kernel level.

Memory Management (First-Fit + Fragmentation)

The MemoryManager uses first-fit allocation, treats memory as contiguous blocks, merges only adjacent free segments, and simulates external fragmentation.

You can create real "Swiss cheese" memory states. Even if total free memory is technically sufficient, a process may fail if no contiguous block is large enough.

This introduces realistic allocation constraints inside a browser environment that normally hides them.

Block-Based Storage System

Below the file system sits a simulated disk: fixed-size blocks, explicit allocation + deallocation, no awareness of filenames, no awareness of directories.

The disk only understands raw blocks. All higher-level structure is built above it.

The Inode-Based File System

Instead of storing files as simple path-based objects, WebOS implements a Unix-inspired inode model.

Identity ≠ Path

Each file has a unique inode ID, logical size, file type, and a list of allocated disk blocks.

Directories do not store file data. They store: name → inodeId.

This creates three distinct layers: namespace (directory structure), identity (inode), physical storage (disk blocks).

What This Enables

Because identity is decoupled from path:

  • Renaming a file does not change its inode
  • Moving a file across directories does not reallocate storage
  • Recursive directory deletion is deterministic
  • Disk exhaustion properly blocks file growth
  • Directory relinking simulates Unix-style behaviour

The StorageSystem manages raw blocks. The FileSystem manages structure and identity. The Kernel enforces constraints.

Modelling this inside JavaScript required extremely clean abstraction boundaries.

Windowing System

The UI layer includes app registry (name → component mapping), generic <AppWindow /> wrapper, drag/resize via react-rnd, GSAP-driven transitions, and centralised z-index + focus handling.

Apps remain isolated. OS behaviour remains centralised.

Error Simulation & System Resilience

WebOS enforces realistic failure cases: OUT_OF_MEMORY, CPU_OVERLOAD, OUT_OF_STORAGE, file system related errors.

Errors originate in the kernel and propagate upward. The UI reacts, it never simulates failure independently.

This preserves architectural integrity.

What This Project Changed for Me

The hardest part wasn't building UI. It was maintaining invariant rules across independent subsystems: memory consistency, scheduler fairness, file system integrity, correct resource cleanup.

If one invariant breaks, the illusion collapses.

It blurred the line between frontend engineering and systems design.

What's Next

Terminal emulator, app installer system, access control simulation, expanded kernel APIs, UI overhaul after feature freeze.

GitHub: Mukund149/Web-Based_Operating-System

T
Written by TheVibeish Editorial