OxideTerm is a local-first SSH client designed to simplify remote server management by integrating terminals, SFTP, port forwarding, and lightweight editing into one workspace. Built with Tauri and React, it uses Pure Rust SSH to deliver a secure and efficient experience without relying on Electron or OpenSSL.
Key Features:
Zero Electron, zero OpenSSL, and zero telemetry for a lightweight, privacy-focused workflow.
BYOK (Bring Your Own Key) support for OxideSens AI, enabling users to leverage their preferred AI providers like OpenAI or DeepSeek.
Local-first SSH workflows that work offline, with optional cloud sync via plugins.
Audience & Benefit:
Ideal for developers and system administrators who prioritize privacy and security in their remote work. OxideTerm eliminates the need for accounts or subscriptions, allowing users to maintain control over their data while enjoying powerful features like SFTP file management, port forwarding, and AI-powered insights directly within the workspace.
README
โก OxideTerm
AI-Powered SSH Client for Remote Servers โ Tauri Desktop App
SSH terminals, SFTP, port forwarding, serial terminals, in-terminal transfers, local shells, and lightweight editing in one workspace.
Built with Tauri & React, powered by Pure Rust SSH. Free. No account needed.
Zero Electron. Zero OpenSSL. Zero Telemetry. Zero Subscription. BYOK-first. Pure Rust SSH.
Watch OxideSens follow a user request and open a terminal inside OxideTerm.
What OxideTerm Is
OxideTerm is a local-first AI workspace for remote servers โ an open-source alternative to Termius, SecureCRT & Tabby.
What you can do:
Manage SSH terminals, SFTP, port forwards, in-terminal transfers, and local shells side by side
Keep working through network hiccups with Grace Period reconnect
Ask OxideSens AI to inspect live sessions and perform approved workspace actions through your own AI provider
It is not a hosted cloud agent platform or a benchmark-only terminal renderer. The product direction is narrower: make remote work feel like one local workspace, without requiring an OxideTerm account.
Why OxideTerm?
If you care about...
OxideTerm gives you...
One remote node, many tools
Terminal, SFTP, port forwarding, trzsz, lightweight editor, monitoring, and OxideSens AI stay attached to the same SSH workspace
Local-first SSH workflows
SSH, SFTP, forwarding, local shell, and config work without signup; cloud sync is opt-in via official plugin
BYOK OxideSens AI instead of platform credits
OxideSens uses your OpenAI/Ollama/DeepSeek/OpenAI-compatible endpoint with MCP, RAG, and approved workspace actions
Reconnect stability
Grace Period probes the old connection for 30s before replacing it, so vim/htop/yazi can survive short network drops
Pure Rust, native app
Tauri 2.0 native app, russh 0.59 compiled against ring, no Electron, no OpenSSL/libssh2 dependency
Credential safety
Passwords and API keys stay in OS keychain, saved connection metadata is sealed locally, and .oxide files use ChaCha20-Poly1305 + Argon2id encryption
Local PTY (zsh/bash/fish/pwsh/WSL2), SSH remote, local serial terminals, split panes, broadcast input, session recording/playback (asciicast v2), WebGL rendering, 30+ themes + custom editor, command palette (โK), zen mode, trzsz in-band file transfer
SSH & Auth
Connection pooling & multiplexing, ProxyJump (unlimited hops) with topology graph, auto-reconnect with Grace Period, Agent Forwarding. Auth: password, SSH key (RSA/Ed25519/ECDSA), SSH Agent, certificates, keyboard-interactive 2FA, Known Hosts TOFU
SFTP
Dual-pane browser, drag-and-drop, smart preview (images/video/audio/code/PDF/hex/fonts), transfer queue with progress & ETA, bookmarks, archive extraction
IDE Mode
CodeMirror 6 with 24 languages, file tree + Git status, multi-tab, conflict resolution, integrated terminal. Optional remote agent for Linux; unsupported architectures can self-build and upload
Port Forwarding
Local (-L), Remote (-R), Dynamic SOCKS5 (-D), lock-free message-passing I/O, auto-restore on reconnect, death reporting, idle timeout
AI (OxideSens)
Target-first assistant for saved connections, live SSH sessions, terminal buffers, SFTP paths, settings, and knowledge base entries; can diagnose remote output, run approved commands, inspect files, and explain failures without an OxideTerm account
Plugins
Runtime ESM loading, 18 API namespaces, 24 UI Kit components, frozen API + Proxy ACL, circuit breaker, auto-disable on errors
CLI
oxt companion: JSON-RPC 2.0 over Unix Socket / Named Pipe, status/health/list/session inspect/forward/config/connect/focus/attach/SFTP/import/AI, human + JSON output
Security
.oxide encrypted export (ChaCha20-Poly1305 + Argon2id 256 MB), encrypted local config at rest, OS keychain, Touch ID (macOS), portable encrypted keystore, host key TOFU, zeroize memory clearing
i18n
11 languages: EN, ็ฎไฝไธญๆ, ็น้ซไธญๆ, ๆฅๆฌ่ช, ํ๊ตญ์ด, FR, DE, ES, IT, PT-BR, VI
Under the Hood
OxideTerm keeps the product surface local-first, but the internals are built for SSH-heavy work. The full implementation notes are preserved below for readers who want the engineering details.
Architecture, SSH internals, reconnect, AI, forwarding, plugins, and more
Architecture โ Dual-Plane Communication
OxideTerm separates terminal data from control commands into two independent planes:
Data plane (WebSocket): each SSH session gets its own WebSocket port. Terminal bytes flow as binary frames with a Type-Length-Payload header โ no JSON serialization, no Base64 encoding, zero overhead in the hot path.
Control plane (Tauri IPC): connection management, SFTP ops, forwarding, config โ structured JSON, but off the critical path.
Node-first addressing: the frontend never touches sessionId or connectionId. Everything is addressed by nodeId, resolved atomically server-side by the NodeRouter. SSH reconnect changes the underlying connectionId โ but SFTP, IDE, and forwards are completely unaffected.
๐ฉ Pure Rust SSH โ russh 0.59
The entire SSH stack is russh 0.59 compiled against the ring crypto backend:
Zero OpenSSL dependencies โ the full crypto stack is Rust. No more "which OpenSSL version?" debugging.
Full SSH2 protocol: key exchange, channels, SFTP subsystem, port forwarding
ChaCha20-Poly1305 and AES-GCM cipher suites, Ed25519/RSA/ECDSA keys
Custom AgentSigner: wraps system SSH Agent and satisfies russh's Signer trait, solving RPITIT Send bound issues by cloning &AgentIdentity to an owned value before crossing .await
pub struct AgentSigner { /* wraps system SSH Agent */ }
impl Signer for AgentSigner { /* challenge-response via Agent IPC */ }
Platform support: Unix (SSH_AUTH_SOCK), Windows (\\.\pipe\openssh-ssh-agent)
Proxy chains: each hop independently uses Agent auth
Grace Period (30s): probe the old SSH connection via keepalive โ if it recovers (e.g., WiFi AP switch), your TUI apps (vim, htop, yazi) survive completely untouched
If recovery fails โ new SSH connection โ auto-restore forwards โ resume SFTP transfers โ reopen IDE files
Sidebar chat: persistent conversations with full history
Target-first workspace context: sees saved connections, live SSH sessions, terminal buffers, SFTP paths, settings, and knowledge base entries as workspace targets
Approved actions: can diagnose remote output, run approved commands, inspect files, and explain failures without requiring an OxideTerm account
MCP support: connect external Model Context Protocol servers (stdio & SSE) for third-party tool integration
RAG Knowledge Base (v0.20): import Markdown/TXT documents into scoped collections (global or per-connection). Hybrid search fuses BM25 keyword index + vector cosine similarity via Reciprocal Rank Fusion. Markdown-aware chunking preserves heading hierarchy. CJK bigram tokenizer for Chinese/Japanese/Korean.
Providers: OpenAI, Ollama, DeepSeek, OneAPI, or any /v1/chat/completions endpoint
Security: API keys stored in OS keychain; on macOS, key reads gated behind Touch ID via LAContext โ no entitlements or code-signing required, cached after first auth per session
๐ Port Forwarding โ Lock-Free I/O
Full local (-L), remote (-R), and dynamic SOCKS5 (-D) forwarding:
Message-passing architecture: SSH Channel owned by a single ssh_io task โ no Arc>, eliminating mutex contention entirely
Death reporting: forward tasks actively report exit reason (SSH disconnect, remote port close, timeout) for clear diagnostics
Auto-restore: Suspended forwards automatically resume on reconnect without user intervention
Idle timeout: FORWARD_IDLE_TIMEOUT (300s) prevents zombie connections from accumulating
๐ฆ trzsz โ In-Band File Transfer
Upload and download files directly through the SSH terminal session โ no SFTP connection required:
In-band protocol: files travel as base64-encoded frames inside the existing terminal stream โ works transparently through ProxyJump chains and tmux without extra ports or agents
Bidirectional: server runs tsz to send files to the client; trz triggers client upload; drag-and-drop supported
Directory support: recursive transfers via trz -d / tsz -d
Transfer limits: configurable per-session limits for chunk size, file count, and total bytes
Native Tauri I/O: file reads and writes use Tauri native file dialogs and Rust I/O โ no browser memory constraints
Live notifications: toast notifications for start, completion, cancellation, and errors โ including a hint when trzsz is detected but the feature is disabled
Enable in Settings โ Terminal โ In-Band Transfer
๐ Runtime Plugin System
Dynamic ESM loading with a security-hardened, frozen API surface:
24 UI Kit components: pre-built React components (buttons, inputs, dialogs, tablesโฆ) injected into plugin sandboxes via window.__OXIDE__
Security membrane: Object.freeze on all context objects, Proxy-based ACL, IPC whitelist, circuit breaker with auto-disable after repeated errors
Shared modules: React, ReactDOM, zustand, lucide-react exposed for plugin use without bundling duplicates
โก Adaptive Rendering
Three-tier render scheduler that replaces fixed requestAnimationFrame batching:
Tier
Trigger
Rate
Benefit
Boost
Frame data โฅ 4 KB
120 Hz+ (ProMotion native)
Eliminates scroll lag on cat largefile.log
Normal
Standard typing
60 Hz (RAF)
Smooth baseline
Idle
3s no I/O / tab hidden
1โ15 Hz (exponential backoff)
Near-zero GPU load, battery savings
Transitions are fully automatic โ driven by data volume, user input, and Page Visibility API. Background tabs continue flushing data via idle timer without waking RAF.
cargo build --no-default-features strips PTY for mobile/lightweight builds
๐ช Windows Optimization
Native ConPTY: directly invokes Windows Pseudo Console API โ full TrueColor and ANSI support, no legacy WinPTY
Shell scanner: auto-detects PowerShell 7, Git Bash, WSL2, CMD via Registry and PATH
And More
IDE Mode: CodeMirror 6 over SFTP, 24 languages, file tree with Git status, multi-tab, conflict resolution โ optional remote agent (~1 MB) for enhanced features on Linux
Resource profiler: live CPU/memory/network via persistent SSH channel reading /proc/stat, delta-based calculation, auto-degrades to RTT-only on non-Linux
Custom theme engine: 31 built-in themes, visual editor with live preview, 20 xterm.js fields + 24 UI color variables, auto-derive UI colors from terminal palette
Session recording: asciicast v2 format, full record and playback
Broadcast input: type once, send to all split panes โ batch server operations
Background gallery: per-tab background images, 16 tab types, opacity/blur/fit control
CLI companion (oxt): ~1 MB binary, JSON-RPC 2.0 over Unix Socket / Named Pipe, status/health/list/session inspect/forward/config/connect/focus/attach/SFTP/import/AI with human or --json output
OxideTerm uses the native WebView runtime provided by the operating system. Most users already have it installed; install these manually only if the app fails to launch or your environment is air-gapped.
Platform
Runtime Dependency
Windows
WebView2 Runtime โ pre-installed on Windows 10 (1803+) and Windows 11. For air-gapped / intranet environments, use the Evergreen Standalone Installer (offline, ~170 MB) or deploy the Fixed Version runtime via group policy.
macOS
None (uses native WebKit)
Linux
libwebkit2gtk-4.1 (usually pre-installed on modern desktops)
Portable Mode
OxideTerm supports a fully self-contained portable mode โ all data (connections, secrets, settings) is stored beside the application binary, making it suitable for USB drives or air-gapped environments.
Activation
Option A โ Marker file (simplest): create an empty file named portable (no extension) next to the app.
Platform
Where to place the portable file
macOS
Next to OxideTerm.app (its sibling directory)
Windows
Next to OxideTerm.exe
Linux (AppImage)
Next to the .AppImage file
/my-usb/
โโโ OxideTerm.app (or .exe / .AppImage)
โโโ portable โ empty file you create
โโโ data/ โ created automatically on first launch
Option B โ portable.json (custom data directory): place a portable.json in the same location:
{
"enabled": true,
"dataDir": "my-data"
}
enabled defaults to true if omitted
dataDir must be a relative path (no ..); defaults to data if omitted
How It Works
First launch โ a bootstrap screen prompts you to create a portable password. This password encrypts a local keystore (ChaCha20-Poly1305 + Argon2id) that protects all saved secrets.
Subsequent launches โ enter the password to unlock. On macOS with Touch ID, you can optionally bind biometric unlock in Settings โ General โ Portable Runtime.
Instance lock โ only one OxideTerm instance can use a portable data directory at a time (data/.portable.lock).
Management โ change the portable password or toggle biometric unlock in Settings โ General โ Portable Runtime.
Portability โ copy the entire folder (app + portable marker + data/) to another machine. The password travels with the keystore.
> [!TIP]
> Automatic updates are disabled in portable mode. To update, replace the application binary while keeping the data/ directory.
git clone https://github.com/AnalyseDeCircuit/oxideterm.git
cd oxideterm && pnpm install
# Build CLI companion (required for CLI features)
pnpm cli:build
# Full app (frontend + Rust backend with hot reload)
pnpm run tauri dev
# Frontend only (Vite on port 1420)
pnpm dev
# Production build
pnpm run tauri build
Tech Stack
Layer
Technology
Details
Framework
Tauri 2.0
Native shell with the operating system WebView
Runtime
Tokio + DashMap 6
Full async, lock-free concurrent maps
SSH
russh 0.59 (ring)
No OpenSSL/libssh2 in the SSH stack; SSH Agent
Local PTY
portable-pty 0.8
Feature-gated, ConPTY on Windows
Frontend
React 19.1 + TypeScript 5.8
Vite 7, Tailwind CSS 4
State
Zustand 5
19 specialized stores
Terminal
xterm.js 6 + WebGL
GPU-accelerated, 60fps+
Editor
CodeMirror 6
24 language modes
Encryption
ChaCha20-Poly1305 + Argon2id
AEAD + memory-hard KDF (256 MB)
Storage
redb 2.1
Embedded KV store
i18n
i18next 25
11 languages ร 22 namespaces
Plugins
ESM Runtime
Frozen PluginContext + 24 UI Kit
CLI
JSON-RPC 2.0
Unix Socket / Named Pipe
Project Scale
Measured with tokei, excluding dependencies and build artifacts.
Metric
Current Size
Total code
286K+
TypeScript / TSX
130K+
Rust
100K+
Frontend test code
24K+
Frontend test files
128
Source files (src + src-tauri/src)
664
Security
Concern
Implementation
Passwords
OS keychain (macOS Keychain / Windows Credential Manager / libsecret)
Portable Keystore
ChaCha20-Poly1305 encrypted vault beside the app, optional biometric binding via OS keychain
Rust-native migration via GPUI (Zed's GPU-accelerated framework) โ [in progress]
Support and Maintenance
Reproducible bug reports and regressions 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, plugin, or pull request all make the project easier to keep moving.
You are free to use, modify, and distribute this software under the terms of the GPL-3.0. Any derivative work must also be distributed under the same license.
OxideTerm changed from PolyForm Noncommercial 1.0.0 to GPL-3.0 starting with v1.0.0. We made this switch deliberately: no "open source" cosplay with noncommercial traps or no-competition riders, just clear copyleft freedom for users, forks, redistributors, and commercial operators.
Public code is not automatically open source. If a project advertises a familiar license while adding riders like "no redistribution", "no repackaging", "no competing products", or "no unauthorized distribution platforms", that is source-available branding, not the freedom users expect from open source. OxideTerm does not add no-compete or anti-redistribution riders: the GPL-3.0 terms are the terms.