Skip to main content

Crate oxide_docs

Crate oxide_docs 

Source
Expand description

§Oxide — The Binary-First WebAssembly Browser

https://docs.oxide.foundation

Oxide is a binary-first browser that fetches and executes .wasm (WebAssembly) modules instead of HTML/JavaScript. Guest applications run in a secure sandbox with zero access to the host filesystem, environment variables, or raw network sockets. The browser exposes a rich set of capability APIs that guest modules import to interact with the host.

The desktop shell is built on GPUI (Zed’s GPU-accelerated UI framework). Guest draw commands map directly onto GPUI primitives — filled quads, GPU-shaped text, vector paths, and image textures — giving your canvas output full hardware acceleration.

§Crate Map

CratePurposeAudience
oxide_sdkGuest SDK — safe Rust wrappers for the "oxide" host importsApp developers
oxide_browserHost runtime — Wasmtime engine, sandbox, GPUI shellBrowser contributors

§Quick Start — Building a Guest App

# Cargo.toml
[package]
name = "my-oxide-app"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
oxide-sdk = "0.6"

§Static app (one-shot render)

use oxide_sdk::*;

#[no_mangle]
pub extern "C" fn start_app() {
    log("Hello from Oxide!");
    canvas_clear(30, 30, 46, 255);
    canvas_text(20.0, 40.0, 28.0, 255, 255, 255, 255, "Welcome to Oxide");
}

§Interactive app (frame loop with widgets)

use oxide_sdk::*;

#[no_mangle]
pub extern "C" fn start_app() { log("Ready"); }

#[no_mangle]
pub extern "C" fn on_frame(_dt_ms: u32) {
    canvas_clear(30, 30, 46, 255);
    let (mx, my) = mouse_position();
    canvas_circle(mx, my, 20.0, 255, 100, 100, 255);
    if ui_button(1, 20.0, 20.0, 100.0, 30.0, "Click me!") {
        log("Clicked!");
    }
}

§High-level drawing API

use oxide_sdk::draw::*;

#[no_mangle]
pub extern "C" fn start_app() {
    let c = Canvas::new();
    c.clear(Color::hex(0x1e1e2e));
    c.fill_rect(Rect::new(10.0, 10.0, 200.0, 100.0), Color::rgb(80, 120, 200));
    c.fill_circle(Point2D::new(300.0, 200.0), 50.0, Color::RED);
    c.text("Hello!", Point2D::new(20.0, 30.0), 24.0, Color::WHITE);
}

Build and run:

cargo build --target wasm32-unknown-unknown --release
# Open Oxide browser → navigate to your .wasm file

§Architecture Overview

┌─────────────────────────────────────────────────────┐
│                    Oxide Browser                    │
│                                                     │
│  ┌──────────┐  ┌────────────┐  ┌──────────────────┐ │
│  │  URL Bar │  │   Canvas   │  │     Console      │ │
│  └────┬─────┘  └──────┬─────┘  └──────┬───────────┘ │
│       │               │               │             │
│  ┌────▼───────────────▼───────────────▼──────────┐  │
│  │              Host Runtime (oxide-browser)      │  │
│  │  Wasmtime engine · sandbox policy             │  │
│  │  fuel: 500M instructions · memory: 256 MB     │  │
│  └────────────────────┬──────────────────────────┘  │
│                       │                             │
│  ┌────────────────────▼──────────────────────────┐  │
│  │          Capability Provider                  │  │
│  │  "oxide" wasm import module                   │  │
│  │  canvas · gpu · audio · video · capture       │  │
│  │  fetch · streaming · websocket · webrtc · midi │  │
│  │  timers · animation frames · navigation       │  │
│  │  console · storage · clipboard · widgets      │  │
│  │  input · hyperlinks · crypto · protobuf       │  │
│  └────────────────────┬──────────────────────────┘  │
│                       │                             │
│  ┌────────────────────▼──────────────────────────┐  │
│  │           Guest .wasm Module (oxide-sdk)       │  │
│  │  exports: start_app(), on_frame(dt_ms)        │  │
│  │  imports: oxide::*                            │  │
│  └───────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘

§Guest SDK API Reference

The oxide_sdk crate provides the full guest-side API. All functions are available via use oxide_sdk::*;.

§High-Level Drawing API (oxide_sdk::draw)

The oxide_sdk::draw module provides GPUI-inspired ergonomic types that wrap the low-level canvas functions with less boilerplate:

TypeDescription
oxide_sdk::draw::ColorsRGB + alpha with named constants and hex() constructor
oxide_sdk::draw::Point2D2D point in canvas coordinates
oxide_sdk::draw::RectAxis-aligned rectangle with hit-testing
oxide_sdk::draw::CanvasZero-cost drawing facade
use oxide_sdk::draw::*;

let c = Canvas::new();
c.clear(Color::hex(0x1e1e2e));
c.fill_rect(Rect::new(10.0, 10.0, 200.0, 100.0), Color::rgb(80, 120, 200));
c.fill_circle(Point2D::new(300.0, 200.0), 50.0, Color::RED);
c.text("Hello!", Point2D::new(20.0, 30.0), 24.0, Color::WHITE);
c.line(Point2D::ZERO, Point2D::new(400.0, 300.0), 2.0, Color::YELLOW);
let (w, h) = c.dimensions();

§Low-Level Canvas Drawing

The canvas is the main rendering surface. Coordinates start at (0, 0) in the top-left corner. Each draw command maps to a GPUI GPU primitive.

FunctionDescription
oxide_sdk::canvas_clearClear canvas with a solid RGBA color
oxide_sdk::canvas_rectDraw a filled rectangle
oxide_sdk::canvas_circleDraw a filled circle
oxide_sdk::canvas_textDraw text at a position
oxide_sdk::canvas_lineDraw a line between two points
oxide_sdk::canvas_dimensionsGet canvas (width, height) in pixels
oxide_sdk::canvas_imageDraw an encoded image (PNG, JPEG, GIF, WebP)
use oxide_sdk::*;

canvas_clear(30, 30, 46, 255);
canvas_rect(10.0, 10.0, 200.0, 100.0, 80, 120, 200, 255);
canvas_circle(300.0, 200.0, 50.0, 200, 100, 150, 255);
canvas_text(20.0, 30.0, 24.0, 255, 255, 255, 255, "Hello!");
canvas_line(0.0, 0.0, 400.0, 300.0, 255, 200, 0, 255, 2.0);

let (w, h) = canvas_dimensions();
log(&format!("Canvas: {}x{}", w, h));

§Console Logging

FunctionDescription
oxide_sdk::logPrint an informational message
oxide_sdk::warnPrint a warning (yellow)
oxide_sdk::errorPrint an error (red)

§HTTP Networking

All network access is mediated by the host — the guest never opens raw sockets. Protocol Buffers is the native wire format.

FunctionDescription
oxide_sdk::fetchFull HTTP request with method, headers, body
oxide_sdk::fetch_getHTTP GET shorthand
oxide_sdk::fetch_postHTTP POST with content-type and body
oxide_sdk::fetch_post_protoHTTP POST with protobuf body
oxide_sdk::fetch_putHTTP PUT
oxide_sdk::fetch_deleteHTTP DELETE
use oxide_sdk::*;

let resp = fetch_get("https://api.example.com/data").unwrap();
log(&format!("Status: {}, Body: {}", resp.status, resp.text()));

§Protobuf — Native Data Format

The oxide_sdk::proto module provides a zero-dependency protobuf encoder/decoder compatible with the Protocol Buffers wire format.

use oxide_sdk::proto::{ProtoEncoder, ProtoDecoder};

let msg = ProtoEncoder::new()
    .string(1, "alice")
    .uint64(2, 42)
    .bool(3, true)
    .finish();

let mut decoder = ProtoDecoder::new(&msg);
while let Some(field) = decoder.next() {
    match field.number {
        1 => log(&format!("name = {}", field.as_str())),
        2 => log(&format!("age  = {}", field.as_u64())),
        _ => {}
    }
}

§Storage

FunctionDescription
oxide_sdk::storage_setStore a key-value pair (session-scoped)
oxide_sdk::storage_getRetrieve a value by key
oxide_sdk::storage_removeDelete a key
oxide_sdk::kv_store_setPersistent on-disk KV store
oxide_sdk::kv_store_getRead from persistent KV store
oxide_sdk::kv_store_deleteDelete from persistent KV store

§Audio

FunctionDescription
oxide_sdk::audio_playPlay audio from encoded bytes (WAV, MP3, OGG, FLAC)
oxide_sdk::audio_play_urlFetch audio from a URL and play it
oxide_sdk::audio_play_with_formatPlay with a format hint
oxide_sdk::audio_detect_formatSniff container from magic bytes
oxide_sdk::audio_pause / oxide_sdk::audio_resume / oxide_sdk::audio_stopPlayback control
oxide_sdk::audio_set_volume / oxide_sdk::audio_get_volumeVolume control (0.0 – 2.0)
oxide_sdk::audio_is_playingCheck playback state
oxide_sdk::audio_position / oxide_sdk::audio_seek / oxide_sdk::audio_durationSeek and position
oxide_sdk::audio_set_loopEnable/disable looping
oxide_sdk::audio_channel_playMulti-channel simultaneous playback

§Video

Video decoding uses FFmpeg on the host. Frames are rendered as GPUI textures for GPU-accelerated compositing.

§Media Capture

The host shows permission dialogs before granting access to hardware.

§Timers

Timer callbacks fire via the guest-exported on_timer(callback_id) function.

FunctionDescription
oxide_sdk::set_timeoutOne-shot timer after a delay
oxide_sdk::set_intervalRepeating timer at an interval
oxide_sdk::clear_timerCancel a timer
oxide_sdk::time_now_msCurrent time (ms since UNIX epoch)

§Animation Frames

Vsync-aligned callbacks for smooth rendering. Callbacks fire via the guest-exported on_timer(callback_id) function (the same export used by oxide_sdk::set_timeout), one-shot per request.

FunctionDescription
oxide_sdk::request_animation_frameSchedule a one-shot frame callback
oxide_sdk::cancel_animation_frameCancel a pending request

§Streaming HTTP

Non-blocking variant of oxide_sdk::fetch that streams the response body back to the guest in chunks. Returns immediately with a handle; poll oxide_sdk::fetch_state and oxide_sdk::fetch_recv each frame.

FunctionDescription
oxide_sdk::fetch_beginDispatch a streaming request, returns a handle
oxide_sdk::fetch_begin_getGET shorthand
oxide_sdk::fetch_statePoll lifecycle state (FETCH_* constants)
oxide_sdk::fetch_statusHTTP status code, or 0 until headers arrive
oxide_sdk::fetch_recvPoll the next body chunk as a oxide_sdk::FetchChunk
oxide_sdk::fetch_recv_intoPoll into a caller-provided buffer (no allocation)
oxide_sdk::fetch_errorRetrieve the error message for a failed request
oxide_sdk::fetch_abortCancel an in-flight request

§WebSocket

Long-lived bidirectional connections. Messages are queued on the host and drained by the guest each frame via oxide_sdk::ws_recv.

FunctionDescription
oxide_sdk::ws_connectOpen a WebSocket, returns a handle
oxide_sdk::ws_ready_statePoll state (oxide_sdk::WS_OPEN, etc.)
oxide_sdk::ws_send_textSend a UTF-8 text frame
oxide_sdk::ws_send_binarySend a binary frame
oxide_sdk::ws_recvPop the next oxide_sdk::WsMessage from the queue
oxide_sdk::ws_closeInitiate the close handshake
oxide_sdk::ws_removeFree host resources after close completes

§MIDI Devices

Read and write MIDI messages on hardware controllers and synthesisers. Each input port maintains a bounded queue; long SysEx packets are split.

FunctionDescription
oxide_sdk::midi_input_count / oxide_sdk::midi_output_countEnumerate ports
oxide_sdk::midi_input_name / oxide_sdk::midi_output_nameLook up port names
oxide_sdk::midi_open_input / oxide_sdk::midi_open_outputOpen a port, returns a handle
oxide_sdk::midi_sendSend raw MIDI bytes to an output
oxide_sdk::midi_recvPop the next packet from an input queue
oxide_sdk::midi_closeClose a port

§GPU

WebGPU-style API for GPU-backed buffers, textures, shaders, and pipelines. Shader source is WGSL.

FunctionDescription
oxide_sdk::gpu_create_bufferAllocate a GPU buffer
oxide_sdk::gpu_create_textureAllocate a 2D texture
oxide_sdk::gpu_create_shaderCompile a WGSL shader module
oxide_sdk::gpu_create_pipelineBuild a render pipeline
oxide_sdk::gpu_create_compute_pipelineBuild a compute pipeline
oxide_sdk::gpu_write_bufferUpload bytes into a buffer
oxide_sdk::gpu_drawIssue a draw call into a target texture
oxide_sdk::gpu_dispatch_computeDispatch a compute workgroup grid
oxide_sdk::gpu_destroy_buffer / oxide_sdk::gpu_destroy_textureRelease GPU resources
FunctionDescription
oxide_sdk::navigateNavigate to a new URL
oxide_sdk::push_statePush history entry (like pushState())
oxide_sdk::replace_stateReplace current history entry
oxide_sdk::get_urlGet current page URL
oxide_sdk::history_back / oxide_sdk::history_forwardNavigate history

§Input Polling

§Interactive Widgets

Widgets are rendered during the on_frame() loop:

FunctionDescription
oxide_sdk::ui_buttonClickable button, returns true when clicked
oxide_sdk::ui_checkboxCheckbox, returns current checked state
oxide_sdk::ui_sliderSlider, returns current value
oxide_sdk::ui_text_inputText input field, returns current text

§Crypto & Encoding

FunctionDescription
oxide_sdk::hash_sha256SHA-256 hash (32-byte array)
oxide_sdk::hash_sha256_hexSHA-256 hash (hex string)
oxide_sdk::base64_encode / oxide_sdk::base64_decodeBase64 encoding/decoding

§Other APIs

FunctionDescription
oxide_sdk::clipboard_write / oxide_sdk::clipboard_readSystem clipboard access
oxide_sdk::random_u64 / oxide_sdk::random_f64Cryptographic random numbers
oxide_sdk::notifySend a notification
oxide_sdk::upload_fileOpen native file picker
oxide_sdk::get_locationMock geolocation
oxide_sdk::load_moduleDynamically load another .wasm module
oxide_sdk::register_hyperlink / oxide_sdk::clear_hyperlinksCanvas hyperlinks
oxide_sdk::url_resolve / oxide_sdk::url_encode / oxide_sdk::url_decodeURL utilities

§Browser Internals

The oxide_browser crate contains the host-side implementation. Key modules for contributors:


§Guest Module Contract

Every .wasm module loaded by Oxide must:

  1. Export start_appextern "C" fn() entry point called on load
  2. Optionally export on_frameextern "C" fn(dt_ms: u32) for interactive apps with a render loop
  3. Optionally export on_timerextern "C" fn(callback_id: u32) to receive timer callbacks
  4. Import from "oxide" — all host APIs live under this namespace
  5. Compile as cdylibcrate-type = ["cdylib"] in Cargo.toml
  6. Target wasm32-unknown-unknown — no WASI, pure capability-based

§Security Model

ConstraintValuePurpose
Filesystem accessNoneGuest cannot read/write host files
Environment variablesNoneGuest cannot inspect host env
Raw network socketsNoneAll networking is mediated via fetch
Memory limit256 MB (4096 pages)Prevents memory exhaustion
Fuel limit500M instructionsPrevents infinite loops / DoS
No WASIZero implicit system access

Re-exports§

pub use oxide_browser;
pub use oxide_sdk;