Blog

How Solavera puts a live preview next to your terminal, with nothing on your machine

One SSH connection to your machine, carrying three things at once: the terminal, the live preview, and the files your agent touches. That is the whole product. Here is how it fits together.

I run Claude Code from my phone. I SSH into my Mac over Tailscale, start the agent, and drive it from the couch, a parked car, or bed at 3am. The one part that never worked was seeing the result. The agent rebuilds your homepage and you read about it scrolling past in a terminal, when what you actually want is to look at the page.

The ways to see it are all bad. Expose a tunnel with ngrok or cloudflared and paste a fresh URL into a browser every session. Split-screen the terminal and Safari on a phone, where both halves are too cramped to use. Or deploy the branch, just to look at what changed. Every one of those is a detour around the thing you wanted, which was to glance at the render.

So I built the version where the page is right there, next to the terminal, on the phone. This is how it works.

One connection, three lanes

Solavera is one SSH connection to your machine. Not a relay, not a cloud service sitting in the middle, not an account you sign into. Your phone dials your machine directly, the same way you already reach it. The entire product is what that one connection carries.

The thing that makes it possible is old and boring. A single SSH connection can carry several independent channels at once. Solavera opens three of them.

  1. The terminal. A PTY channel, drawn by SwiftTerm. You run your agent, your dev server, anything. This is the part every SSH client already does.
  2. The preview. A port-forward. Your dev server is listening on something like localhost:5173 on the machine. Solavera forwards that port down to a port on the phone, and a web view loads it. The phone is loading http://localhost, pointed at your machine’s dev server, through the SSH channel. Nothing about it is public.
  3. The files. SFTP, on the same connection. When your agent writes a file, the app can read it and render it. When you circle a problem on the preview with your finger, the screenshot writes back to your machine as an image the agent can read.
Your iPhone one SSH connection Your machine
Terminal PTY your shell + agent
Preview port-forward localhost:5173
Files SFTP artifacts + annotations
Nothing installed on your machine but the SSH server it already has.

Nothing to install on your machine

The only thing running on your machine is sshd, the SSH server it already has. On a Mac you turn on Remote Login in Sharing, which is a toggle, not an install, and you add your key. That is the entire host setup.

That constraint shaped the build. The moment the preview needs its own process on your machine, you are back to installing and babysitting something, and you have traded one chore for another. Keeping everything on the single SSH channel is what makes the setup a toggle and a key instead of a project.

It slides over, it does not replace

The preview is a sheet that slides up over the terminal. At rest it sits at half height, so you see the agent working on top and your site rendering on the bottom. Swipe up and the preview fills the screen in a clean mobile view. The terminal stays live underneath the whole time. You are never choosing between the session and the render. You have both, and you move between them with a gesture.

Live, not deployed

The forward is a transparent TCP pipe, so your dev server’s hot reload travels over it like everything else. You tell the agent to change something, it edits a file, the dev server pushes the update across the SSH channel, and the web view repaints. You did not reload. You did not redeploy. You did not paste a new tunnel URL. The page just changes, a second or so after the agent does.

That feedback loop is the entire reason the thing exists. Watching the render keep pace with the agent is a different experience from reading a diff and imagining it.

What happens if I lose signal or close the app?

The connection dies when iOS suspends the app or you walk out of wifi range. That sounds like a problem. It mostly is not, because of how the pieces are split.

Claude Code’s supervisor keeps the agent’s work running on your machine whether or not your phone is attached. So when the app comes back, its job is not to recreate anything. It re-dials the SSH connection, re-opens the port-forward, and re-attaches. The agent’s progress was never in the app to begin with. It was on your machine the whole time.

The one thing the supervisor does not cover is your own shell. The directory you were in, your scrollback, a npm run dev you started by hand. So there is an opt-in switch that wraps your session in tmux. Turn it on and your shell survives the disconnect with everything else. Reconnect and you land exactly where you left off. tmux is your own install on your own machine. The app never puts it there, it just uses it if you have it on.

What it’s built on

I built it on Citadel, a pure-Swift SSH library. It exposes the PTY and the port-forward as plain async calls, two channels over one connection, with no C plumbing to hand-write.

Before I built the real app I spiked the whole loop on real hardware: ed25519 auth, the terminal, the forward, and a web view rendering a live Vite dev server with hot reload, on cellular with wifi turned off, for half an hour straight, to be sure the connection held. It did. Then I built the rest.

That is the whole architecture. One connection, three lanes, and nothing on your machine but the SSH server that is already there.

FAQ

Do I need to set up a tunnel to see my dev server on my phone?

No. The preview travels over your existing SSH connection as a local port-forward. Your dev server stays bound to localhost on your machine and nothing is ever exposed publicly. There is no ngrok, cloudflared, or public URL to manage.

What do I have to install on my machine to use Solavera?

Nothing. On a Mac you turn on Remote Login, which is a toggle in macOS Sharing, and add your SSH key. There is no daemon, menu-bar app, or host agent. The preview rides the same SSH connection the terminal already holds, so it needs no service of its own.

How does the preview update without redeploying?

Your dev server's hot reload runs over the forwarded port like any other traffic. When your agent edits a file, the dev server pushes the update across the SSH channel and the in-app web view repaints. No deploy, no manual refresh, no rebuilding a tunnel URL.

What happens to my session if I lose signal or close the app?

Claude Code's supervisor keeps the agent's work running on your machine whether or not the app is attached. On reconnect, Solavera re-dials, re-opens the port-forward, and re-attaches. Turn on the optional tmux session and your shell, scrollback, and dev server survive the disconnect too.