meatshell
简体中文 | English
A lightweight, low-memory SSH / terminal client inspired by FinalShell, but written entirely in Rust + Slint. The goal is to keep FinalShell's core experience (resource-monitor sidebar, session management, tabbed terminals) while cutting memory use from the 400 MB+ of a JVM app down to the tens-of-MB range of a native binary.
Screenshots

Welcome page: session management + local resource monitor sidebar

Tabbed terminal (full-screen btop) + SFTP file browser + remote resource monitoring
Download & install
Every pushed v* tag triggers a Gitea Actions build that produces the Windows
GNU package and publishes it on the
Releases page.
Windows
Download meatshell-*-windows-x86_64.zip, unzip, and run meatshell.exe.
At runtime, meatshell-debug.log is written next to meatshell.exe; check it first for SSH connection crashes or unexpected exits.
Linux
tar -xzf meatshell-*-linux-x86_64.tar.gz
cd meatshell-*-linux-x86_64
./meatshell # run it directly
# Optional: install the app icon + launcher entry (shows the icon in the dock /
# app list — no argument needed, it finds the binary next to the script)
chmod +x install-linux.sh && ./install-linux.sh
Requires glibc ≥ 2.35 (Ubuntu 22.04+ / Debian 12+). On Wayland you may need to log out/in once after installing the icon.
macOS
tar -xzf meatshell-*-macos-*.tar.gz # aarch64 = Apple Silicon, x86_64 = Intel
xattr -dr com.apple.quarantine meatshell # clear the "unsigned app" Gatekeeper flag
./meatshell
To build from source, see Running below.
Roadmap
v0.1
- FinalShell-style dark theme UI
- Local system monitor sidebar (CPU / memory / swap / network throughput, 1 Hz)
- Tabs (welcome page + multiple terminal sessions)
- Session management: create / edit / delete, persisted to local JSON
- Config location:
%APPDATA%/meatshell/sessions.json(Windows) /~/.config/meatshell/sessions.json(Linux) /~/Library/Application Support/meatshell/sessions.json(macOS)
- Config location:
- SSH connection scaffold (
russh, pure Rust, password + private key) - Raw PTY input + VT/ANSI terminal view
v0.2
- Full VT/ANSI terminal emulation (
vt100/xterm parser, full-screen TUI, scrollback, find, select-copy) - Remote host resource monitoring (run a remote collector script, like FinalShell)
- SFTP file browser + drag-and-drop upload/download
- Known-hosts (
known_hosts) verification (TOFU into the app known_hosts, reject changed keys) - Store session passwords in the OS keychain (encrypted config fallback when unavailable)
v0.3+
- Split panes for tabbed terminals
- Session groups / folders
- Theme switching (light / follow system)
- Command history & snippet management
Tech stack
| Module | Choice |
|---|---|
| UI | Slint (compiled pure Rust, no GC) |
| Async runtime | tokio |
| SSH protocol | russh (no libssh dependency) |
| System metrics | sysinfo |
| Serialization | serde + serde_json |
| Logging | tracing + tracing-subscriber |
Running
cargo run --release
On first launch an empty session store is created at
%APPDATA%/meatshell/sessions.json. Click "+ New Session" in the top-right
to add your first server.
Project layout
meatshell/
├── Cargo.toml
├── build.rs # Slint compiler entry point
├── ui/
│ ├── app.slint # top-level window
│ ├── theme.slint # design tokens
│ ├── widgets.slint # reusable buttons / inputs / sparkline
│ ├── sidebar.slint # left-hand system monitor panel
│ ├── tabs.slint # top tab bar
│ ├── welcome.slint # welcome page / quick connect
│ ├── session_dialog.slint # new / edit session dialog
│ └── terminal_view.slint # VT/ANSI terminal view + command bar / SFTP panel
└── src/
├── main.rs
├── app.rs # UI ↔ backend bridge
├── config.rs # session JSON persistence
├── keychain.rs # OS keychain password storage + encrypted fallback
├── known_hosts.rs # OpenSSH known_hosts verification
├── system.rs # CPU / memory / network sampling
├── ssh.rs # SSH session worker
└── sftp.rs # SFTP browser / transfer worker
Development notes
- Slint widgets use a strict layout DSL; after editing a
.slintfile,cargo checkis the fastest feedback loop. - The application event loop is single-threaded (required by Slint); all
cross-thread UI updates go through
slint::invoke_from_event_loopcallbacks. known_hostsuses trust-on-first-use (TOFU): first connections are written to meatshell's ownknown_hosts; later server-key changes are rejected.- Session passwords prefer the OS keychain; when no keychain backend is available, meatshell falls back to local ChaCha20-Poly1305 encrypted config.
License
Dual-licensed under MIT OR Apache-2.0.