(updated )
4 min read
Mobile development with opencode

Seems like the hot new trend is writing code from your phone, and I wanted to share my setup as I’m quite fond of it and think other people might benefit from it too.
It’s built on a few basic building blocks and some small tweaks which make the experience quite nice as a whole.

Goals

  • Gain the superpower of a mid-prompt toilet break without fear of my agent derailing - be able to monitor its progress and steer it slightly if needed
  • Occasionally, actually code while on the go. I found it to be a great activity while resting between sets at the gym although it does tend to get my rest times higher

Non-Goals

  • Be completely independent from my computer
  • Delegate coding to some “cloud”, self-provisioned or not (I don’t want to have to mess with synchronizing state to more than one machine or constantly working remotely)
  • Reinvent the wheel

The Setup

  1. A tailnet with both devices connected to it
  2. shuvcode - an opencode fork with a enhancements such as the ability to install it as a PWA, create projects on the go and a few other tweaks for improving the experience on a mobile screen.
  3. A domain you control (optional, but a very nice improvement).

With our own domain, we can do this cool trick that allows us to name services on our computer instead of remembering arbitrary ports:

  1. Run the shuvcode server
  2. Add an A record for *.pc.ts.hasha.men pointing at your computer’s tailnet IP address (100.x.y.z) 1
  3. Set up caddy to reverse proxy from code.pc.ts.hasha.men to shuvcode

Running the server can be done like this:

bun run --cwd ~/Documents/oss/shuvcode/packages/opencode --conditions=browser src/index.ts serve --hostname 0.0.0.0 --port 4096

with the following Caddyfile:

(tls_config) {
	tls {
		dns cloudflare {env.CLOUDFLARE_API_TOKEN}
		propagation_timeout 5m
		propagation_delay 30s
		resolvers 8.8.8.8
	}
}

code.pc.ts.hasha.men {
	import tls_config
	reverse_proxy localhost:4096
}

You will need to use a DNS-01 challenge because the HTTP server cannot be accessed from outside the tailnet.

Then set up a shell alias to create TUI sessions in the running opencode instance instead of creating a new one:

oc() { bun run --cwd ~/Documents/oss/shuvcode/packages/opencode --conditions=browser src/index.ts attach http://localhost:4096 --dir "$PWD" "$@"; }

And.. surprisingly that’s about it. You can now visit code.pc.ts.hasha.men, install it as a PWA and enjoy the glorious shuvcode mobile UI. shuvcode's web ui, as it appears on mobile

Bonus: Mobile Mobile Development

One of the better uses for this setup is working on mobile apps, because after getting the hot-reload part right you can play with them while they’re being built. With Expo, it looks like this:

REACT_NATIVE_PACKAGER_HOSTNAME=pc.ts.hasha.men bun start --host lan

With prebuilt apps (as opposed to Expo Go builds) you might need to manually select the server. You can do so by pasting yourscheme://expo-development-client/?url=http://YOUR_IP:8081 into your favorite notes app and pressing it to launch your app.

Alternatives / Honorable Mentions

  • Happy
  • HAPI which is closer to this setup and actually looks like a neat project I didn’t know about initially
  • Companion with my TUI

Footnotes

  1. Alternatively, use Tailscale Serve or Tailscale Funnel but I like having it as a subdomain

⬆️ look up — yoavsh.ai — your new domain 🎉