DEV Community

Cover image for I just wanted Claude Code on my phone. 10 days and 2,000 downloads later, here's the story.
Chad
Chad

Posted on

I just wanted Claude Code on my phone. 10 days and 2,000 downloads later, here's the story.

Claude Relay on a phone — accessing Claude Code from anywhere

I didn't set out to build a developer tool. I just wanted to use Claude Code away from my desk.

This is how a personal workflow hack turned into an open-source project with 2,000+ npm downloads — and what I learned along the way.

Claude Code is already an app

Most people think of Claude Code as a coding tool. I saw something different: a runtime for a personal AI assistant.

Think about it. Claude Code already has everything you need — a conversational interface, file system access, persistent context through CLAUDE.md, custom slash commands, and the ability to read, write, and search across your entire project. It's not just a coding agent. It's a programmable chat application that happens to run in a terminal.

So instead of building an app with Claude Code, I decided to use Claude Code as the app.

I configured a CLAUDE.md that described my projects, my goals, my preferences, and my schedule. I added slash commands for recurring workflows — session management, project tracking, weekly reviews. I organized file-based knowledge across folders that it could search and reference.

The result was a personal assistant that remembered everything, understood my context deeply, and improved every time I refined the instructions. I canceled my ChatGPT Plus subscription and genuinely didn't miss it — not even the memory feature. This was better.

But it ran in a terminal. And I wanted it everywhere.

The problem: it lived on my desk

Claude Code runs in a terminal. Close the lid, and it's gone.

So I set up a dedicated MacBook in my garage as an always-on server. Amphetamine to prevent sleep, Tailscale for secure remote access, tmux to keep sessions alive. Then I'd SSH in from my phone using iSH.

It worked. I could reach Claude Code from anywhere over Tailscale.

But the experience had friction. iSH was surprisingly capable for a mobile terminal, but there were real limitations — copying images in tmux was painful, and the phone keyboard UX had a hard ceiling. It was functional, not comfortable.

I checked Claude's official app. The UI was nicer, but it required pushing code to GitHub and spinning up a virtual environment each time. Slash commands weren't fully supported. It wasn't the same setup I'd built.

The idea: cut the steps

What I really wanted was fewer steps.

Before:  phone → iSH → SSH → tmux attach → claude
After:   phone → tap bookmark → claude-relay
Enter fullscreen mode Exit fullscreen mode

A lightweight web server could do that. Relay the Claude Code session to a browser page, add it to my home screen, done.

Since I was already on Tailscale, I didn't need complex authentication — no cloud, no third-party auth. Just a simple PIN to keep it locked down. The whole thing could run locally.

spawn("claude") → stdout JSON stream → WebSocket → browser
Enter fullscreen mode Exit fullscreen mode

That's the first version. I spawned the claude CLI as a child process, parsed its stdout JSON stream line by line, and relayed everything to a browser page over WebSocket.

That's why it's called "relay."

8 days after the first commit, it was on npm.

What I didn't see coming

Here's the thing: I'm comfortable in the terminal. I use Claude Code for coding all day, but I'd also turned it into a personal assistant — project management, scheduling, note-taking, all through the same interface. For me, the terminal was fine. The relay server was just a way to access it when I was away from my desk — nothing more.

So when I shared it on Reddit, I wasn't expecting the feature requests I got:

  • "Can I get notifications when Claude needs approval?"
  • "Can I run multiple projects at once?"
  • "I want to use this for hands-off coding"

I hadn't considered any of these because they weren't my problems. But every single one was valid. These were developers using Claude Code differently than I was — as a coding assistant that needed babysitting. They wanted to walk away and come back when it was done.

That changed my perspective on what this tool could be.

20 stars and 1,876 downloads in the first week.

v2: From personal hack to developer tool

The stdout parsing approach had gotten me far, but it couldn't support everything Claude Code could do. I switched to the official Claude Agent SDK, which gave me full programmatic control — model switching, usage tracking, session compaction, the works.

But I was careful about one thing: don't break Claude Code.

I'm a terminal person. What feels like a convenience to me might break someone else's workflow. So the principle was: preserve the Claude Code experience exactly, and only add what the browser uniquely enables.

Push notifications

This was the feature that changed everything — and it wasn't even on my original list.

Claude needs approval → phone buzzes → tap approve → done
Enter fullscreen mode Exit fullscreen mode

No more walking back to check if Claude is waiting. No more losing 20 minutes of dead time because you forgot which terminal window it was in. The session keeps moving whether you're at your desk or not.

Push notification on phone — Claude needs your approval

I added PWA support so you could install it on your phone's home screen. The favicon blinks in the browser tab when a session needs attention. It fundamentally changed how people used Claude Code — from something you babysit to something that works alongside you.

The hardest part: onboarding

Building the notification itself was straightforward. The hard part was making sure people could actually set it up.

Push notifications require HTTPS. If you use Tailscale Pro, the certificate problem solves itself — but I didn't want to require a paid service for a free tool. So I went with mkcert for local certificate generation. Install the cert, trust it on your phone, done.

But "done" is doing a lot of heavy lifting there. How do you guide a user through certificate installation, PWA setup, and push permission — all from a CLI tool?

I built a multi-step onboarding flow directly in the terminal. It surveys your use case first (local only? remote access? mobile?), then gives you one task at a time based on your setup. Once the terminal steps are done, it shows a QR code that hands off to your phone for the remaining setup.

This was probably the feature I spent the most time on. Not the notification itself, but making sure anyone could actually get there.

Onboarding flow — QR code handoff from terminal to phone

File browser and terminal

I was still keeping VS Code open on the side — just for quick file checks and the occasional terminal command. Four-finger swipe to VS Code, glance at a file, swipe back. Dozens of times a day.

So I added a read-only file browser and a built-in terminal. Not a full IDE — just enough to check files and run commands without leaving the window.

I stopped opening VS Code. If I needed to edit a file directly, vim in the built-in terminal was enough.

The worktree revolution

Around this time, I switched my git workflow from git checkout to git worktree. Combined with claude-relay, the effect was dramatic.

My setup with Arc Browser: split each tab — claude-relay on the left, the dev server on the right. One saved tab per worktree. Switch between issues by switching browser tabs.

Now I had 4-5 branches running simultaneously. Claude working on a feature in one tab, fixing a bug in another, refactoring in a third. Browser notifications told me which one needed attention. Context switching dropped to near zero.

Arc Browser split view — claude-relay on the left, dev server on the right

The port problem

But managing all those sessions was getting messy. Each claude-relay instance needed its own port — 2633, 2635, 2637, hopping by twos. I'd forget which port mapped to which branch. Every new worktree meant opening a terminal, configuring the server, starting a dev server manually.

So I built a daemon. One port (2633), one process, managing everything. Projects register over Unix IPC, and the web UI routes via WebSocket paths. Add a project from the CLI, and it appears in the browser instantly.

multiple projects managed from one UI

Persistent terminals

The last piece. The built-in terminal was ephemeral — close the tab, lose the session. But I needed dev servers running per worktree, and I didn't want to remember which port was which.

I made the terminals persistent. Start a dev server in a terminal tab, close the browser, come back later — it's still running. Each project can have multiple named terminal tabs. The port management problem just... disappeared.

That's where we are now: v2.2.

What I learned

  1. Build for yourself first. The best tools come from genuine daily friction, not market research.
  2. Ship before it's ready. v1 was a single server.js. It was enough to validate the idea.
  3. Users see what you don't. I'm a terminal person — I never would have prioritized push notifications or hands-off mode. The community shaped this tool more than I did.
  4. Preserve the original experience. Adding features is easy. Not breaking existing workflows is hard.

Try it

npx claude-relay
Enter fullscreen mode Exit fullscreen mode

One command. No account, no cloud, no install. Everything runs on your machine.


What's your Claude Code setup like? I'm curious how others are working with it — especially if you've found ways to reduce the context-switching problem.

Top comments (0)