____                      _
/ ___|  ___ __ _ _ __ __ _| |__
\___ \ / __/ _` | '__/ _` | '_ \
 ___) | (_| (_| | | | (_| | |_) |
|____/ \___\__,_|_|  \__,_|_.__/

Scarab Terminal Emulator

Next-Generation GPU-Accelerated Terminal with F# Plugins

Build Status License: MIT Rust Fusabi Bevy

Features | Installation | Quick Start | Plugins | Documentation | Contributing


Visual Demos

Link Hints Demo

Press Ctrl+Shift+O to highlight all links, then press the shown key to open


Command Palette - Quick Access to Everything

Command Palette

Press Ctrl+Shift+P for fuzzy searchable command palette


Plugin System - Extend with F#

Plugin Installation

Write powerful plugins in Fusabi (F# for Rust) with hot-reload support


Real-Time Theme Switching

Theme Switch

Switch themes instantly - no restart required


Watch Full Demos

Scarab in 2 Minutes - Quick feature overview β–Ά Watch on YouTube | πŸ“₯ Download MP4

Your First Plugin - Step-by-step plugin creation β–Ά Watch on YouTube | πŸ“₯ Download MP4

Advanced Workflows - Power user tips β–Ά Watch on YouTube | πŸ“₯ Download MP4


⚠️ Alpha Software Warning

Scarab is currently in alpha (v0.1.0-alpha). While the core architecture is stable and functional, expect:

  • Incomplete features and rough edges
  • Potential breaking changes between releases
  • Limited platform support (Linux only, macOS/Windows planned)
  • Active development with frequent updates

Current Status: ~80% of MVP features complete | Phase 5: Integration & Polish


πŸš€ What is Scarab?

Scarab is a high-performance, split-process terminal emulator built in Rust that reimagines terminal extensibility through:

  • Split Architecture: Daemon (headless server) + Client (GPU-accelerated GUI) for resilience and flexibility
  • Zero-Copy IPC: Shared memory ring buffer with lock-free synchronization
  • Hybrid F# Plugin System: Powered by Fusabi - an official F# dialect for Rust
  • GPU-Accelerated Rendering: Built on Bevy game engine with cosmic-text
  • Hot-Reloadable UI: Write UI scripts in F# that reload instantly without recompilation

Built for developers who want a modern, hackable terminal with native scripting support.


✨ Features

Core Terminal

  • βœ… Full VTE Compatibility: ANSI escape sequences, colors (256 + true color), scrollback
  • βœ… GPU Rendering: 60+ FPS at 200x100 cells with cosmic-text texture atlas caching
  • βœ… Session Persistence: SQLite-backed session management, survives client crashes
  • βœ… Split-Process Design: Daemon persists terminal state, clients attach/detach freely

Plugin System (Fusabi-powered)

  • βœ… Dual Runtime Support:
    • Client-side (.fsx scripts): Hot-reloadable UI plugins via fusabi-frontend
    • Daemon-side (.fzb bytecode): High-performance compiled plugins via fusabi-vm
  • βœ… Rich Plugin API: 10+ hooks (output, input, resize, pre/post command, remote commands)
  • βœ… Remote UI Protocol: Daemon plugins can control client UI (overlays, modals, commands)
  • βœ… Example Plugins:
    • scarab-nav: Link hints and keyboard navigation
    • scarab-palette: Command palette with fuzzy search
    • scarab-session: Session management commands
    • Git status indicators, notification monitors, custom keybindings

Performance

  • πŸš€ Zero-Copy Rendering: Shared memory with lock-free AtomicU64 sequence numbers
  • πŸš€ Optimized Builds: LTO, single codegen unit, opt-level 3
  • πŸš€ Profiling Support: Tracy, puffin, criterion benchmarks

Configuration

  • πŸ”§ TOML-based with hot-reload
  • πŸ”§ F# DSL for advanced configuration (Fusabi-lang syntax)
  • πŸ”§ Per-session overrides with inheritance

πŸ“¦ Installation

Prerequisites

  • Rust 1.75+ with Cargo (Install Rust)
  • Linux with X11 or Wayland (macOS/Windows support planned)
  • Git (for cloning repository)
# Clone the repository
git clone https://github.com/raibid-labs/scarab.git
cd scarab
 
# Build with optimizations
cargo build --release
 
# Binaries will be in target/release/
# - scarab-daemon
# - scarab-client

Platform-Specific Notes

Ubuntu/Debian:

sudo apt install build-essential pkg-config libfontconfig-dev

Fedora/RHEL:

sudo dnf install gcc pkg-config fontconfig-devel

Arch Linux:

sudo pacman -S base-devel fontconfig

🏁 Quick Start

1. Start the Daemon (Terminal Server)

In a terminal, run:

cargo run --release -p scarab-daemon

The daemon will:

  • Create shared memory at /scarab_shm_v1
  • Start IPC socket at /tmp/scarab.sock
  • Initialize session manager with SQLite database
  • Load daemon plugins from ~/.config/scarab/plugins/

2. Launch the Client (GUI)

In a separate terminal, run:

cargo run --release -p scarab-client

The client will:

  • Connect to daemon via IPC socket
  • Map shared memory for zero-copy rendering
  • Open Bevy window with terminal UI
  • Load client UI scripts from ~/.config/scarab/ui-scripts/
  • Launch interactive tutorial on first run (press ESC to skip)

3. Interactive Tutorial

On first launch, Scarab will guide you through an 8-step interactive tutorial:

  1. Welcome - Introduction to Scarab
  2. Navigation - Running commands
  3. Scrollback - Mouse wheel scrolling
  4. Link Hints - Keyboard-driven URL opening (Ctrl+Shift+O)
  5. Command Palette - Quick command access (Ctrl+Shift+P)
  6. Plugins - Plugin system overview
  7. Configuration - Customization basics
  8. Completion - Next steps

Replay anytime: scarab-client --tutorial

4. Create Your First Plugin (5 minutes!)

Create ~/.config/scarab/plugins/hello.fsx:

(*
 * hello.fsx - My First Scarab Plugin
 * A simple plugin that greets you when loaded
 *)
 
open Scarab.PluginApi
 
// Plugin metadata
let metadata = {
    Name = "hello-plugin"
    Version = "1.0.0"
    Description = "My first Scarab plugin"
    Author = "Your Name"
    Homepage = None
    ApiVersion = "0.1.0"
    MinScarabVersion = "0.1.0"
}
 
// Called when plugin loads
let on_load (ctx: PluginContext) : Async<Result<unit, string>> =
    async {
        ctx.Log(LogLevel.Info, "Hello from my first plugin!")
 
        // Get terminal size
        let (cols, rows) = ctx.GetSize()
        ctx.Log(LogLevel.Info, sprintf "Terminal size: %dx%d" cols rows)
 
        return Ok ()
    }
 
// Export the plugin
Plugin.Register {
    Metadata = metadata
    OnLoad = on_load
    OnUnload = None
    OnOutput = None
    OnInput = None
    OnResize = None
    OnAttach = None
    OnDetach = None
    OnPreCommand = None
    OnPostCommand = None
    OnRemoteCommand = None
    GetCommands = fun () -> []
}

Restart the daemon to load your plugin:

# Ctrl+C the daemon, then:
cargo run --release -p scarab-daemon

See your plugin’s log messages in the daemon output!


πŸ”Œ Plugin System

Why Fusabi?

Fusabi is an official F# dialect scripting language designed for Rust. It provides:

  • Familiar F# Syntax: If you know F#, you know Fusabi
  • Type Safety: Compile-time type checking prevents runtime errors
  • Async/Await: First-class support for asynchronous operations
  • Zero-Cost FFI: Direct interop with Rust types
  • Dual Runtimes: Compiled bytecode (.fzb) and interpreted scripts (.fsx)

Plugin Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      SCARAB CLIENT (GUI)                     β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  UI Scripts (.fsx) - fusabi-frontend               β”‚    β”‚
β”‚  β”‚  β€’ Hot-reloadable (no Rust recompilation)          β”‚    β”‚
β”‚  β”‚  β€’ UI overlays, custom keybindings                 β”‚    β”‚
β”‚  β”‚  β€’ Fast iteration for UI development               β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  Bevy Rendering Engine + Shared Memory Reader      β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β–²
                           β”‚ Zero-Copy IPC (Shared Memory)
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   SCARAB DAEMON (Headless)                   β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  Compiled Plugins (.fzb) - fusabi-vm               β”‚    β”‚
β”‚  β”‚  β€’ High performance (pre-compiled bytecode)        β”‚    β”‚
β”‚  β”‚  β€’ Output filtering, mux logic                     β”‚    β”‚
β”‚  β”‚  β€’ Process monitoring, shell integration           β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  PTY Manager + VTE Parser + Session State          β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Plugin Hooks

Plugins can hook into various terminal lifecycle events:

HookLocationDescription
OnLoadDaemon/ClientCalled when plugin is loaded
OnUnloadDaemon/ClientCalled before plugin is unloaded
OnOutputDaemonIntercept terminal output before rendering
OnInputDaemonIntercept keyboard/mouse input before PTY
OnResizeDaemonCalled when terminal is resized
OnAttachDaemonCalled when a client connects
OnDetachDaemonCalled when a client disconnects
OnPreCommandDaemonCalled before shell command execution
OnPostCommandDaemonCalled after shell command completes
OnRemoteCommandDaemonHandle commands from client UI (command palette)
GetCommandsDaemonProvide commands for client command palette

Example: Git Status Plugin

See a real-world plugin that shows git status in your terminal:

// examples/plugins/git-status.fsx
open Scarab.PluginApi
open System.Diagnostics
 
let metadata = {
    Name = "git-status"
    Version = "1.0.0"
    Description = "Display git repository status in terminal"
    Author = "Scarab Examples"
    Homepage = Some "https://github.com/raibid-labs/scarab"
    ApiVersion = "0.1.0"
    MinScarabVersion = "0.1.0"
}
 
// Check if in git repository
let checkGitRepo () : bool =
    try
        let psi = ProcessStartInfo("git", "rev-parse --git-dir")
        psi.RedirectStandardOutput <- true
        psi.UseShellExecute <- false
        use proc = Process.Start(psi)
        proc.WaitForExit()
        proc.ExitCode = 0
    with _ -> false
 
// Update and draw git status overlay
let updateGitStatus (ctx: PluginContext) =
    if checkGitRepo() then
        // Get current branch
        let branch = (* ... git command ... *)
        let isDirty = (* ... git status ... *)
 
        // Draw overlay in top-right corner
        ctx.QueueCommand(RemoteCommand.DrawOverlay {
            Id = 10000UL
            X = (* top-right position *)
            Y = 0us
            Text = sprintf " git:%s%s " branch (if isDirty then "*" else "")
            Style = { Fg = 0xFFFFFFFFu; Bg = 0x00AA00FFu; ZIndex = 100.0f }
        })
 
// Register hooks
Plugin.Register {
    Metadata = metadata
    OnLoad = (* initial status check *)
    OnPostCommand = Some (* update after git/cd commands *)
    OnResize = Some (* reposition overlay *)
    (* ... *)
}

More Examples: See examples/plugins/ for:

  • hello-plugin.fsx - Minimal hello world
  • output-filter.fsx - Filter and highlight terminal output
  • custom-keybind.fsx - Custom keyboard shortcuts
  • notification-monitor.fsx - Desktop notifications for long commands
  • session-manager.fsx - Session switching and management

πŸ“– Documentation

Getting Started

Project Documentation

Plugin Development

  • plugins - Example plugins with detailed comments
  • plugin-template - Starter template for new plugins
  • API Reference: Run cargo doc --open --workspace for full API documentation

Configuration

  • fusabi-config - Configuration examples
    • minimal.fsx - Minimal configuration
    • standard.fsx - Standard configuration with comments
    • advanced.fsx - Advanced features
    • custom-theme.fsx - Custom color themes

πŸ—οΈ Building from Source

Full Workspace Build

# Debug build (faster compilation)
cargo build --workspace
 
# Release build (optimized, recommended for usage)
cargo build --release --workspace
 
# Build specific crate
cargo build --release -p scarab-daemon
cargo build --release -p scarab-client

Development Workflow

# Check all crates for errors (faster than build)
cargo check --workspace
 
# Run all tests
cargo test --workspace
 
# Run specific test suite
cargo test -p scarab-client ui_tests
 
# Run with debug logging
RUST_LOG=debug cargo run -p scarab-daemon
RUST_LOG=debug cargo run -p scarab-client
 
# Watch mode (requires cargo-watch)
cargo watch -x 'check --workspace'

Performance Profiling

# Build with profiling symbols
cargo build --profile profiling
 
# Run benchmarks
cargo bench --workspace
 
# Generate flamegraph (requires cargo-flamegraph)
cargo flamegraph -p scarab-daemon

⚑ Performance Highlights

  • Zero-Copy IPC: Shared memory ring buffer eliminates data copying between daemon and client
  • Lock-Free Synchronization: AtomicU64 sequence numbers avoid mutex contention
  • GPU-Accelerated: Bevy engine with cosmic-text texture atlas caching
  • Optimized Builds: Thin LTO, single codegen unit, aggressive optimizations
  • 60+ FPS Rendering: Smooth scrolling even at 200x100 cell grids

Benchmark Results (on reference hardware):

  • Startup time: ~50ms (daemon) + ~200ms (client)
  • Input latency: <5ms (keyboard to screen)
  • Memory usage: ~15MB (daemon) + ~80MB (client with GPU textures)
  • Plugin load time: <10ms for typical .fsx script

πŸ—ΊοΈ Roadmap

Current Phase: Phase 5 - Integration & Polish (~80% complete)

Completed (Phases 1-4)

  • βœ… Core terminal emulation (VTE parser, rendering)
  • βœ… Zero-copy IPC with shared memory
  • βœ… Plugin system with Fusabi integration
  • βœ… Session management and persistence
  • βœ… Configuration system with hot-reload
  • βœ… Remote UI protocol (daemon controls client UI)
  • βœ… Core plugins: nav, palette, session

In Progress (Phase 5)

  • πŸ”„ Interactive tutorial and onboarding
  • πŸ”„ E2E testing with real daemon-client interaction
  • πŸ”„ UI polish and animations
  • πŸ”„ Documentation and examples
  • πŸ”„ Alpha release preparation

Upcoming (Phases 6-10)

  • πŸ“‹ Phase 6: Tabs, splits, window management
  • πŸ“‹ Phase 7: macOS and Windows support
  • πŸ“‹ Phase 8: Advanced rendering (ligatures, images, sixel)
  • πŸ“‹ Phase 9: Multiplexing and remote sessions
  • πŸ“‹ Phase 10: Beta release and ecosystem growth

See ROADMAP.md for detailed phase breakdown.


🀝 Contributing

Scarab is in active development and welcomes contributions! Here’s how to get started:

Ways to Contribute

  • πŸ› Report Bugs: Open an issue with reproduction steps
  • πŸ’‘ Suggest Features: Discuss new ideas in GitHub Discussions
  • πŸ“ Improve Documentation: Fix typos, add examples, clarify guides
  • πŸ”Œ Write Plugins: Share your plugins in examples/plugins/
  • πŸ§ͺ Add Tests: Improve test coverage for any crate
  • 🎨 UI/UX: Design improvements for Bevy client

Development Setup

  1. Fork and Clone:

    git clone https://github.com/YOUR_USERNAME/scarab.git
    cd scarab
  2. Create a Branch:

    git checkout -b feature/my-awesome-feature
  3. Make Changes:

    # Make your changes
    cargo check --workspace  # Ensure no errors
    cargo test --workspace   # Run tests
    cargo fmt               # Format code
    cargo clippy --workspace # Lint code
  4. Commit and Push:

    git add .
    git commit -m "feat: Add my awesome feature"
    git push origin feature/my-awesome-feature
  5. Open Pull Request: Create a PR on GitHub with description of changes

Code Guidelines

  • Follow Rust standard formatting (cargo fmt)
  • Pass clippy lints (cargo clippy)
  • Add tests for new functionality
  • Update documentation for API changes
  • Keep commits atomic and well-described

Questions?


πŸ“„ License

Scarab is licensed under the MIT License. See LICENSE for details.


πŸ™ Acknowledgments

Scarab stands on the shoulders of giants:

Core Technologies

  • Fusabi - F# scripting language for Rust (plugin system foundation)
  • Bevy - Data-driven game engine (GPU rendering)
  • cosmic-text - Advanced text shaping and rendering
  • Alacritty - VTE parser (alacritty_terminal crate)

Inspirations

  • tmux - Session persistence and multiplexing concepts
  • kitty - GPU acceleration and protocol innovation
  • Warp - Modern terminal UX and command palette
  • Zellij - Rust terminal multiplexer with plugins

Community

  • Rust Community - For the amazing ecosystem
  • Bevy Community - For support and plugins
  • F# Community - For inspiration behind Fusabi

Built with ❀️ by raibid-labs

⬆ Back to Top