Skip to content

About

A full-featured IDE that runs entirely in your browser.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

BrowserLab

BrowserLab is a full-featured, browser-based IDE that executes JavaScript, Python, and WebAssembly entirely in the browser using Web Workers, Pyodide, and native WebAssembly APIs — no server required. It features a virtual file system, package management, performance monitoring, and drag-and-drop file uploads.

Developed by Kautilya Reddy Racha


Table of Contents

  1. Architecture Overview
  2. Getting Started
  3. Project Structure
  4. Phase 1 — Monaco Editor & JavaScript Sandbox
  5. Phase 2 — Virtual File System (VFS)
  6. Phase 3 — WebAssembly Runtime
  7. Phase 4 — Python via Pyodide
  8. Phase 5 — Unified Multi-Language Runtime Abstraction
  9. Phase 6 — Execution Sandboxing & Resource Management
  10. Phase 7 — Package & Dependency Management
  11. Phase 8 — Performance Optimization & Monitoring
  12. React UI Layer
  13. Configuration Reference
  14. API Reference
  15. Data Flow Diagrams
  16. IndexedDB Schema Reference
  17. Security Model
  18. Build & Deployment

1. Architecture Overview

BrowserLab runs 100% client-side. All code execution happens in the browser via Web Workers and WebAssembly — zero backend required.

┌─────────────────────────────────────────────────────────┐
│                     React UI Layer                       │
│  Root.tsx → HomePage / App.tsx, Components, Hooks        │
├──────────┬──────────┬───────────┬────────────┬──────────┤
│   VFS    │ Runtime  │   Deps    │    Perf    │  Home    │
│  Module  │ Manager  │  Manager  │  Manager   │  Page    │
├──────────┴──────────┴───────────┴────────────┴──────────┤
│              Web Workers / Service Worker                 │
│    sandbox.worker.ts  │  python.worker.ts  │  cache-sw   │
├─────────────────────────────────────────────────────────┤
│                   Browser APIs                           │
│  IndexedDB  │  WebAssembly  │  Cache API  │  Drag & Drop │
└─────────────────────────────────────────────────────────┘

Technology Stack

Layer Technology
Build tool Vite 7.3.1
UI Framework React 19.2.0
Language TypeScript ~5.9.3 (strict mode)
Code Editor Monaco Editor 0.55.1 (@monaco-editor/react 4.7.0)
Python Runtime Pyodide 0.26.4 (CDN)
Persistence IndexedDB (3 databases)
Caching Service Worker (Cache API) + in-memory LRU
Deployment Vercel (static)

2. Getting Started

Prerequisites

  • Node.js 20+ and npm

Installation

git clone <repo-url>
cd BrowserLab
npm install

Development

npm run dev           # Vite dev server with HMR

Build

npm run build         # TypeScript check + Vite build
npm run preview       # Preview production build

Deploy to Vercel

The project includes a vercel.json with proper SPA routing and COOP/COEP headers for Pyodide/WASM:

# Push to GitHub, then import in Vercel — auto-detects Vite
# Or use the Vercel CLI:
npx vercel

Available Scripts

Script Description
dev Vite dev server with HMR
build tsc -b && vite build
preview Preview production build
lint ESLint check

3. Project Structure

BrowserLab/
├── index.html                 # Entry HTML
├── package.json               # Dependencies & scripts
├── vercel.json                # Vercel deployment config (SPA + COOP/COEP headers)
├── vite.config.ts             # Vite configuration
├── tsconfig.json              # Root TypeScript config
├── tsconfig.app.json          # App TypeScript config (src/)
├── tsconfig.node.json         # Node TypeScript config
├── eslint.config.js           # ESLint configuration
├── public/
│   ├── cache-sw.js            # Service worker (3 caching strategies)
│   └── vite.svg               # Favicon
├── src/
│   ├── main.tsx               # React entry point → Root
│   ├── Root.tsx               # Page router (HomePage ↔ Editor)
│   ├── App.tsx                # Editor layout (Toolbar + Sidebar + Editor + Console)
│   ├── App.css                # Global styles
│   ├── index.css              # Base styles / CSS variables
│   ├── types.ts               # Shared UI types (ConsoleEntry, WorkerResponse)
│   ├── vfs/                   # Virtual File System
│   │   ├── types.ts           # VFSNode, VFSProject, IFileSystem
│   │   ├── VirtualFileSystem.ts # In-memory IFileSystem implementation
│   │   ├── persistence.ts     # IndexedDB CRUD operations
│   │   └── index.ts           # Barrel exports
│   ├── runtime/               # Multi-language runtime engine
│   │   ├── types.ts           # RuntimeType, IRuntime, ExecutionRequest
│   │   ├── BaseRuntime.ts     # Abstract base with state machine
│   │   ├── JavaScriptRuntime.ts # Web Worker sandbox execution
│   │   ├── WasmRuntime.ts     # WAT compiler + WASM execution
│   │   ├── PythonRuntime.ts   # Pyodide worker execution
│   │   ├── RuntimeManager.ts  # Central orchestrator & dispatcher
│   │   ├── ResourceMonitor.ts # Real-time resource tracking
│   │   ├── ExecutionGuard.ts  # Auto-terminate on resource breach
│   │   ├── errors.ts          # Error normalization per language
│   │   ├── wat-compiler.ts    # WAT → WASM binary compiler
│   │   ├── index.ts           # Barrel exports
│   │   └── hybrid/            # Execution routing
│   │       ├── types.ts       # DispatchPolicy, protocol types
│   │       ├── CodeAnalyzer.ts # Pattern-based code analysis
│   │       ├── FallbackDispatcher.ts # Local routing decision engine
│   │       └── index.ts
│   ├── deps/                  # Package & dependency management
│   │   ├── types.ts           # PackageSpec, PackageRecord, IPackageResolver
│   │   ├── DependencyManager.ts # Central orchestrator
│   │   ├── DependencyValidator.ts # Code analysis + manifest bridging
│   │   ├── PackageCache.ts    # IndexedDB package persistence
│   │   ├── index.ts
│   │   └── resolvers/
│   │       ├── JavaScriptResolver.ts  # esm.sh CDN resolver
│   │       ├── PythonResolver.ts      # Pyodide/micropip resolver
│   │       ├── WasmResolver.ts        # WASM package resolver
│   │       └── index.ts
│   ├── perf/                  # Performance monitoring
│   │   ├── types.ts           # ProfileSpan, MetricPoint, CacheEntry, etc.
│   │   ├── PerformanceProfiler.ts # Span-based profiling engine
│   │   ├── IntelligentCache.ts    # 2-tier LRU/LFU/TTL cache
│   │   ├── MetricsCollector.ts    # Time-series metrics aggregation
│   │   ├── PerformanceManager.ts  # Central facade
│   │   ├── serviceWorkerRegistration.ts # SW registration utilities
│   │   └── index.ts
│   ├── components/            # React UI components
│   │   ├── HomePage.tsx       # Landing page with feature cards
│   │   ├── HomePage.css       # Landing page styles
│   │   ├── CodeEditor.tsx     # Monaco editor wrapper
│   │   ├── ConsoleOutput.tsx  # Output display panel
│   │   ├── Toolbar.tsx        # Top bar with controls
│   │   ├── FileExplorer.tsx   # VFS file tree + drag-and-drop upload
│   │   ├── DependencyPanel.tsx # Package management UI
│   │   └── PerformancePanel.tsx   # 4-tab monitoring dashboard
│   ├── hooks/                 # React hooks
│   │   ├── useCodeExecution.ts # Runtime manager bridge
│   │   └── usePerformance.ts   # Performance manager bridge
│   ├── workers/               # Web Workers
│   │   ├── sandbox.worker.ts  # JavaScript sandbox
│   │   └── python.worker.ts   # Pyodide Python runtime + micropip
│   └── context/
│       └── VFSContext.tsx      # React Context for VFS + IndexedDB auto-save
└── server/                    # (Legacy — not used in serverless mode)
    └── src/
        ├── index.ts           # WebSocket execution server
        ├── container.ts       # Docker/subprocess execution
        ├── session.ts         # Session tracking
        ├── collab.ts          # Collaboration server
        └── warmPool.ts        # Container pre-warming pool

4. Phase 1 — Monaco Editor & JavaScript Sandbox

Overview

The foundation of BrowserLab: a Monaco-powered code editor with JavaScript execution in an isolated Web Worker sandbox.

Components

src/components/CodeEditor.tsx

Wraps @monaco-editor/react with:

  • Dynamic language detection from file extension
  • Keyboard shortcut Ctrl+Enter to trigger execution
  • Theme: vs-dark
  • Automatic layout on resize

src/workers/sandbox.worker.ts

A dedicated Web Worker that:

  1. Blocks dangerous globals — fetch, XMLHttpRequest, WebSocket, navigator, indexedDB, etc. are overridden with Object.defineProperty to throw on access
  2. Captures console output — console.log/warn/error/info are replaced with functions that post messages back to the main thread
  3. Executes code via new Function('console', code) — runs user code in the worker's isolated scope
  4. Timeout protection — a configurable timeout (default: 5000ms) kills execution of infinite loops
  5. Memory heartbeat — periodic performance.memory sampling (Chromium) posted to main thread

src/types.ts

Shared types for the worker protocol:

interface ConsoleEntry {
  id: string;
  type: 'log' | 'warn' | 'error' | 'info' | 'result' | 'system';
  content: string;
  timestamp: number;
}

interface WorkerResponse {
  type: 'console' | 'result' | 'error' | 'timeout';
  method?: string;
  content: string;
}

5. Phase 2 — Virtual File System (VFS)

Overview

An in-memory file system with IndexedDB persistence, supporting multi-file projects with tree structure.

Type System (src/vfs/types.ts)

type VFSNodeId = string;

interface VFSNode {
  id: VFSNodeId;
  name: string;
  type: 'file' | 'directory';
  parentId: VFSNodeId | null;   // null = root-level
  content: string;               // file content (empty for directories)
  language: string;              // inferred from extension
  createdAt: number;
  updatedAt: number;
}

interface VFSProject {
  id: string;
  name: string;
  nodes: Record<VFSNodeId, VFSNode>;
  activeFileId: VFSNodeId | null;
  createdAt: number;
  updatedAt: number;
}

VirtualFileSystem (src/vfs/VirtualFileSystem.ts)

Implements IFileSystem as a pure in-memory store backed by a VFSProject object. Key features:

  • Recursive path building for getProjectFiles()
  • inferLanguage() maps file extensions to Monaco language IDs
  • Node ID generation via timestamp + random suffix

Persistence (src/vfs/persistence.ts)

IndexedDB database: browserlab_vfs (version 1)

Operation Function
Save project saveProject(project: VFSProject)
Load project loadProject(id: string): VFSProject | null
List projects listProjects(): { id, name }[]
Delete project deleteProject(id: string)
Save default ID saveDefaultProjectId(id: string)
Get default ID getDefaultProjectId(): string | null

VFS Context (src/context/VFSContext.tsx)

React Context provider that:

  1. Loads the default project from IndexedDB on mount (or creates a starter project)
  2. Auto-saves to IndexedDB on every content change (debounced)
  3. Exposes useVFS() hook with: activeFile, activeFileId, updateFileContent, getActiveFileContent, getProjectFiles, selectFile, createFile, createDirectory, deleteNode, renameNode

Starter Project

On first launch, creates a default project with:

  • main.js — Hello World with example code
  • utils.js — Utility functions
  • math.wat — WebAssembly text format example
  • example.py — Python example
  • README.md — Project readme

6. Phase 3 — WebAssembly Runtime

Overview

Executes WebAssembly Text Format (WAT) code by compiling it to WASM binary and running it through the browser's native WebAssembly APIs.

WAT Compiler (src/runtime/wat-compiler.ts)

A hand-written WAT text → WASM binary compiler that:

  • Tokenizes WAT source into a token stream
  • Parses tokens into an AST (module → functions, exports, imports, memory, globals, data segments)
  • Emits valid WASM binary format with proper section encoding
  • Supports: i32, i64, f32, f64 types
  • Supports instructions: local.get/set/tee, global.get/set, arithmetic, comparisons, control flow (if/else/block/loop/br/br_if), memory operations, call, return, drop, select, etc.

WasmRuntime (src/runtime/WasmRuntime.ts)

Execution flow:

  1. Detect WAT format (must start with (module)
  2. Compile WAT → WASM binary via compileWat()
  3. Set up import object with console-like output functions
  4. Instantiate module via WebAssembly.compile() + WebAssembly.instantiate()
  5. Auto-execute: search for main, _start, run, _main entry points
  6. Timeout protection: 10 second limit

7. Phase 4 — Python via Pyodide

Overview

Python execution powered by Pyodide — a CPython interpreter compiled to WebAssembly, running in a dedicated Web Worker.

Python Worker (src/workers/python.worker.ts)

  1. Sandbox hardening — blocks dangerous globals (XMLHttpRequest, EventSource, indexedDB, caches, BroadcastChannel, SharedWorker). Allows importScripts, navigator, location (required by Pyodide internals).
  2. Lazy initialization — Pyodide loaded from https://cdn.jsdelivr.net/pyodide/v0.26.4/full/ on first execution
  3. stdout/stderr capture — py.setStdout() and py.setStderr() pipe Python output to the main thread
  4. VFS sync — project files written to Pyodide's emscripten filesystem at /project/ and added to sys.path
  5. Auto-import — py.loadPackagesFromImports(code) pre-loads required Pyodide-compatible packages
  6. micropip integration — pre-loaded; packages specified in ExecutionRequest.packages are installed from PyPI before execution
  7. Package installation — tries loadPackage() first (Pyodide builtins), then falls back to micropip.install() (pure-Python wheels from PyPI)

Pyodide-Compatible Packages

The following popular packages are available as Pyodide builtins (no micropip needed): numpy, scipy, pandas, matplotlib, scikit-learn, sympy, networkx, pillow, opencv-python, pyyaml, sqlalchemy, beautifulsoup4, lxml, regex, jinja2, astropy, biopython, and more.

PythonRuntime (src/runtime/PythonRuntime.ts)

  • Manages the worker lifecycle (create, execute, terminate, dispose)
  • Passes packages from ExecutionRequest to worker for pre-installation
  • Tracks Pyodide ready state — shows "loading" during initial interpreter download
  • Worker is reused across executions (Pyodide persists state between runs)
  • 60-second default execution timeout

8. Phase 5 — Unified Multi-Language Runtime Abstraction

Overview

A polymorphic runtime system that abstracts language differences behind a common interface.

Core Types (src/runtime/types.ts)

type RuntimeType = 'javascript' | 'wasm' | 'python';

type RuntimeState = 'idle' | 'loading' | 'running' | 'error' | 'terminated';

interface ExecutionRequest {
  code: string;
  files?: Record<string, string>;
  importMap?: Record<string, string>;
  packages?: string[];              // Python packages to install before execution
}

Runtime Registry

const AVAILABLE_RUNTIMES: Record<RuntimeType, RuntimeInfo> = {
  javascript: { id: 'javascript', label: 'JavaScript', extensions: ['js','jsx','ts','tsx','mjs'], icon: '🟨', isLocal: true },
  wasm:       { id: 'wasm',       label: 'WebAssembly', extensions: ['wat','wasm'], icon: '🟪', isLocal: true },
  python:     { id: 'python',     label: 'Python',      extensions: ['py'], icon: '🐍', isLocal: true },
};

inferRuntime(filename) maps file extensions to RuntimeType.

BaseRuntime (src/runtime/BaseRuntime.ts)

Abstract base class providing:

  • State machine — setState() with pub/sub notification
  • Memory heartbeat — optional memoryReportCallback forwarding
  • Dispose pattern — terminates, clears listeners, sets state to terminated

Error Normalization (src/runtime/errors.ts)

normalizeError(error, runtimeType) produces clean, user-friendly error messages:

  • JavaScript — strips Worker/sandbox internal stack frames
  • WASM — humanizes CompileError, LinkError, RuntimeError prefixes
  • Python — removes Pyodide internal frames, remaps file references

RuntimeManager (src/runtime/RuntimeManager.ts)

The central orchestrator managing all execution:

Key Features:

  • Instance caching and reuse (Python worker persists Pyodide across runs)
  • All execution routes to local (remote is disabled by default)
  • Gathers Python packages from DependencyManager and passes via ExecutionRequest.packages
  • Stale-execution guards (monotonic executionId counter)
  • Output streaming with resource guarding
  • Error normalization
  • VFS file provision to runtimes
  • Performance profiling integration

Key Methods:

Method Description
execute(code, runtimeType) Main entry point — initializes and executes
terminate() Stops current execution on active runtime
switchRuntime(type) Changes active runtime without executing
setFileProvider(fn) Registers VFS file provider
setDependencyManager(dm) Attaches package manager
setPerformanceManager(pm) Attaches profiling
onOutput(cb) Subscribe to execution output
onStateChange(cb) Subscribe to runtime state changes
onResourceUpdate(cb) Subscribe to resource monitoring
dispose() Clean shutdown of all runtimes

9. Phase 6 — Execution Sandboxing & Resource Management

Resource Monitor (src/runtime/ResourceMonitor.ts)

Tracks per-runtime resource usage in real-time:

Default Resource Limits:

Limit JavaScript WASM Python
Max execution time 10s 30s 60s
Max memory 128 MB 256 MB 512 MB
Max output messages 10,000 10,000 10,000
Max output bytes 5 MB 5 MB 5 MB

Monitoring cycle:

  1. startTracking(runtimeId) — creates snapshot, starts 500ms interval timer
  2. Worker heartbeats feed recordMemory() for memory tracking
  3. Output callbacks feed recordOutput() for volume tracking
  4. Each tick checks time/memory/output limits and fires ResourceAlert on breach
  5. Safety sweep auto-stops stale trackers after 5 minutes

Execution Guard (src/runtime/ExecutionGuard.ts)

createGuardedOutput() wraps the output callback:

  • Records output volume per message
  • Listens for ResourceAlert events → emits warning → calls onTerminate()
  • Prevents double-termination

10. Phase 7 — Package & Dependency Management

Overview

CDN-backed package resolution, caching, and installation for JavaScript (esm.sh), Python (Pyodide/micropip), and WASM packages.

Package Flow

User adds package in DependencyPanel
       │
       ▼
DependencyManager.addPackage(spec)
       │
       ▼
Resolver.validate() → Resolver.resolve()
       │
       ├── JavaScriptResolver → esm.sh CDN URL
       ├── PythonResolver → Pyodide builtin check → PyPI JSON API
       └── WasmResolver → WASM package URL
       │
       ▼
PackageCache (IndexedDB)
       │
       ▼  (on execute)
RuntimeManager gathers packages
       │
       ▼
Worker installs via loadPackage() or micropip.install()

Resolvers

  • JavaScriptResolver — resolves via esm.sh CDN, generates import map entries
  • PythonResolver — classifies as Pyodide built-in or micropip package, validates against unsupported list (GPU libs, server frameworks, etc.), checks PyPI JSON API for pure-Python wheels
  • WasmResolver — resolves WASM package URLs

Dependency Manager (src/deps/DependencyManager.ts)

Method Description
addPackage(spec) Validate → resolve → cache → update manifest
removePackage(runtime, name) Remove from manifest
resolveAll() Re-resolve all pending/failed packages
getJavaScriptImportMap() CDN URLs for JS worker import maps
getPythonInstallList() { builtins: string[], micropip: string[] }

Package Cache (src/deps/PackageCache.ts)

IndexedDB database: browserlab_packages (version 1)


11. Phase 8 — Performance Optimization & Monitoring

Performance Profiler (src/perf/PerformanceProfiler.ts)

High-resolution span-based profiling with categories: execution, compile, pyodide-load, package-install, cache-hit, cache-miss, network, vfs-operation, etc.

Features:

  • Nested spans via span.startChild()
  • Cold vs. hot start tracking
  • Percentile analysis (p50, p95, p99)
  • Max 2000 spans (auto-evicts oldest)

Intelligent Cache (src/perf/IntelligentCache.ts)

Two-tier caching:

  • Tier 1: In-memory Map — instant access
  • Tier 2: IndexedDB (browserlab_perf_cache) — persisted across sessions

Eviction policies: LRU (default), LFU, TTL. Default: 100 MB, 500 entries, 24h TTL.

Metrics Collector (src/perf/MetricsCollector.ts)

Time-series metrics with auto-generated performance hints:

Trigger Hint
Execution > 5s Slow execution warning
Execution > 15s Critical slow execution
Worker init > 3s Slow worker initialization
Memory > 256MB High memory usage
Memory > 512MB Critical memory usage

Service Worker (public/cache-sw.js)

Intercepts network requests with three strategies:

Strategy Used For
Cache-first Pyodide CDN, WASM files, Monaco chunks
Network-first Frequently updated resources
Stale-while-revalidate esm.sh, unpkg, skypack packages

Cache name: browserlab-perf-v1, max entries: 200


12. React UI Layer

Page Flow

main.tsx → Root.tsx
              │
              ├── HomePage (landing page with feature cards)
              │        │
              │        └── "Open Editor" button → 350ms exit animation
              │
              └── VFSProvider → App.tsx (editor)

Home Page (src/components/HomePage.tsx)

Landing page shown before the editor:

  • Animated background grid with glowing orbs
  • Gradient title with shimmer animation
  • 6 feature cards (JavaScript, Python, WASM, VFS, Packages, Performance)
  • "Open Editor" CTA button with smooth transition
  • Developer credit footer
  • Fully responsive

App Component (src/App.tsx)

Editor layout wiring all hooks and panels:

  • Auto-detects runtime from active file extension
  • Global Ctrl+Enter keyboard shortcut for execution
  • Loading screen during initial VFS hydration
  • Layout: sidebar (FileExplorer, DependencyPanel, PerformancePanel) + CodeEditor + ConsoleOutput

Components

Component Description
HomePage Landing page with animated hero and feature cards
CodeEditor Monaco editor with language detection, dark theme
ConsoleOutput Scrollable output panel with color-coded entries
Toolbar Run/stop buttons, runtime selector, resource indicators
FileExplorer VFS tree with create/rename/delete + drag-and-drop file upload from PC
DependencyPanel Package search, add/remove, status indicators
PerformancePanel 4-tab dashboard: Health, Profiler, Cache, Hints

File Explorer — Drag & Drop

The FileExplorer supports dragging files from your local machine directly onto the panel:

  • Reads dropped files as text and creates them in the VFS
  • Auto-selects the last dropped file in the editor
  • Visual feedback: dashed border overlay with "Drop files here" message
  • Works with any text file (.js, .py, .json, .md, etc.)

Hooks

useCodeExecution(perfManager?)

Bridges RuntimeManager to React state:

  • Creates singleton RuntimeManager
  • Subscribes to output, state, resource, alert events
  • Initializes DependencyManager
  • Returns: entries, isRunning, runtimeState, resourceSnapshot, depManager, execute(), clearConsole(), terminateRuntime(), setFileProvider()

usePerformance()

Bridges PerformanceManager to React state:

  • Periodic summary refresh every 5 seconds
  • Returns: perfManager, health, hints, summary, cacheStats, recentSpans, refreshSummary(), clearMetrics(), clearCache()

13. Configuration Reference

Dispatch Policy (Client)

All execution is local by default:

const DEFAULT_DISPATCH_POLICY = {
  remoteEnabled: false,    // Cloud execution disabled
  preferLocal: true,       // Always prefer browser execution
  fallbackToLocal: true,
  confidenceThreshold: 0.6,
};

TypeScript Configuration

  • Target: ES2022
  • Module: ESNext with bundler resolution
  • Strict mode enabled
  • verbatimModuleSyntax: true
  • jsx: react-jsx

14. API Reference

VirtualFileSystem

class VirtualFileSystem implements IFileSystem {
  constructor(project: VFSProject)
  getProject(): VFSProject
  getNode(id: VFSNodeId): VFSNode | undefined
  getChildren(parentId: VFSNodeId | null): VFSNode[]
  createFile(parentId: VFSNodeId | null, name: string, content?: string): VFSNode
  createDirectory(parentId: VFSNodeId | null, name: string): VFSNode
  updateContent(id: VFSNodeId, content: string): void
  renameNode(id: VFSNodeId, newName: string): void
  deleteNode(id: VFSNodeId): void
  getProjectFiles(): Record<string, string>
}

RuntimeManager

class RuntimeManager {
  readonly monitor: ResourceMonitor

  setFileProvider(provider: () => Record<string, string>): void
  setDependencyManager(manager: DependencyManager): void
  setPerformanceManager(manager: PerformanceManager): void

  execute(code: string, runtimeType: RuntimeType): Promise<void>
  terminate(): void
  switchRuntime(type: RuntimeType): void

  onStateChange(cb: RuntimeStateChangeCallback): () => void
  onOutput(cb: RuntimeOutputCallback): () => void
  onResourceUpdate(cb: ResourceUpdateCallback): () => void
  onResourceAlert(cb: ResourceAlertCallback): () => void

  getState(type?: RuntimeType): RuntimeState
  getActiveType(): RuntimeType

  disposeRuntime(type: RuntimeType): void
  dispose(): void
}

DependencyManager

class DependencyManager {
  onEvent(cb: DependencyEventCallback): () => void
  getManifest(): DependencyManifest
  getPackagesForRuntime(runtime: RuntimeType): PackageRecord[]
  addPackage(spec: PackageSpec): Promise<PackageRecord>
  removePackage(runtime: RuntimeType, name: string): void
  resolveAll(): Promise<void>
  getJavaScriptImportMap(): Record<string, string>
  getPythonInstallList(): { builtins: string[]; micropip: string[] }
  dispose(): void
}

PerformanceManager

class PerformanceManager {
  readonly profiler: PerformanceProfiler
  readonly cache: IntelligentCache
  readonly metrics: MetricsCollector

  initialize(): Promise<void>
  startSpan(name, category, runtimeType?): ActiveSpan
  measure<T>(name, category, runtimeType, fn): Promise<T>
  getProfileSummary(): ProfileSummary
  recordMetric(name, value, unit, tags?): void
  getHealth(): SystemHealth
  getHints(): readonly PerformanceHint[]
  getCacheStats(): CacheStats
  dispose(): void
}

15. Data Flow Diagrams

Code Execution Flow

User clicks Run (or Ctrl+Enter)
       │
       ▼
  App.handleRun()
       │
       ▼
  useCodeExecution.execute(code, runtimeType)
       │
       ▼
  RuntimeManager.execute(code, runtimeType)
       │
       ├── Gather Python packages from DependencyManager
       │
       ├── getOrCreate(runtimeType)
       │         │
       │         ├── JavaScriptRuntime → sandbox.worker.ts → new Function()
       │         ├── WasmRuntime → wat-compiler → WebAssembly.instantiate()
       │         └── PythonRuntime → python.worker.ts → micropip.install() → Pyodide.runPythonAsync()
       │
       └── Output streams back to ConsoleOutput

Drag-and-Drop File Upload Flow

User drags files from PC onto FileExplorer
       │
       ▼
  onDrop handler → FileReader.readAsText()
       │
       ▼
  VFS.createFile(null, filename, content)
       │
       ▼
  setActiveFile(newFileId) → Monaco editor shows file

16. IndexedDB Schema Reference

browserlab_vfs (v1)

Store Key Path Purpose
projects id VFS project state
settings key Default project ID

browserlab_packages (v1)

Store Key Path Indexes Purpose
packages id runtime, expiresAt Cached package artifacts

browserlab_perf_cache (v1)

Store Key Path Indexes Purpose
cache_entries key category, lastAccessedAt, accessCount Performance cache entries

17. Security Model

Browser-Side Sandboxing

  1. Web Worker isolation — user code runs in dedicated workers, isolated from the main thread and DOM
  2. Blocked globals — dangerous APIs (fetch, XMLHttpRequest, WebSocket, EventSource, indexedDB, caches, BroadcastChannel) blocked via Object.defineProperty
  3. Code execution via new Function() — prevents access to worker's module scope
  4. Timeout protection — configurable per runtime (5s JS, 10s WASM, 60s Python)
  5. Resource limits — memory, output volume, and execution time caps with auto-termination
  6. COOP/COEP headers — Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: credentialless for SharedArrayBuffer support (configured in vercel.json)

Data Privacy

  • All persistence is local IndexedDB — no data leaves the browser
  • No analytics, no telemetry
  • Fully offline-capable after initial load

18. Build & Deployment

Production Build

npm run build
# Output: dist/ directory with optimized assets

Build stats: ~88 modules, ~2.4s build time

Vercel Deployment

The project includes vercel.json with:

  • Build command: npm run build
  • Output directory: dist
  • SPA routing: All non-asset paths rewrite to index.html
  • COOP/COEP headers: Required for Pyodide/WASM SharedArrayBuffer support
  • Credentialless COEP: Uses credentialless instead of require-corp so CDN resources (Pyodide, esm.sh) still load
{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "framework": "vite",
  "rewrites": [
    { "source": "/((?!assets/).*)", "destination": "/index.html" }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
        { "key": "Cross-Origin-Embedder-Policy", "value": "credentialless" }
      ]
    }
  ]
}

Deployment Steps

  1. Push to GitHub
  2. Import in Vercel — auto-detects Vite
  3. Click Deploy — that's it

Or via CLI:

npx vercel

Module Count

Module Group Count
VFS 4
Runtime (core + hybrid) 14
Dependencies 8
Performance 7
Components 8
Hooks 2
Workers 2
Context 1
Root files (main, Root, App, types) 4
Total ~88 modules

*BrowserLab — a 100% client-side browser IDE. Developed by Kautilya Reddy Racha & Dinesh Reddy Racha *

About

A full-featured IDE that runs entirely in your browser.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages