Dinotty: a self-hosted terminal server for AI coding agents
Multi-device terminal server for AI coding agents. Server-side VTE, session persistence, file browser, web preview, plugin system. Self-hosted.
At a glance
- What is it?
- Dinotty keeps Claude Code, Codex, opencode and OpenClaw sessions alive on the server and renders them as text on any device. It is a good fit if you move between phone and desktop mid-task, and a poor one if you want a plain SSH client.
- Who is it for?
- Adopt Dinotty if you already run coding agents in a terminal and want the same session reachable from a phone, a tablet and a desktop without a remote desktop protocol in between. Skip it if you only need a local terminal, or if you cannot run a persistent server process that holds your PTYs.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Dinotty targets: agent sessions that die with the window
Coding agents such as Claude Code, opencode, Codex and OpenClaw run inside a terminal. That terminal is usually bound to one machine and one window. Close the laptop lid, lose Wi-Fi on the train, or switch to a phone, and the process is gone or unreachable. Dinotty's stated goal is to remove that binding: the README describes it as "A terminal built for coding agents" and promises "One session across phone, iPad and desktop".
The intended user is someone who already works with a terminal-based agent and wants to keep a task moving across devices. The README's own example is stopping mid-task on a computer, continuing on a phone, then returning to the desktop "exactly where you left off". This is not a general-purpose SSH replacement and not a remote desktop. The README draws that line itself in a comparison table, arguing that Dinotty sends text (JSON and bytes) while VNC, RDP and Parsec send full screen pixels.
It is also explicitly self-hosted. The philosophy section says "Self-hosted. No subscriptions. No relay. Your data stays on your machine." The server is the product; the clients are views onto it.
How Dinotty works: server-side VTE, PTYs and pane-based layout
The architecture is visible in the repository layout and the Cargo manifest. The workspace has a single member, src-tauri, and the root package is named dinotty-server. It depends on axum 0.7 with the ws and macros features, tokio with the full feature set, and portable-pty 0.8 for pseudo-terminal allocation. The terminal emulation itself comes from the vte crate (0.13), which is the parser behind the claim of a "full VTE parser" running on the server.
That choice drives everything else. Because the server parses the escape sequences, it holds the authoritative screen state rather than the browser. The README says this "enables session recovery & screen snapshots". The PTY process is owned by the server, so a disconnecting client does not kill it; the README states that PTY processes survive disconnection and that refreshing the page restores the view, with auto-reconnect using exponential backoff.
Above the terminal layer sits a pane model. Terminals, plugins, files, SSH connections and web previews are all panes, and the README describes dragging them to assemble a workspace, with splits, cross-tab moves and extraction into a new tab. State is grouped into workspaces with a Mission Control overview, and the README notes that plugin tabs are workspace-scoped.
The frontend is Vue 3 with xterm in the topic list, built as a separate workspace alongside a Tauri-based desktop client (src-tauri, .taurignore) and an android-app directory. The server embeds static assets through rust-embed, and there is a plugin-api directory plus a seed directory in the tree. A bench directory exists, but the README publishes no benchmark numbers, so the bandwidth figures in its comparison table (roughly 1 to 10 KB/s) should be read as the project's own claim, not a measurement you can check from the repository.
Installing Dinotty and running a first agent session
The README does not contain an install section, and the repository files given here do not include a documented build or release procedure for the server. There is a deploy directory, a scripts directory, and a homepage at dinotty.com, and the README links to documentation at xichan96.github.io/dinotty. Those are the places the project points to for setup; the commands below are the ones the repository itself defines, not an invented install path.
The root package.json is for the documentation site only. It is marked private and its scripts run VitePress, so do not mistake it for the application build:
{
"name": "dinotty-docs",
"private": true,
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs --port 4173"
}
}Running pnpm docs:dev from the repository root serves the documentation locally. That tells you what the project documents, not how the server is deployed.
The Rust side is a Cargo workspace whose only member is src-tauri, and the workspace version is 0.28.0, matching the v0.28.0 release. Because the workspace has one member, the standard Cargo entry point builds the src-tauri package, which is where the Tauri desktop shell lives. The dinotty-server package declared in the root Cargo.toml carries the axum, tokio and portable-pty dependencies, so treat the two as one codebase rather than two independently installable products.
For a first real use, the workflow the README describes is: start the server, open the web UI, create a terminal pane, and launch an agent such as Claude Code inside it. Then disconnect deliberately. Close the browser tab, reopen it, and the session should come back with the agent still running. That refresh test is the one behaviour worth confirming before you build anything on top of it.
Where Dinotty is the wrong tool
Dinotty assumes a long-running server process that owns your PTYs. If that process dies, the sessions it held die with it unless the project has persistence you can verify; the README documents survival of client disconnection and page refresh, and does not document server restart recovery. Anyone who needs agent sessions to outlive a host reboot should confirm that separately, because the README is silent on it.
The security model is also thin in what is published here. The README says data stays on your machine and that there is no relay, which is a statement about topology, not about authentication. The Cargo manifest includes cookie support through axum-extra and hashing crates (sha2, sha1, md-5, hmac), but the README does not describe an authentication flow, TLS termination, or how a server exposed beyond localhost should be protected. If you plan to reach the server from a phone over the internet, that gap is the thing to resolve first, and the repository files given here do not resolve it.
Finally, Dinotty is not a general terminal multiplexer replacement for people who are happy with SSH. If your workflow is one laptop, one terminal, and no need to switch devices, the pane system, the plugin API and the VTE layer are overhead. The project is aimed at a specific pattern: an agent running somewhere persistent, viewed from wherever you happen to be.
Dinotty compared with tmux over SSH
The nearest thing most engineers already use is tmux on a remote host, reached over SSH. Both keep a process alive after the client disconnects, and both let you reattach later. The difference is where the terminal state lives and what the client has to be.
With tmux, the client is a terminal emulator on your machine. It receives raw escape sequences and renders them locally. On a phone, that means an SSH client plus a terminal app, and the experience depends on how well that app handles a small screen, a software keyboard and agent TUIs. Dinotty moves the emulation to the server with the vte crate, so the client receives a screen state it can render as text at any size. That is the mechanism behind the README's claim of "Native text at any size" against "Scaled bitmap, blurry on phone" for remote desktop tools, and it is also what makes the file browser, web preview and plugin panes possible in the same interface.
The trade is control and simplicity. tmux is a small, well-understood program you install with your package manager; Dinotty is a Rust server, a Vue frontend, a Tauri desktop client and a plugin runtime. You get panes, SFTP browsing and a mobile-friendly UI; you take on a larger surface to build, deploy and secure. If you already have tmux and a terminal you like on every device, Dinotty does not obviously improve your day. If your phone is where you want to check on an agent, the server-side VTE is the part tmux cannot give you.
Maintenance, releases and the MIT licence
The repository is not archived, and the last push was on 2026-09-15. Releases are frequent and versioned: v0.26.0 on 2026-09-10, v0.27.0 on 2026-09-14, and v0.28.0 on 2026-09-15. The workspace version in Cargo.toml is 0.28.0, so the Rust workspace and the release tag move together. That cadence means upgrade cost is real: expect to rebuild or re-pull regularly rather than pinning once and forgetting it.
Upgrading means rebuilding the Rust workspace and, for the desktop client, the Tauri application; the frontend is a separate pnpm workspace (pnpm-workspace.yaml, pnpm-lock.yaml). Because the server owns long-lived PTY processes, an upgrade is a restart of the thing holding your sessions. The README does not document a rolling upgrade, a drain mode, or session migration across restarts, so plan upgrades around your agent runs rather than during them.
The licence is MIT, declared in both the LICENSE file and the Cargo workspace package metadata. MIT is permissive: you can use, modify and redistribute the code, including commercially, provided the copyright notice and permission notice are retained. It offers no patent grant and no warranty. That is a description of the licence text, not legal advice; if you are embedding Dinotty in a product, have someone qualified read the terms.
One more cost worth naming: the plugin system is JavaScript with hot reload, and the README lists built-in plugins including CC Switch and JSON Formatter. Plugins run inside your server process and can subscribe to terminal events and execute commands. There is no sandboxing described in the README, so treat third-party plugins as code you are choosing to run.
Editorial conclusion
Adopt Dinotty if you already run coding agents in a terminal and want the same session reachable from a phone, a tablet and a desktop without a remote desktop protocol in between. Skip it if you only need a local terminal, or if you cannot run a persistent server process that holds your PTYs. Before committing, verify three things on your own machine: that the server starts and the web UI loads, that a session survives a browser refresh, and that the build path you intend to use (source or packaged client) is documented for your platform.
Frequently asked questions
What is Dinotty and who is it for?
Dinotty is a self-hosted, multi-device terminal server for AI coding agents such as Claude Code, opencode, Codex and OpenClaw. It is aimed at people who run those agents in a terminal and want the same session available from a phone, a tablet and a desktop.
Does a Dinotty session survive a browser refresh or a disconnect?
The README states that PTY processes survive disconnection and that refreshing the page restores the session, with auto-reconnect using exponential backoff. It does not document what happens to sessions when the server process itself restarts.
How do I install Dinotty?
The README does not include install steps; it links to the project documentation and the deploy and scripts directories in the repository. The Rust side is a Cargo workspace whose only member is src-tauri, so a source build goes through Cargo, and the root package.json only builds the documentation site.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/xichan96-dinotty)