AI-Powered SSH Client and Remote Operations Workspace
SSH, Telnet, Serial, RDP/VNC, SFTP, port forwarding, and lightweight editing in one native workspace.
GPU-rendered. Free. No account needed.
No Electron. No bundled WebView. No telemetry. No subscription. BYOK-first. Pure-Rust SSH without OpenSSL/libssh2.
Open-source, local-first, and GPU-rendered with GPUI.
English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Français | Deutsch | Español | Italiano | Português | Tiếng Việt
OxideTerm is an open-source, local-first workspace for connecting to servers and working across terminals, files, forwarding, host tools, and remote desktops.
What you can do:
Your connections and operational data stay under your control. OxideTerm requires no account, uses your own AI provider when OxideSens is enabled, and keeps the desktop experience free of Electron and bundled browser runtimes.
| If you care about... | OxideTerm gives you... |
|---|---|
| One remote node, many tools | Terminal, SFTP, port forwarding, RDP/VNC, trzsz, native IDE, monitoring, and OxideSens AI stay attached to the same workspace |
| A desktop app without Electron or a bundled WebView | GPUI draws the interface directly on a GPU surface, without shipping a browser runtime |
| Local-first operations workflows | SSH, Telnet, SFTP, forwarding, RDP/VNC, local shell, serial terminals, and config work without signup |
| BYOK OxideSens AI instead of platform credits | OxideSens uses your OpenAI/Anthropic/Gemini/Ollama/OpenAI-compatible endpoint with MCP, RAG, provider-aware reasoning controls, and approved workspace actions |
| Reconnect stability | Grace Period probes the old connection for 30s before replacing it, so TUI apps can survive short network drops |
| Pure-Rust SSH and credential safety | The SSH stack uses russh + ring without OpenSSL/libssh2; stored credentials use the OS keychain, and .oxide bundles use ChaCha20-Poly1305 + Argon2id |
The screenshots below show the OxideTerm workspace across terminal, file, editing, and forwarding workflows.
SSH Terminal + OxideSens AI![]() | SFTP File Manager![]() |
Built-in IDE![]() | Smart Port Forwarding![]() |
OxideTerm keeps terminal rendering, connection state, reconnect orchestration, files, forwarding, automation, and AI context inside one Rust application. The result is a workspace in which tools share the same server identity and session lifecycle instead of behaving like disconnected utilities.
| Aspect | Bundled browser approach | OxideTerm |
|---|---|---|
| Rendering | Browser engine and web layout | GPUI on a GPU surface |
| Terminal data flow | WebSocket → JS event loop → xterm.js | Rust input → TerminalState mutation → GPUI render |
| Connection lifecycle | Split across frontend and backend layers | One in-process connection and reconnect pipeline |
| AI context | Copied through an application bridge | Built from the active workspace with user approval |
| Plugin runtime | Browser scripting environment | Manifest-only, capability-scoped WASM, and trusted process runtimes |
| CLI | Requires the desktop app running | Standalone binary, direct crate linkage |
| Runtime boundary | Desktop wrapper plus browser runtime | Native process with no bundled browser runtime |
| Category | Features |
|---|---|
| Terminal & Connections | Local shells, SSH, Telnet, serial, split panes, Free Type Mode, shell integration, command marks, recording, trzsz transfers, terminal graphics, advanced multi-target command sending, multi-hop routes, host-key verification, Agent forwarding, 2FA, and Grace Period reconnect |
| Files & Remote Editing | SFTP browsing, transfer queues, speed limits, progress and ETA, bookmarks, safe writes, local file management, remote project trees, multi-tab editing, conflict handling, and workspace restore |
| Forwarding & Networking | Local, remote, and dynamic SOCKS5 forwarding, saved rules, reconnect-aware restore, remote port detection, connection topology, and ad-hoc socket debugging |
| Host Operations & Remote Desktop | Host monitoring, processes, services, logs, ports, tasks, disks, packages, containers, tmux, built-in RDP and VNC, clipboard, input, reconnect, and viewport-aware sizing |
| OxideSens & Automation | BYOK providers, MCP, local RAG, Agent Skills, approved workspace actions, command policy, chat history, encrypted cloud sync, portable .oxide bundles, and a standalone CLI for automation and diagnostics |
| Extensions & Personalization | Manifest-only, capability-scoped WASM, and process plugins, custom tabs and settings, Quick Commands, themes, background images, configurable shortcuts, and 11 interface languages |
OxideTerm keeps terminal, SSH, Telnet, RDP, VNC, SFTP, forwarding, editing, AI, plugins, and CLI in one Rust architecture. The implementation notes below are for readers who want the engineering details.
GPUI and the terminal/SSH backend share one Rust process; optional remote agents and platform helpers remain outside this boundary:
┌─────────────────────────────────────────────────┐
│ GPUI Render Loop │
│ WorkspaceApp · Tab surfaces · GPUI views │
└──────────────────────┬──────────────────────────┘
│ in-process Arc<> / async
┌──────────────────────▼──────────────────────────┐
│ Domain Crates (Rust async) │
│ NodeRouter → SshConnectionRegistry │
│ TerminalState ← SSH PTY channel (russh) │
│ SftpSession · ForwardingRuntime · IdeWorkspace │
│ Ai/ACP Entities · CloudSync · Plugin Runtimes │
└─────────────────────────────────────────────────┘
There is no serialization boundary between the UI and the SSH/terminal backend. Terminal bytes mutate TerminalState directly — no JSON, no WebSocket, no Base64, no xterm.js parse pass. GPUI reads the state and emits GPU draw calls.
The desktop app links the russh stack directly:
ringSSH_AUTH_SOCK) and Windows (\\.\pipe\openssh-ssh-agent)AgentSigner for russh Signer trait compatibility across .await boundsReconnect is coordinated by one Rust pipeline:
Pipeline: queued → snapshot → grace-period → ssh-connect → await-terminal → restore-forwards → resume-transfers → restore-ide → verify → done
SshConnectionRegistry is backed by DashMap; the workspace uses it through NodeRouter and runtime entities:
connecting → active → idle → link_down → reconnectingnodeId → connectionId by NodeRouterWorkspaceApp helpers persist the snapshot to session_tree.json, while live handles are rebuilt on startuplink_downConnectionRegistry owns physical connections, health state, consumers, and idle cleanup. WorkspaceRuntimeEntity schedules probes and reconnect jobs. AI and plugins use capability handles, host snapshots, or terminal hooks rather than registering as physical connection consumers.
OxideSens is BYOK-first, with context building performed in-process:
The entire UI is written in Rust using GPUI (Zed's GPU-backed UI framework):
Terminal rendering is modeled as Rust state first, then drawn by GPUI:
TerminalState; scrollback, cursor, selection, marks, and search state stay in RustRemote files are part of the same node workspace rather than a separate disconnected feature:
NodeRouter and carry a connection generation; reconnect reacquires an eligible session, but an old-generation operation is never silently replaced by a new connectionExtension and support surfaces stay inside explicit Rust-owned boundaries:
--yes guards, and rollback backups where applicableForwarding is implemented as a standalone Rust crate:
ssh_io task — no Arc<Mutex<Channel>>The in-band protocol is integrated directly with native file dialogs:
Portable exports use:
Requirements: Rust toolchain (Edition 2024), desktop environment capable of running GPUI.
# Run the app
cargo run
# If the renderer fails on your machine, try the compatibility profile
OXIDETERM_RENDER_PROFILE=compatibility cargo run
# Build the headless CLI companion
./scripts/build/build-cli.sh
# Build the optional Linux remote agent
./scripts/build/build-agent.sh
CLI artifacts land in crates/oxideterm-gpui-app/resources/cli-bin/<target-triple>/oxideterm.
The headless oxideterm CLI works without launching the app — useful for automation, CI, and diagnostics.
cargo run -p oxideterm-cli -- doctor --strict
cargo run -p oxideterm-cli -- settings validate --strict --json
cargo run -p oxideterm-cli -- connections search prod
cargo run -p oxideterm-cli -- forwards list --format json
cargo run -p oxideterm-cli -- cloud-sync push --dry-run --json
cargo run -p oxideterm-cli -- oxide export ./profile.oxide --connection prod --password-stdin
cargo run -p oxideterm-cli -- report --bundle ./oxideterm-report.zip
cargo run -p oxideterm-cli -- completion install zsh --force
# Path/profile isolation for CI or fixture testing
cargo run -p oxideterm-cli -- --config-dir ./fixture-config doctor --strict
| Layer | Technology | Notes |
|---|---|---|
| UI framework | GPUI (Zed) | GPU-backed immediate mode, pure Rust |
| Runtime | Tokio + DashMap | Full async, lock-free concurrent maps |
| SSH | russh (ring) | No OpenSSL/libssh2 in the SSH stack; SSH Agent |
| Local PTY | portable-pty | Feature-gated, ConPTY on Windows |
| Terminal emulation | alacritty_terminal | VT100–VT500, Sixel, Kitty graphics |
| Editor | tree-sitter (syntax), custom buffer | Multi-language, SFTP-backed |
| Encryption | ChaCha20-Poly1305 + Argon2id | AEAD + memory-hard KDF (256 MB) |
| Plugin runtime | Wasmtime/WASI, sidecar WASM, and process paths | Controlled WASM host calls; process plugins are local and not OS-sandboxed |
| AI streaming | SSE (OpenAI/Anthropic/Gemini) | In-process, no IPC boundary |
| RAG | BM25 + HNSW vector index | CJK bigram tokenizer, RRF fusion |
| i18n | oxideterm-i18n (custom) | Built-in loader, 11 shipped locales |
| Concern | Implementation |
|---|---|
| Stored credentials | OS keychain (macOS Keychain / Windows Credential Manager / libsecret) |
| Secret memory | Secret-bearing Rust types and temporary buffers use zeroize / Zeroizing at supported ownership boundaries |
| Diagnostics | Support output favors structured metadata and redacted hints over secret-bearing payloads |
| AI context | Provider-bound messages pass through credential-pattern redaction; workspace context and actions remain user-controlled |
.oxide export | ChaCha20-Poly1305 + Argon2id (256 MB memory, 4 iterations) |
| CLI writes | Dry-run plans, --yes guards, rollback backups for state-changing commands |
| Host keys | TOFU with ~/.ssh/known_hosts, rejects unexpected changes |
| Plugin boundary | Manifest-only, controlled WASM host API, or trusted local process |
OxideTerm is licensed under GPL-3.0-only without additional license restrictions. When using it, access only systems, networks, and devices that you own or are explicitly authorized to access, and comply with applicable law. Do not use OxideTerm for unauthorized access, service disruption, or bypassing access controls.
Contributions are welcome across Rust code, documentation, translations, plugins, testing, and issue reproduction. Open an issue to discuss larger changes or well-scoped fixes.
Bug reports are most useful with a redacted CLI bundle:
cargo run -p oxideterm-cli -- report --bundle ./oxideterm-report.zip
Reproducible bug reports and regressions with redacted diagnostics are prioritized. Feature requests are reviewed based on scope, safety, and alignment with OxideTerm's remote-server workspace direction.
If OxideTerm helps your workflow, a GitHub star, issue reproduction, translation fix, or plugin all make the project easier to keep moving.
GPL-3.0-only. Detailed dependency attribution is recorded in THIRD_PARTY_NOTICES.md, with additional notices in NOTICE.
russh · GPUI · alacritty_terminal · portable-pty · wasmtime · tree-sitter
No reviews yet. Be the first to rate this tool.
Sign in to leave a review.