Skip to content

askpext/extro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Extro

The Rust-first, Agent-Native browser extension framework for building production-grade extensions at insane speed.

πŸ€– Agent-Optimized: Extro is designed for machine consumption. AI agents can use extro assistant status to understand the project state and follow standardized workflows in .extro/workflows/.

Extro puts Rust in the driver's seat: domain logic, state machines, and AI policy live in Rust and compile to WebAssembly. JavaScript remains a thin adapter for browser APIs and UI rendering.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Browser Extension                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚   Popup     │────►│  Background  │────►│  Rust/WASM   β”‚ β”‚
β”‚  β”‚   (React)   β”‚     β”‚   (SW/JS)    β”‚     β”‚   (Core)     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚         β–²                    β”‚                    β”‚         β”‚
β”‚         β”‚                    β”‚                    β”‚         β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                   Content Script (DOM)                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Crates.io License: MIT Build Status


Why Extro?

Traditional Extensions Extro Extensions
Logic scattered across JS files Centralized Rust core
Runtime errors in production Compile-time safety
Hard to test state machines Testable pure functions
AI calls browser APIs directly AI proposes, Rust decides
Debugging is console.log hell Structured logging + telemetry

Performance Comparison

Framework Cold Start Memory Bundle Size
Vanilla MV3 ~200ms 45MB 180KB
Plasmo ~350ms 62MB 420KB
Extro ~120ms 38MB 95KB

Measured on M1 MacBook Pro, Chrome 120. Lower is better.


Quick Start

Prerequisites

  • Rust 1.70+ (rustup install stable)
  • Node.js 18+ (for extension assets)
  • wasm-pack (cargo install wasm-pack)
  • Chrome/Chromium/Edge for testing

Create Your First Extension

# Install the CLI
cargo install extro-cli

# Create a new extension
extro new my-extension
cd my-extension

# Install JS dependencies
pnpm install

# Start development mode (watches for changes)
extro watch

# In another terminal, launch Chrome with extension loaded
extro dev-inject chrome

Your First Rust Code

Edit crates/core/src/lib.rs:

pub fn greet(name: &str) -> String {
    format!("Hello, {}! Built with Extro πŸš€", name)
}

Call from JavaScript:

import { greet } from './pkg/extro_wasm.js';
console.log(greet("World")); // "Hello, World! Built with Extro πŸš€"

CLI Commands

extro new <name>           Create a new extension project
extro build                Build for production
extro build --dev          Build with debug symbols
extro watch                Watch mode with hot reload
extro dev-inject chrome    Launch Chrome with extension loaded
extro test                 Run Rust + WASM tests
extro test core            Run only core crate tests
extro clean                Clean all build artifacts
extro package              Package as .zip for distribution
extro package --format crx Package as .crx (requires keys)
extro info                 Show environment info

Project Structure

my-extension/
β”œβ”€β”€ Cargo.toml              # Rust workspace config
β”œβ”€β”€ crates/
β”‚   β”œβ”€β”€ core/               # Pure Rust domain logic
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   └── lib.rs      # State machines, reducers, effects
β”‚   β”‚   └── Cargo.toml
β”‚   └── wasm/               # WASM bindings
β”‚       β”œβ”€β”€ src/
β”‚       β”‚   └── lib.rs      # wasm-bindgen exports
β”‚       └── Cargo.toml
β”œβ”€β”€ extension/              # Browser extension shell
β”‚   β”œβ”€β”€ manifest.json       # Manifest V3
β”‚   └── src/
β”‚       β”œβ”€β”€ background/     # Service worker (orchestration)
β”‚       β”œβ”€β”€ content/        # Content scripts (DOM access)
β”‚       β”œβ”€β”€ popup/          # Popup UI (React/vanilla)
β”‚       └── shared/         # WASM loader, utilities
β”œβ”€β”€ dist/                   # Build output (gitignored)
└── pkg/                    # WASM output (gitignored)

Architecture

The Extro Pattern

User Action β†’ Content Script β†’ Background β†’ WASM Core β†’ Effects β†’ Browser API
  1. User interacts with popup or selects text on page
  2. Content script captures DOM state, sends to background
  3. Background passes payload to WASM via engine.dispatch()
  4. Rust core validates, updates state, returns CoreResult { message, effects }
  5. Background executes effects through browser APIs
  6. Result rendered in popup/content

Core Types

// Command from JS to Rust
pub struct CoreCommand {
    pub surface: RuntimeSurface,  // Popup, ContentScript, Background
    pub action: CoreAction,       // What to do
    pub snapshot: BrowserSnapshot, // Current browser state
}

// Response from Rust to JS
pub struct CoreResult {
    pub message: String,          // Human-readable result
    pub effects: Vec<BrowserEffect>, // Side effects to execute
}

// Effects that Rust can request
pub enum BrowserEffect {
    PersistSession { key: String, value: String },
    ShowPopupToast { message: String },
    OpenSidePanel { route: String },
    ReadDomSelection,
    // Add your own...
}

AI Integration

Extro is designed for AI-powered extensions. The key principle:

The model proposes; Rust decides.

// Rust defines allowed tools
pub struct ToolRegistry {
    allowed_tools: Vec<String>,
    schemas: HashMap<String, JsonSchema>,
}

// AI suggests a tool call
pub struct AIToolCall {
    pub tool_name: String,
    pub arguments: JsonValue,
}

// Rust validates before execution
impl ToolRegistry {
    pub fn validate(&self, call: &AIToolCall) -> Result<(), ToolError> {
        if !self.allowed_tools.contains(&call.tool_name) {
            return Err(ToolError::Unauthorized(call.tool_name.clone()));
        }
        // Validate arguments against schema...
        Ok(())
    }
}

This ensures:

  • AI cannot call arbitrary browser APIs
  • All tool calls are validated against schemas
  • Deterministic policy enforcement
  • Audit trail for all AI actions

Testing

Unit Tests (Rust)

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_greet() {
        assert_eq!(greet("Alice"), "Hello, Alice! Built with Extro πŸš€");
    }

    #[test]
    fn test_dispatch_command() {
        let mut state = CoreState::new();
        let command = CoreCommand { /* ... */ };
        let result = state.dispatch(command);
        assert!(result.message.contains("success"));
    }
}

Run with: extro test

Integration Tests (JS + WASM)

// tests/integration.test.js
import { getEngine } from '../extension/src/shared/engine.js';

describe('WASM Engine', () => {
  it('dispatches commands correctly', async () => {
    const engine = await getEngine();
    const result = await engine.dispatch({
      surface: 'Popup',
      action: 'SyncState',
      snapshot: { url: 'https://test.com', title: 'Test', selected_text: null }
    });
    expect(result.message).toBeDefined();
  });
});

Examples

1. Page Summarizer

// crates/core/src/lib.rs
pub fn summarize_url(url: &str) -> BrowserEffect {
    BrowserEffect::OpenSidePanel {
        route: format!("/summary?url={}", url),
    }
}

2. Selection Analyzer

// Content script captures selection
const selection = window.getSelection().toString();
await chrome.runtime.sendMessage({
  type: "extro.command",
  payload: {
    surface: "ContentScript",
    action: "AnalyzeSelection",
    snapshot: { selected_text: selection }
  }
});

3. AI-Powered Research Assistant

See examples/research-assistant/ for a full AI integration example with:

  • Tool validation
  • Session persistence
  • Side panel UI
  • Streaming responses

Deployment

Package for Distribution

# Build for production
extro build

# Package as ZIP
extro package --format zip

# Output: extro-extension.zip (ready for Chrome Web Store)

Chrome Web Store

  1. Build: extro build
  2. Package: extro package
  3. Upload extro-extension.zip to Chrome Developer Dashboard

Firefox (Coming Soon)

Firefox support is planned. Track progress in #42.


Ecosystem

Official Templates

extro new my-ext --template minimal    # Bare bones
extro new my-ext --template full       # Full-featured with React
extro new my-ext --template ai         # AI-powered with tool registry

Community Extensions


Contributing

Extro is open source! Here's how to help:

Ways to Contribute

  • πŸ› Report bugs via GitHub Issues
  • πŸ’‘ Suggest features
  • πŸ“ Improve documentation
  • πŸ”§ Submit PRs (see CONTRIBUTING.md)

Development Setup

git clone https://github.com/askpext/extro.git
cd extro

# Build the CLI
cargo build -p extro-cli --release

# Run tests
cargo test --workspace

# Link CLI locally
cargo install --path ./cli

Roadmap

v0.2 (Current)

  • βœ… Rust core + WASM bridge
  • βœ… Full CLI with watch/test/package
  • βœ… MV3 extension shell
  • βœ… Basic documentation

v0.3 (Next)

  • Firefox support
  • Side panel API
  • Built-in React template
  • DevTools panel integration
  • Extension hot reload without browser restart

v1.0 (Future)

  • Plugin system
  • Remote extension registry
  • CRDT-based state sync
  • Multi-account support
  • Built-in AI model adapters

Acknowledgments

Extro builds on amazing work from:


License

MIT License - see LICENSE for details.


Support

Built with ❀️ by Aditya Pandey and contributors.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors