v1.1.0 · Phase 4 in progress

DevNest documentation

A unified desktop control panel for developers and self-hosters. Manage Docker, SSH, metrics, files, terminals and more from one local-first Tauri app.

Tauri 2 React 19 TypeScript Rust Tailwind v4 SQLite Local-first

Introduction

DevNest gives developers a single window for all the operational tasks that usually mean jumping between a dozen terminal tabs. Every remote operation runs over a persistent SSH connection — no agent, no cloud relay, nothing leaves your machine.

Demo. Watch the full walkthrough on YouTube.

Guiding principles

  • Local-first. The UI and all data live on your machine; nothing reaches third parties.
  • No remote agent. Every remote operation is a plain SSH command. If it works over SSH, DevNest can surface it.
  • One persistent session per device. A single SSH connection is reused across all panels.
  • Atomic context switching. Selecting a device updates every open panel simultaneously.
  • Narrow vertical slices. Each release phase ships a working product, not a half-finished skeleton.

Tech stack

Layer Technology Purpose
Desktop shell Tauri 2 (Rust + WebView) Native window, system APIs, IPC bridge
Frontend React 19 + TypeScript UI rendering and state management
Styling Tailwind CSS v4 Utility-first CSS
State Zustand Global stores (app, theme, pane, SQL, HTTP)
Terminal @xterm/xterm Full PTY terminal emulator in the browser
Code editor Monaco Editor VS Code editor for file editing
Validation Zod Runtime schema validation
Local DB SQLite (tauri-plugin-sql) Device config, secrets, session state
SSH ssh2 Rust crate Persistent SSH connections, PTY, SFTP
Icons Lucide React Icon set
Markdown marked Live markdown rendering
Build Vite 7 + tsc Frontend bundler + type checker
Tests Vitest + Testing Library Unit and component tests

Architecture

DevNest is a Tauri app where the Rust backend owns all system access and the React frontend drives the UI. Communication flows exclusively through typed Tauri IPC commands.

┌─────────────────────────────────────────────────────────┐
│  React Frontend (WebView)                               │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐               │
│  │  Panels  │  │  Stores  │  │ Lib/Utils│               │
│  │ (panels) │  │ (store/) │  │  (lib/)  │               │
│  └────┬─────┘  └────┬─────┘  └──────────┘               │
│       │  invoke / listen  (Tauri IPC)                   │
└───────┼─────────────────────────────────────────────────┘
        │
┌───────▼─────────────────────────────────────────────────┐
│  Rust Backend  (src-tauri/src/)                         │
│  commands.rs    →  IPC entrypoint                       │
│  ssh.rs         →  Persistent SSH connection pool       │
│  sftp.rs        →  SFTP file operations                 │
│  terminal.rs    →  PTY over SSH (tmux sessions)         │
│  docker.rs      →  docker CLI over SSH                  │
│  metrics.rs     →  CPU / RAM / net / disk via SSH       │
│  git.rs         →  git operations over SSH              │
│  systemd.rs     →  systemctl over SSH                   │
│  tailscale.rs   →  tailscale CLI over SSH               │
│  ngrok.rs       →  ngrok tunnel management              │
│  http_client.rs →  outbound HTTP from Rust              │
│  sql.rs         →  SSH tunnel → remote DB               │
│  secrets.rs     →  OS keychain storage                  │
│  db.rs          →  local SQLite (device config)         │
└─────────────────────────────────────────────────────────┘

SSH session model

A single SSH connection per device is held in AppState. All panels that need remote access call run_remote_command(device_id, cmd) — they never open their own connections. The terminal panel uses a separate PTY channel (backed by tmux) so interactive sessions are independent of command execution.

Data flow

Secrets (SSH passwords, DB passwords, sudo passwords) are stored in the OS keychain via the keyring crate, never in SQLite plain text. Device metadata lives in a local SQLite database.

Roadmap

P0
Foundation Shipped
  • Tauri 2 + React + TypeScript + Vite scaffold
  • Tailwind CSS v4, ESLint, Prettier, Vitest
  • SQLite wired up via tauri-plugin-sql
  • App shell: sidebar, main panel, status bar
  • CI pipeline (lint + typecheck + build)
P1
MVP Shipped
  • SSH connection layer (ssh2 crate, persistent pool)
  • Device manager — add, edit, delete, online indicator
  • Docker panel — list, start/stop/restart/remove, logs
  • System metrics — CPU, RAM, disk, network, sparklines
P2
V1 Shipped
  • Multi-device tab management
  • Tailscale panel (device list, exit nodes)
  • xterm.js terminal with tmux session management
  • SFTP file browser + Monaco file editor
  • Toast alerts + native notifications
P3
V2 Shipped
  • Log viewer (tail -F, journalctl, docker logs, search)
  • Cron manager (read/write crontab, syntax validation)
  • Port scanner (ss -tlnp, process binding)
  • Process list (ps aux, kill with signal selector)
  • Systemd panel (unit list, start/stop/restart/enable)
  • SQL client (SSH tunnel → MySQL/PostgreSQL/SQLite)
  • HTTP client (multi-tab, history, JSON highlighting)
  • Ngrok tunnel manager
  • Git panel + Git graph visualization
  • Markdown viewer / editor
P4
Launch In progress
  • First-run onboarding wizard
  • Plugin API spec + reference plugin
  • Documentation site
  • Code signing (macOS + Windows)
  • Auto-update via Tauri updater
  • Launch assets

Prerequisites

Requirement Notes
Node.js 22+ Required for the Vite / React frontend build
Rust stable Install via rustup.rs
Linux libs libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libxdo-dev
macOS Xcode CLI tools — xcode-select --install
Windows Microsoft Visual Studio Build Tools

Installation

Run in development

git clone https://github.com/umerghafoor/DevDash
cd DevDash
npm install
npm run tauri dev

Build a release binary

# All platforms
npm run package

# Linux .deb only
npm run package:linux
Tip. Release builds for Linux (.deb, .rpm, .AppImage), macOS, and Windows are automatically published on every push to main via the CI pipeline.

Adding your first device

  1. Click + Add device in the sidebar.
  2. Enter a name, hostname or IP, SSH port (default 22), and username.
  3. Choose authentication — SSH key (path to private key) or password.
  4. Optionally enable Keep alive to auto-connect on startup.
  5. Optionally enable Use sudo for commands that require root. You'll be prompted once; the password is stored in the OS keychain.
  6. Click Connect — the status indicator turns green when the SSH session is established.
Localhost is available as a built-in device that bypasses SSH entirely and runs commands locally.

Panels

Each panel below is a self-contained feature surface that operates on the currently selected device.

Terminal

A full PTY terminal powered by xterm.js running over an SSH channel. Each terminal is backed by a tmux session so your shell survives reconnects.

Features

  • Multi-tab — multiple shells per device, multiple devices simultaneously
  • Persistent sessions — reconnecting reattaches the existing tmux session
  • Resize handling — SIGWINCH propagated on window resize
  • In-terminal search — Ctrl F opens a search bar (SearchAddon)
  • Clickable URLs — WebLinksAddon turns URLs into links
  • Completion notification — desktop notification when a long-running command finishes
  • Theme-aware — terminal colors inherit the app's active theme

Keyboard shortcuts

Shortcut Action
Ctrl F Toggle search
Ctrl Shift C Copy selection
Ctrl Shift V Paste

Docker

Manages Docker containers on the selected device via docker CLI commands over SSH.

  • Container list auto-refreshed every 5 seconds
  • Actions — start, stop, restart, remove (with confirmation)
  • Container logs — streamed live in-app
  • Sudo support — automatically prefixes sudo if enabled for the device
Note. If Docker requires sudo on your remote machine, enable Use sudo in the device settings.

Metrics

Real-time system metrics polled every 2 seconds while the panel is open, paused when hidden.

Metric Source Display
Overall CPU % /proc/stat Sparkline (60-point rolling history)
Per-core CPU % /proc/stat Per-core sparklines
RAM usage /proc/meminfo Used / total + sparkline
Disk usage df -h Bar per mount point
Network I/O /proc/net/dev Rx/Tx bps per interface + sparkline
CPU info /proc/cpuinfo Model, cores, frequency
RAM DIMMs dmidecode Module details (requires sudo)

File browser

A full SFTP file navigator that reuses the existing SSH session — no second connection needed.

  • Navigate directories, create folders, rename, delete files and directories
  • Upload files from your local machine
  • Download files to your local machine
  • Open any text file directly in the code editor panel
  • Remote file picker for selecting paths in other panels
  • Persistent current working directory across panel switches

Code editor

A full Monaco Editor (the engine behind VS Code) for editing remote files in-place. Files are fetched via SFTP, edited locally, and saved back on disk.

  • Syntax highlighting for all major languages
  • IntelliSense and bracket matching
  • JSON and YAML language support via CodeMirror modes
  • File size limit — files up to 2 MB are fully loaded
  • Save shortcut — Ctrl S / Cmd S

Git & Git graph

Run Git operations on a remote repository over SSH without needing to open a terminal.

  • View working tree status — staged, unstaged, untracked
  • Diff view for changed files
  • Stage, unstage, and commit changes
  • Push and pull
  • Branch list and switching
  • Git graph — visual commit history graph (separate panel)

Log viewer

Tail and search log files in real time, including structured sources like journalctl and Docker logs.

Sources

  • Arbitrary file paths via tail -F <path>
  • Systemd journal — journalctl -u <unit> -f
  • Docker container logs — docker logs -f <container>

Features

  • Live streaming with pause / resume
  • Search and filter by keyword
  • Line highlighting rules
  • Jump to bottom, copy individual lines

Systemd & services

Manage system services on systemd-based systems. The Services panel lists every service with quick start, stop, restart, enable and disable controls. The Systemd panel offers a more detailed unit-aware view with inline journal output.

Cron manager

Read and write the user's crontab via a form-based editor — no need to remember cron syntax.

  • Reads existing crontab with crontab -l
  • Form editor with fields for minute, hour, day, month, weekday, and command
  • Cron expression validation
  • Human-readable description of each schedule
  • Writes back with crontab -

Ports & processes

The Ports panel shows all listening TCP/UDP ports on the device (via ss -tlnp) alongside the process that owns each socket. The Processes panel lists running processes sorted by CPU or memory (via ps aux), each with a kill button and signal selector (SIGTERM, SIGKILL, …).

Tailscale

Control the Tailscale mesh network directly from DevNest.

  • Runs tailscale status --json to list all mesh peers
  • Shows IP, hostname, and online state per peer
  • Enable or disable exit nodes via tailscale set --exit-node=...
  • One-click SSH to this peer — pre-fills the device manager form
Note. The Tailscale CLI may require sudo or the tailscale group on some systems.

Ngrok

Manage ngrok tunnels running on the selected device. View active tunnels, their public URLs, and the local addresses they forward to.

HTTP client

A built-in REST client — similar to Insomnia or Postman — for testing APIs from within DevNest.

  • Multi-tab request history
  • All HTTP methods — GET, POST, PUT, PATCH, DELETE, …
  • Custom headers and request body
  • JSON response syntax highlighting
  • Persistent request history (Zustand store)

SQL client

Connect to a remote database through an SSH tunnel — the tunnel is opened automatically, no manual port forwarding needed.

Supported databases

  • MySQL / MariaDB
  • PostgreSQL
  • SQLite (file path on remote)

Features

  • SSH tunnel created per connection, torn down on disconnect
  • Database password stored in OS keychain
  • Multi-tab query editor
  • Result table with column sorting

Markdown

A split-pane Markdown editor with live HTML preview powered by marked. Write documentation, notes, or README files and see the rendered output in real time.

Project structure

DevDash/
├── src/                       # React frontend
│   ├── app/                   # App root (App.tsx, device heartbeat)
│   ├── components/            # Shared UI components
│   │   ├── AddDeviceDialog.tsx
│   │   ├── CodeEditor.tsx
│   │   ├── CommandPalette.tsx
│   │   ├── MainPanel.tsx
│   │   ├── Sidebar.tsx
│   │   ├── StatusBar.tsx
│   │   └── ...
│   ├── panels/                # Feature panels (one file per panel)
│   │   ├── DockerPanel.tsx
│   │   ├── TerminalPanel.tsx
│   │   ├── MetricsPanel.tsx
│   │   └── ...               # 19 panels total
│   ├── store/                 # Zustand global stores
│   │   ├── app-store.ts       # Devices, active device, tabs
│   │   ├── theme-store.ts     # Color theme
│   │   ├── http-store.ts      # HTTP client history
│   │   └── ...
│   └── lib/                   # Frontend utilities
│       ├── api.ts             # Typed wrappers over Tauri invoke()
│       ├── fuzzy.ts           # Fuzzy search (Command Palette)
│       └── ...
├── src-tauri/                 # Tauri + Rust backend
│   └── src/
│       ├── commands.rs        # All tauri::command handlers
│       ├── ssh.rs             # SSH connection pool
│       ├── sftp.rs            # SFTP operations
│       ├── terminal.rs        # PTY / tmux management
│       ├── docker.rs          # Docker CLI parsing
│       ├── metrics.rs         # System metrics parsing
│       └── ...
├── docs/
│   └── plans/                 # High-level plan + low-level TODO
└── public/                    # Static assets

Commands

Command Description
npm run tauri dev Start Tauri dev server with hot-reload
npm run dev Start Vite frontend only (no Tauri window)
npm test Run Vitest unit tests
npm run test:watch Vitest in watch mode
npm run lint ESLint (zero warnings policy)
npm run typecheck TypeScript type check (tsc --noEmit)
npm run format Prettier format all files
npm run format:rust cargo fmt --all
npm run fix Format JS/TS + Rust in one command
npm run package Build release binary for current platform
npm run package:linux Build Linux .deb only

Rust backend

# Format
cargo fmt --check --manifest-path src-tauri/Cargo.toml

# Lint
cargo clippy --all-targets -- -D warnings

# Test
cargo test --manifest-path src-tauri/Cargo.toml

Adding a new Tauri command

  1. Add the implementation in the relevant module (e.g. docker.rs).
  2. Expose it as a public function in commands.rs annotated with #[tauri::command].
  3. Register it in the .invoke_handler() call in lib.rs.
  4. Add a typed wrapper in src/lib/api.ts using invoke().

React frontend

Adding a new panel

  1. Create src/panels/YourPanel.tsx with a Props interface accepting deviceId: string.
  2. Register the panel in MainPanel.tsx — add it to the panel registry and sidebar tab list.
  3. Add any necessary Zustand store state in the appropriate store file.

State management

Store Purpose
app-store.ts Devices, active device ID, tabs, panel panes
theme-store.ts Active color theme and custom theme editor
colors-store.ts Raw color values derived from theme
http-store.ts HTTP client request / response history
sql-store.ts SQL client connections and query tabs
ui-store.ts Global UI state (modal open, sidebar width)
sudo-store.ts Sudo prompt visibility and callbacks
shortcuts-store.ts Keyboard shortcut registry
recents-store.ts Recently accessed files and paths
pane-settings-store.ts Per-pane device assignments
services-store.ts System service list cache
palette-store.ts Command palette state

Testing

Tests live in src/store/app-store.test.ts and src/test/setup.ts. The framework is Vitest with @testing-library/react.

npm test            # single run
npm run test:watch  # watch mode
Philosophy. Unit tests focus on Rust parsers (docker ps output, metrics, …). Integration tests use a Dockerized SSH server. UI components are tested with React Testing Library.

Releases & CI

Every push to main triggers the CI pipeline, which:

  1. Runs lint, typecheck, and all tests
  2. Builds release binaries for Linux (.deb, .rpm, .AppImage), macOS, and Windows
  3. Publishes a GitHub release with all installable artifacts

Current version — v1.1.0.