Tech Stack
Every technology in Ghost earns its place. There are no accidental dependencies, no “we might need it later” choices. This page explains what Ghost is built with, why each technology was chosen over alternatives, and how they all fit together.
If you’re not a developer, this page gives you a sense of what’s under the hood — like knowing your car has a V8 engine and all-wheel drive, even if you’re not going to rebuild the transmission yourself.
Backend — Pure Go 1.25
Section titled “Backend — Pure Go 1.25”Ghost’s entire backend — the proxy, API server, database, AI agent, device manager, and everything else — is compiled into a single executable file with zero external dependencies. There’s no Java runtime to install, no Python packages to manage, no Node.js version conflicts. You get one file, you run it, it works.
This is possible because Ghost is written in Go (also called Golang), a programming language created by Google specifically for building networked services. Go compiles to machine code, meaning the resulting program runs directly on your CPU without any interpreter or virtual machine in between.
The phrase “no CGo” means Ghost doesn’t link against any C libraries — it’s 100% Go code. This matters because it makes the program trivially portable between operating systems and CPU architectures (Intel vs Apple Silicon).
Core Libraries
Section titled “Core Libraries”| Component | Library | Why This Was Chosen |
|---|---|---|
| HTTP Router | go-chi/chi/v5 | A lightweight, fast HTTP router that’s compatible with Go’s standard library. Ghost’s ~50 REST API endpoints are all registered through chi. It supports middleware (reusable code that runs before/after every request, like authentication checks). |
| WebSocket | gorilla/websocket | The most battle-tested WebSocket library in Go. Ghost uses WebSockets to push real-time events to the frontend (like “a new flow was captured”) without the frontend having to keep asking. Supports ping/pong keepalive to detect dead connections. |
| Database | modernc.org/sqlite | A pure Go implementation of SQLite (the world’s most widely used database engine). Because it’s pure Go (no C code), it compiles cleanly on every platform. Ghost uses SQLite in WAL mode (allows reading while writing) with FTS5 (full-text search — instant text search across all captured traffic). |
| TLS/MITM | crypto/tls + refraction-networking/utls | Go’s standard TLS library handles the basic encryption, while uTLS (from the Refraction Networking project) makes Ghost’s TLS handshake look exactly like Chrome’s. This is important because some servers reject connections that don’t look like real browsers — uTLS ensures Ghost doesn’t get blocked. |
| JavaScript Engine | dop251/goja | A pure Go implementation of JavaScript (ECMAScript 5.1+). This powers Ghost’s addon system — users write JavaScript scripts that run inside the proxy pipeline. Goja runs these scripts in a sandboxed environment (they can’t access the file system or network directly), which is critical for security. |
| LLM — Anthropic | anthropics/anthropic-sdk-go | The official Go SDK for Anthropic’s Claude AI models. Ghost uses Claude for its AI agent because Claude has the best tool-calling capabilities (the ability for the AI to call Ghost’s built-in functions like searching traffic or running security tests). |
| LLM — OpenAI | openai/openai-go | The official Go SDK for OpenAI’s GPT models. Also used for connecting to Ollama (a local AI runner) because Ollama exposes an OpenAI-compatible API — meaning Ghost can talk to local models using the same code. |
| Config | BurntSushi/toml | Parses Ghost’s configuration file (~/.ghost/config.toml). TOML is a human-readable config format similar to INI files but with more structure. |
| Unique IDs | oklog/ulid/v2 | Generates ULIDs (Universally Unique Lexicographically Sortable Identifiers) for flow IDs. Unlike random UUIDs, ULIDs encode the creation timestamp in the first part, which means sorting by ID automatically sorts by time — perfect for a traffic list. |
| LRU Cache | hashicorp/golang-lru/v2 | An LRU (Least Recently Used) cache from HashiCorp, used for the certificate cache. Ghost can hold 10,000 generated TLS certificates in memory, evicting the oldest ones when the cache is full. This means traffic to frequently-visited domains uses cached certificates for speed. |
| Brotli | andybalholm/brotli | Decompresses Brotli-encoded HTTP response bodies. Brotli is a compression format (like gzip but more efficient) used by many modern web servers. Ghost needs to decompress bodies to display them and for the AI agent to read them. |
| CORS | go-chi/cors | Handles Cross-Origin Resource Sharing headers so the frontend (running on one port) can make API calls to the backend (running on another port) without the browser blocking them. |
| Rate Limiting | golang.org/x/time/rate | A token bucket rate limiter from Go’s extended library. Used to throttle security testing tools so they don’t overwhelm target servers with too many requests per second. |
| Error Tracking | getsentry/sentry-go | Sends crash reports and errors to Sentry (an error tracking service) so the development team can find and fix problems quickly. |
Why Go Over Other Languages?
Section titled “Why Go Over Other Languages?”-
Single binary deployment. Go compiles to one executable file. No runtime to install, no
pip install, nonpm install, no classpath. Copy the file, run it, done. This makes installation and auto-updates trivial. -
Cross-compilation. Building for a different operating system is a single command:
GOOS=darwin GOARCH=arm64 go buildproduces a macOS Apple Silicon binary, even when building on a Windows machine. Ghost targets macOS as the primary platform, built from a Windows dev machine. -
Built-in concurrency. Go’s goroutines (lightweight threads) are perfect for a proxy server. Each incoming connection gets its own goroutine, the AI agent can execute up to 4 tools in parallel, device polling runs in the background — all without the complexity of traditional thread management. Ghost routinely handles hundreds of concurrent proxy connections.
-
Performance. The proxy adds less than 5 milliseconds of latency to requests at the 99th percentile. The SQLite database handles 100,000+ flows without slowdown. These numbers matter because Ghost sits in the critical path of all network traffic — any slowness would make apps feel laggy.
-
Mature ecosystem. Go has battle-tested libraries for everything Ghost needs: HTTP handling, TLS, cryptography, database access, JSON processing, and networking. The standard library alone covers most requirements.
Frontend — React 19 + TypeScript
Section titled “Frontend — React 19 + TypeScript”The frontend is the visual interface you interact with — the traffic list, panels, settings, AI chat, and everything you see in the Ghost window. It’s built as a web application using React (a UI framework from Meta/Facebook) and TypeScript (JavaScript with type safety), then embedded inside the Tauri desktop shell.
| Component | Library | Why This Was Chosen |
|---|---|---|
| UI Framework | React 19 | The latest version of React, the most widely-used UI framework. React 19 includes concurrent rendering features that keep the UI responsive even when processing large amounts of data (like updating a list of 10,000 flows). |
| Build Tool | Vite 7 | Vite is a build tool that compiles TypeScript/JSX into optimized JavaScript for the browser. It’s known for extremely fast hot-module replacement (HMR) — when a developer changes code, the browser updates in milliseconds without a full page reload. |
| CSS | Tailwind CSS v4 | A utility-first CSS framework. Instead of writing custom CSS files, developers apply small utility classes directly in the HTML (like text-sm font-bold text-cyan-400). This prevents CSS from growing uncontrollably and ensures design consistency across the entire app. |
| State Management | Zustand | A lightweight state management library. Ghost has about 20 “stores” — shared data containers for things like the flow list, proxy status, active session, agent conversations, etc. Zustand was chosen over heavier alternatives (like Redux) because it’s simpler, faster, and has less boilerplate code. |
| UI Components | shadcn/ui | A collection of accessible, well-built UI components (buttons, inputs, dropdowns, dialogs, etc.). Ghost uses these as a foundation but resyles every component to match the Ghost design system — the default shadcn look is too generic for Ghost’s aesthetic. |
| Virtual Scrolling | @tanstack/react-virtual | Renders only the rows visible on screen, even when there are 10,000+ flows in the list. Without virtual scrolling, the browser would create DOM elements for every single row, consuming massive amounts of memory and making scrolling choppy. With it, Ghost only creates ~30-40 visible rows and recycles them as you scroll. |
| Resizable Panels | react-resizable-panels v4 | Powers the three-panel layout (scope panel, flow list, flow inspector) with draggable dividers so you can resize each panel to your preference. |
| Markdown Rendering | react-markdown + plugins | The AI agent’s responses are formatted in Markdown (with headings, code blocks, tables, etc.). This library renders that Markdown as rich formatted HTML with syntax-highlighted code blocks. |
| Diagrams | Mermaid | Renders flowcharts, sequence diagrams, and other technical diagrams inside agent responses and bug reports. Used when the agent generates visual explanations of traffic flows. |
| Code Highlighting | highlight.js | Adds syntax coloring to code blocks in agent responses (like generated test scripts). Makes code readable by coloring keywords, strings, variables, etc. |
| Icons | Lucide React | A consistent, clean icon library. Every icon in Ghost (method badges, status indicators, toolbar buttons) comes from Lucide to maintain visual consistency. |
| Notifications | Sonner | A toast notification library. When Ghost needs to tell you something briefly (like “Flow replayed successfully” or “Connection lost”), it shows a small notification that slides in and auto-dismisses. |
Ghost bundles its own fonts as woff2 files (no CDN calls, no external requests, works fully offline):
- Space Grotesk — Used for all UI text, headings, and labels. It’s a geometric sans-serif with a technical, modern feel that avoids the generic look of system fonts like Inter or San Francisco.
- JetBrains Mono — Used for all code, technical values, API paths, and monospaced content. Designed specifically for readability in code contexts with clear distinction between similar characters (like
0vsO,1vsl).
Design System
Section titled “Design System”Ghost uses shadcn/ui components as a starting foundation but resyles every single one to match the Ghost design system. The default shadcn appearance is explicitly rejected — it looks too much like every other shadcn app.
- Color scale:
ghost-950(near-black) throughghost-50(near-white) — a custom neutral scale - Accent colors: Cyan (primary), blue, purple, pink — derived from the Ghost logo gradient
- Both themes: Dark and light mode are equally polished. Neither is an afterthought. The user actively switches between both.
Desktop — Tauri v2
Section titled “Desktop — Tauri v2”Tauri is the framework that turns the React web application into a native desktop app. Instead of bundling an entire copy of Chrome (like Electron does), Tauri uses the operating system’s built-in web renderer (WebKit on macOS, WebView2 on Windows), resulting in a dramatically smaller and lighter application.
| Component | What It Does |
|---|---|
| Tauri v2 | The core framework. Creates the application window, embeds the WebView (where the React UI renders), manages the system tray icon, and provides the native menu bar. |
| Rust shell | The native code layer written in Rust. Manages the Go sidecar process lifecycle, implements the proxy safety net (automatically disables system proxy if the Go engine crashes), and handles platform-specific operations. |
| tauri-plugin-shell | Spawns the Go sidecar as a child process with the --sidecar flag. Monitors its health and restarts it if needed. |
| tauri-plugin-dialog | Provides native “Save As” and “Open File” dialogs that look and feel like the operating system’s native dialogs (not web-style file pickers). |
| tauri-plugin-fs | Gives the frontend limited, scoped access to the filesystem — only specific directories, not the entire disk. Used for exporting session data and saving bug reports. |
| tauri-plugin-process | Handles app restart after an auto-update is applied. |
| tauri-plugin-updater | Checks for and applies updates to Ghost. Updates are signed with EdDSA cryptographic signatures to prevent tampering — Ghost will only install updates that are verified authentic. |
Why Tauri Instead of Electron?
Section titled “Why Tauri Instead of Electron?”Electron (used by VS Code, Slack, Discord) bundles a full copy of Chromium with every app. Tauri takes a fundamentally different approach:
- Binary size: Ghost’s installer is approximately 15MB. An equivalent Electron app would be 150MB+ because it includes all of Chromium.
- Memory usage: Tauri uses the OS’s built-in WebView (WebKit on macOS), sharing memory with other system processes. Electron spawns its own Chromium instance, consuming significantly more RAM.
- Native integration: Tauri provides first-class system tray support, native menu bars, and platform-specific APIs. Ghost uses these for proxy management (macOS’s
networksetup, Windows Registry) — tasks that Electron handles less elegantly. - Security: Tauri uses a capability-based permission system — each plugin explicitly declares what it can access. Combined with a hardened Content Security Policy and scoped filesystem access, Ghost minimizes its attack surface.
Browser Extension — Chrome Manifest V3
Section titled “Browser Extension — Chrome Manifest V3”Ghost’s browser extension works in Chrome and Firefox. It runs inside the browser and communicates with Ghost’s backend over a WebSocket connection.
| Component | What It Does |
|---|---|
| Service Worker | The extension’s background process (runs even when the popup is closed). Maintains a persistent WebSocket connection to Ghost’s WebSocket Hub. Routes messages between content scripts and Ghost. Tracks which browser tabs are active. |
| Content Script | Injected into every web page you visit (when the extension is active). Captures 7 types of user interactions: clicks, text inputs, form submissions, page navigations, scroll events, element selections, and copy/paste actions. These interactions are correlated with network traffic in Ghost’s UI. Also supports 15 types of automated browser actions (clicking elements, filling forms, taking screenshots) and 6 types of JavaScript injection commands. |
| Popup | The small UI that appears when you click the extension icon in the browser toolbar. Shows connection status (whether the extension is connected to Ghost), provides quick action buttons, and displays a log of recent interactions. |
| Build System | Built with Rollup (a JavaScript bundler). Content scripts are compiled as classic scripts (not ES modules) because Chrome’s content script system has limitations with ES module imports. |
Database — SQLite (WAL Mode)
Section titled “Database — SQLite (WAL Mode)”Ghost stores all captured traffic, settings, agent conversations, and other data in a SQLite database — a single file on your disk (located in ~/.ghost/). SQLite was chosen because it requires no separate database server (no PostgreSQL or MySQL to install and configure), supports full-text search natively, and is the most widely deployed database engine in the world (it’s in your phone, your browser, and your operating system right now).
| Setting | Value | What It Means |
|---|---|---|
| Engine | modernc.org/sqlite (pure Go) | A Go implementation of SQLite, so Ghost doesn’t need a C compiler or any native libraries installed. |
| Journal Mode | WAL (Write-Ahead Log) | Allows the proxy to write new flows to the database at the same time as the frontend reads flow data. Without WAL, reads would block writes (or vice versa), causing the UI to stutter when traffic is heavy. |
| Connection Limit | MaxOpenConns(1) | Only one database connection writes at a time. This is SQLite’s single-writer model — it prevents write conflicts. Multiple readers can run simultaneously thanks to WAL. |
| Full-Text Search | FTS5 on URL, headers, body | FTS5 (Full-Text Search version 5) creates a search index across flow URLs, headers, and bodies. This powers Ghost’s instant search — type any string and results appear immediately, even across 100,000+ flows. |
| IDs | ULID (time-ordered) | Flow IDs are ULIDs, which encode the creation timestamp. This means ORDER BY id is the same as ORDER BY created_at, making time-based queries fast without a separate index. |
| Migrations | 18 migrations at startup | When Ghost starts, it checks the database version and applies any pending schema changes. This ensures the database structure is always up-to-date, even after an app update that adds new features. |
| Maintenance | WAL checkpoint every 30 minutes | The WAL file grows as writes accumulate. Every 30 minutes, Ghost “checkpoints” the WAL — merging its changes back into the main database file. On shutdown, a TRUNCATE checkpoint fully cleans up the WAL file. |
| Foreign Keys | Enabled (PRAGMA foreign_keys = ON) | Ensures referential integrity — for example, deleting a session automatically deletes all its flows, and a flow can’t reference a non-existent session. |
| Busy Timeout | 10 seconds | If a write can’t acquire the database lock immediately (because another write is in progress), it waits up to 10 seconds before giving up. This prevents errors during brief write contention. |
Database Tables
Section titled “Database Tables”| Table | What It Stores |
|---|---|
flows | The core table. Every captured HTTP request/response: method, URL, headers, body, status code, timing data, tags, device info, and more. |
flows_fts | The full-text search index that mirrors data from flows. Not a regular table — it’s an FTS5 virtual table that SQLite queries when you search for text across all flows. |
sessions | Named capture sessions. Each session has a name, creation date, and an “active” flag (only one session is active at a time). |
settings | Application settings stored as key-value pairs. Things like proxy port, LLM API keys (encrypted), theme preference, noise detection settings, etc. |
addons | JavaScript addon scripts. Each row contains the script code, name, description, whether it’s enabled, and which interceptor phases it hooks into. |
conversations | AI agent chat conversations. Each conversation belongs to a session and has a title, creation date, and mode (QA or Security). |
messages | Individual messages within agent conversations. Both user messages and agent responses, including tool calls and their results. |
interactions | Browser extension interaction events: clicks, inputs, navigations, etc. Each interaction is timestamped so it can be correlated with concurrent network traffic. |
journeys + journey_steps | Recorded user journeys (sequences of user actions like “login → search → checkout”). Journeys have steps, and each step records what happened and what traffic was generated. |
ws_frames | WebSocket frame data. When Ghost captures WebSocket connections, individual frames (messages sent back and forth) are stored here for inspection. |
security_findings | Security vulnerability findings generated by the security interceptor or the AI agent. Each finding has a severity, description, affected flow, and remediation advice. |
artifacts | Persisted outputs like bug reports and exported data. When the agent generates a bug report or you export a session, the output is saved here. |
map_rules | URL mapping and rewriting rules. Each rule defines pattern matches and actions (redirect to different URL, serve a local file, return a mock response). |
injection_rules | JavaScript injection rules for the browser extension. Each rule defines a URL pattern and JavaScript code to inject into matching pages. |
extension_events | Browser events captured by the extension: console errors, page navigations, localStorage/sessionStorage changes. Provides broader context beyond just network traffic. |
LLM Providers
Section titled “LLM Providers”Ghost’s AI agent can connect to three different AI providers. You choose which one to use in Ghost’s settings — the agent works the same way regardless of provider.
| Provider | SDK | Available Models | Best For |
|---|---|---|---|
| Anthropic | anthropic-sdk-go (official) | Claude Sonnet 4.6, Claude Opus 4.6 | The recommended choice. Claude models have the best tool-calling accuracy (the ability to correctly invoke Ghost’s built-in functions like searching traffic or running security tests), which is critical for Ghost’s agent to work well. |
| OpenAI | openai-go (official) | GPT-4o, GPT-4-turbo | A solid alternative if you already have an OpenAI API key or prefer GPT models. |
| Ollama | openai-go (compatible API) | Any locally-installed model (Llama, Mistral, CodeLlama, etc.) | For offline use or privacy-sensitive environments where sending traffic data to an external API is not acceptable. Ollama runs AI models directly on your machine. Ghost connects to it using the same OpenAI SDK because Ollama exposes an OpenAI-compatible API. |
API Key Security
Section titled “API Key Security”API keys are encrypted at rest using AES-256-GCM (an industry-standard authenticated encryption algorithm). The encryption key is derived from your machine’s identity — a SHA-256 hash of your hostname, operating system, and home directory path. This means:
- API keys stored in Ghost’s database file cannot be read by simply opening the file
- The keys are tied to your specific machine — copying the database to another computer won’t expose them
- Ghost automatically detects plaintext API keys (from older versions or manual config edits) and encrypts them on the next settings save
Security Scanners (External)
Section titled “Security Scanners (External)”Ghost integrates with 10 industry-standard security scanning tools. These are not bundled with Ghost — they are separate open-source tools that you install independently. 7 of them can be installed with one click from Ghost’s Settings UI (via Homebrew on macOS or Chocolatey on Windows). The remaining 3 (Nmap, SSLScan, Hydra) require manual installation. Ghost detects which ones are installed on your machine (by checking your system’s PATH) and makes them available to the AI agent as tools.
| Scanner | What It Does | Why Ghost Integrates With It |
|---|---|---|
| Nuclei | Runs template-based vulnerability scans. Has thousands of community-maintained templates covering CVEs, misconfigurations, default credentials, and more. | The broadest automated vulnerability coverage. The agent can point Nuclei at endpoints discovered in captured traffic. |
| DalFox | Specialized XSS (Cross-Site Scripting) scanner. Generates and tests XSS payloads automatically. | XSS is one of the most common web vulnerabilities. DalFox is more thorough at finding XSS than general-purpose scanners. |
| ffuf | Web fuzzer. Sends thousands of requests with different parameter values to discover hidden endpoints, files, or input handling issues. | Useful for discovering API endpoints or parameters that aren’t visible in normal traffic. The agent uses Ghost’s built-in wordlists (api-endpoints.txt, common-paths.txt) for fuzzing. |
| sqlmap | SQL injection testing tool. Automatically detects and exploits SQL injection vulnerabilities in web applications. | SQL injection remains one of the most critical vulnerability classes. sqlmap is the gold standard for detecting it. |
| TruffleHog | Secret scanner. Detects accidentally leaked secrets (API keys, passwords, tokens) in HTTP responses, source code, and configuration files. | Catches a common and dangerous mistake — secrets accidentally exposed in API responses or client-side code. |
| Katana | Web crawler/spider. Follows links, submits forms, and maps the structure of a web application automatically. | Helps the agent discover endpoints and pages that aren’t visible in manually-captured traffic. Useful for comprehensive security assessments. |
| Semgrep | Static code analysis tool. Scans source code (when available) for security patterns, bugs, and anti-patterns using customizable rules. | If the agent encounters source code (like JavaScript bundles in responses), Semgrep can analyze it for vulnerabilities without executing it. |
| Nmap | Network port scanner and service detector. Maps open ports and identifies running services on target hosts. | Helps discover additional attack surface beyond just HTTP endpoints — database ports, admin interfaces, debug services. |
| SSLScan | TLS/SSL configuration analyzer. Tests cipher suites, protocol versions, certificate validity, and known TLS vulnerabilities. | Identifies weak TLS configurations (outdated protocols, weak ciphers, expired certificates) that could enable man-in-the-middle attacks. |
| Hydra | Password brute-force and dictionary attack tool. Tests login endpoints against wordlists of common credentials. | Tests whether login endpoints are vulnerable to credential stuffing or lack rate limiting and account lockout protections. |
When the AI agent is in Security mode and encounters a situation where one of these tools would be useful (for example, it finds a parameter that might be vulnerable to SQL injection), it can automatically invoke the appropriate scanner, wait for results, and incorporate the findings into its analysis — all without you needing to run anything manually.