A Progressive Web App (PWA) client for OpenCode - the open source AI coding agent.
- Connect to OpenCode Server: Configure and connect to your OpenCode server
- Session Management: Create, switch, and delete chat sessions
- Real-time Chat: Send messages and receive streaming AI responses via SSE
- Tool Call Visualization: View tool executions with collapsible output
- Permission Handling: Approve or deny permission requests from the agent
- Mobile Optimized: Touch-friendly UI with safe area support
- PWA Installable: Install as an app on your home screen
On your computer, run:
# Install opencode if you haven't
curl -fsSL https://opencode.ai/install | bash
# Start the server with CORS enabled
opencode serve --hostname 0.0.0.0 --port 4096 --cors http://localhost:5173# Clone and install
cd opencode-mobile
npm install
# Start development server
npm run devOpen http://localhost:5173 in your browser (or your mobile device on the same network).
- Enter your OpenCode server URL (e.g.,
http://192.168.1.100:4096) - Click "Check Connection" to verify
- Click "Connect"
To access OpenCode from anywhere (not just your local network), use one of these secure tunnel solutions:
# Install Tailscale on your server
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
# Install Tailscale app on your mobile device
# Then connect using your Tailscale hostname:
# http://your-machine.tailnet-name.ts.net:4096# Install cloudflared
brew install cloudflare/cloudflare/cloudflared # macOS
# or: sudo apt install cloudflared # Ubuntu
# Create tunnel
cloudflared tunnel create opencode
cloudflared tunnel route dns opencode opencode.yourdomain.com
# Run tunnel
cloudflared tunnel run --url http://localhost:4096 opencode# Install ngrok
brew install ngrok # macOS
# Expose server
ngrok http 4096npm run buildThe dist/ folder contains static files that can be deployed to:
- Vercel:
vercel deploy - Netlify: Drag & drop
dist/folder - GitHub Pages: Push to
gh-pagesbranch - Any static host: Upload
dist/contents
- HTTPS Required: For PWA features to work (install prompt, service worker), the app must be served over HTTPS
- CORS Configuration: Your OpenCode server must allow your PWA domain:
opencode serve --cors https://your-pwa-domain.com
- Mixed Content: An HTTPS PWA cannot connect to an HTTP server. Use a secure tunnel (Tailscale/Cloudflare) or deploy OpenCode server with HTTPS
┌─────────────────────────────────────────────────────────┐
│ Mobile PWA │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ ConnectRoute│ │SessionsRoute│ │ ChatRoute │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ │ │ │ │
│ └────────────────┼─────────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Zustand Store (appStore) │ │
│ │ - sessions, messages, parts, permissions │ │
│ └───────────────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ SDK Client │ │ ConnectionMgr │ │
│ │ (REST API) │ │ (SSE Events) │ │
│ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │
└──────────┬──────────┘
▼
┌───────────────────────────────┐
│ OpenCode Server │
│ (localhost:4096) │
│ - REST API │
│ - Server-Sent Events │
└───────────────────────────────┘
- React 19 - UI framework
- TypeScript - Type safety
- Tailwind CSS v4 - Styling
- Zustand - State management
- React Router - Navigation
- Vite - Build tool
- vite-plugin-pwa - PWA support
- @opencode-ai/sdk - OpenCode API client
# Start dev server
npm run dev
# Type check
npx tsc --noEmit
# Build for production
npm run build
# Preview production build
npm run previewopencode-mobile/
├── src/
│ ├── main.tsx # Entry point
│ ├── App.tsx # Root component with routing
│ ├── routes/
│ │ ├── ConnectRoute.tsx # Server connection UI
│ │ ├── SessionsRoute.tsx # Session list
│ │ └── ChatRoute.tsx # Chat interface
│ ├── components/
│ │ ├── layout/
│ │ │ └── TopBar.tsx
│ │ └── chat/
│ │ ├── MessageList.tsx
│ │ ├── MessageBubble.tsx
│ │ ├── Composer.tsx
│ │ ├── ToolCallCard.tsx
│ │ └── PermissionSheet.tsx
│ ├── lib/
│ │ ├── opencode/
│ │ │ ├── client.ts # SDK wrapper
│ │ │ ├── connection.ts # SSE manager
│ │ │ ├── events.ts # Event parsing
│ │ │ └── types.ts # Type definitions
│ │ └── storage/
│ │ └── settings.ts # localStorage wrapper
│ ├── state/
│ │ └── appStore.ts # Zustand store
│ └── styles/
│ └── index.css # Tailwind + custom styles
├── public/
│ └── icons/ # PWA icons
├── vite.config.ts
├── tsconfig.json
└── package.json
MIT