198 lines
5.5 KiB
Markdown
198 lines
5.5 KiB
Markdown
# 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
|
||
|
||
Rust’s 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.
|
||
|