forge-host
The forge-host crate is the main runtime executable that runs Forge applications. It embeds the Deno runtime and manages native windows, IPC, and system integration.
Overview
forge-host is launched by forge dev or bundled into the final application. It handles:
- Deno runtime - Embeds JsRuntime for executing TypeScript/JavaScript
- Window management - Creates and manages native windows via tao/wry
- IPC bridge - Routes messages between Deno and WebView renderers
- Module loading - Resolves
host:*imports to extension modules - Asset serving - Serves
app://protocol from filesystem or embedded assets - Hot reload - WebSocket server for development hot module reload
Architecture
┌─────────────────────────────────────────────────────────────┐│ forge-host │├─────────────────────────────────────────────────────────────┤│ ┌─────────────────┐ ┌─────────────────────────────┐ ││ │ Deno JsRuntime │◄────►│ Event Loop (tao) │ ││ │ (app logic) │ │ (windows, menus, tray) │ ││ └────────┬────────┘ └──────────────┬──────────────┘ ││ │ │ ││ │ host:* ops │ WebView IPC ││ ▼ ▼ ││ ┌─────────────────┐ ┌─────────────────────────────┐ ││ │ Extensions │ │ WebView (wry) │ ││ │ fs,net,ui,ipc.. │ │ (renders app:// content) │ ││ └─────────────────┘ └─────────────────────────────┘ │└─────────────────────────────────────────────────────────────┘Module Loading
The ForgeModuleLoader handles module resolution:
host:*specifiers - Maps toext:host_*/init.js- TypeScript files - Transpiled via
deno_ast - JavaScript files - Loaded directly
- JSON files - Parsed as JSON modules
// host:window → ext:host_window/init.jsAsset Protocol
The app:// protocol serves web assets:
- Development mode: Files read from
{app_dir}/web/ - Production mode: Files embedded in binary via
build.rs
// app://index.html → {app_dir}/web/index.html// app://styles/main.css → {app_dir}/web/styles/main.cssEvent Loop
The main event loop (via tao) handles:
- Window events (close, resize, focus, move)
- Menu events (app menu, context menu)
- Tray events (click, menu selection)
- IPC messages (renderer → Deno)
- HMR events (file watcher → WebSocket)
Manifest
Applications are configured via manifest.app.toml:
[app]name = "My App"identifier = "com.example.myapp"version = "0.1.0"crash_reporting = true
[windows]width = 800height = 600resizable = true
[permissions]fs = { read = ["~/.myapp/*"], write = ["~/.myapp/*"] }Key Types
Manifest
Application configuration parsed from manifest.app.toml:
struct Manifest { app: App, windows: Option<Windows>, permissions: Option<Permissions>,}
struct App { name: String, identifier: String, version: String, crash_reporting: Option<bool>,}Preload Script
The preload script (from sdk/preload.ts) is injected into every WebView:
- Provides
window.host.send()andwindow.host.on()API - Bridges renderer to Deno via IPC
- Handles
__host_dispatchfor Deno → renderer messages
File Structure
crates/forge-host/├── src/│ ├── main.rs # Entry point, event loop, runtime setup│ ├── capabilities.rs # Permission system adapters│ └── crash.rs # Crash reporting├── build.rs # Asset embedding, preload compilation└── Cargo.tomlDependencies
| Dependency | Purpose |
|---|---|
deno_core | JavaScript runtime |
deno_ast | TypeScript transpilation |
tao | Window management, event loop |
wry | WebView rendering |
tokio | Async runtime |
notify | File watching (HMR) |
muda | Menu system |
tray-icon | System tray |
rfd | File dialogs |
Related
- forge - CLI that launches forge-host
- ext_window - Window management extension
- ext_ipc - IPC extension
- Architecture - Full system architecture