Files
rust_browser/docs/browser_project_structure_modularization_guide.md
Zachary D. Rowitsch af024d8bd2 Initial commit
2026-01-28 21:41:46 -05:00

5.5 KiB
Raw Permalink Blame History

Browser Project Structure & Modularization Guide

Purpose of this Document

This document provides tactical, technical guidance for structuring the browser codebase as a Rust monorepo. It complements the higher-level architecture document by focusing on:

  • Concrete crate layout
  • Dependency and layering rules
  • Patterns that keep modules extractable
  • Constraints that make AI-assisted development safe and scalable

This document is intentionally opinionated.

Design Goals

  1. Monorepo convenience, library-quality modularity
  2. Clear ownership and boundaries between subsystems
  3. Low cognitive load for humans and AI agents
  4. Future extraction of complex subsystems without rewrites
  5. Minimal use of unsafe, isolated by design

High-Level Workspace Structure

The project is a single Cargo workspace with many small, focused crates.

/Cargo.toml                # workspace root
/crates
  /app_browser              # binary: macOS/Linux desktop shell
  /browser_runtime          # tabs, navigation, session/history, permissions
  /web_api                  # JS<->DOM boundary and host bindings

  /js                       # JS engine public facade
  /js_vm                    # interpreter, runtime, GC integration
  /js_parser                # JS tokenizer/parser

  /dom                      # DOM tree, mutation, events
  /html                     # HTML tokenizer/parser
  /css                      # CSS tokenizer/parser + OM
  /selectors                # CSS selector matching
  /style                    # cascade and computed styles
  /layout                   # layout tree and algorithms
  /display_list             # normalized drawing commands
  /render                   # display list execution (CPU-first)
  /graphics                 # graphics backend abstractions

  /net                      # fetch, cache, cookies, HTTP state machines
  /storage                  # persistent storage plumbing
  /image                    # image decode pipeline
  /fonts                    # font loading and shaping (later)

  /platform                 # macOS/Linux OS integration
  /shared                   # common utilities, types, errors
/tests
  /wpt_harness              # Web Platform Tests runner
  /goldens                  # golden pages + expected dumps
/tools
  /repro_minimizer          # shrinking failing test cases
  /triage                   # crash and flake analysis tools

Many crates may start out nearly empty; their value is in defining boundaries early.

Layering and Dependency Rules

Dependency Direction

Crates must only depend downward:

app_browser
  ↓
browser_runtime
  ↓
engine crates (web_api, dom, style, layout, render, net, js)
  ↓
shared

Rules:

  • app_browser owns the desktop UI and event loop glue.
  • Engine crates must never depend on app_browser or UI concepts.
  • Platform-specific code lives in platform and is accessed via narrow adapters.

Crate Responsibilities (Selected Highlights)

app_browser

  • Window creation
  • Input event capture
  • Platform event loop integration
  • Wiring everything together

No browser logic lives here.

browser_runtime

  • Tabs and browsing contexts
  • Navigation lifecycle
  • Session and history management
  • Permissions and security policy decisions

js / js_vm / js_parser

  • js: stable public API used by the browser
  • js_vm: interpreter, execution state, GC hooks
  • js_parser: tokenizer and parser only

Design rule: the interpreter is the semantic oracle for future JITs.

DOM / Style / Layout / Rendering

  • dom: tree structure, mutation, events
  • style: selector matching + cascade
  • layout: box tree and layout algorithms
  • display_list: backend-agnostic paint representation
  • render: executes display list

These crates must remain platform-agnostic and testable in isolation.

Patterns That Enable Future Extraction

Prefer IDs over Borrows

Across crate boundaries:

  • Use NodeId, StyleId, LayoutId, etc.
  • Store data in arenas inside each crate
  • Expose explicit query/mutation APIs

This avoids lifetime coupling and simplifies APIs.

Phase-Based Mutation

Structure work in explicit phases:

parse → build DOM → style → layout → paint

Each phase produces a stable representation consumed by the next.

Platform Abstraction via Traits

Core crates depend on traits like:

  • Clock
  • NetworkProvider
  • FontProvider
  • ImageDecoder

Implemented by platform or app_browser.

unsafe Usage Policy

Default: no unsafe.

Allowed only in:

  • OS bindings (platform)
  • Graphics backends (graphics)
  • Future performance islands (e.g., JIT, SIMD)

Every unsafe block must:

  • document invariants
  • have targeted tests
  • be covered by fuzzing where applicable

AI-Agent-Friendly Constraints

To maximize safe agent contribution:

  • Keep core execution single-threaded early
  • Prefer simple data structures over clever ones
  • Enforce tests for every change
  • Use compiler errors and tests as the primary feedback loop

Rusts type system and this structure together act as guardrails.

What This Document Is Not

  • A final architecture
  • A performance roadmap
  • A commitment to specific libraries or backends

Those decisions will follow from experimentation and testing.

Expected Evolution

As the project grows:

  • Some crates may merge or split
  • Certain crates may be extracted into external libraries
  • Additional layers (JIT, compositor threads, sandboxing) will be added

The constraints in this document are intended to make those changes incremental, not disruptive.