- Expo - React Native framework with SDK 54
- Plasmo - Browser extension framework
- Next.js - React framework for the landing page and API routes
- tRPC v11 - Type-safe API layer
- Better Auth - Authentication
- Drizzle ORM - Database ORM
- Turso - Serverless SQLite database (libSQL)
- Turborepo - Monorepo tooling
- TypeScript - Type safety
- Tailwind CSS & NativeWind - Styling
The monorepo is organized using Turborepo and contains:
opentab/
├── apps/
│ ├── extension/ # Chrome extension
│ │ ├─ Plasmo framework
│ │ ├─ React 19
│ │ ├─ Tailwind CSS
│ │ └─ Typesafe API calls using tRPC
│ ├── native/ # React Native mobile app
│ │ ├─ Expo SDK 54
│ │ ├─ React Native using React 19
│ │ ├─ Navigation using Expo Router
│ │ ├─ Tailwind using NativeWind
│ │ └─ Typesafe API calls using tRPC
│ └── server/ # Next.js app
│ ├─ Landing page with marketing content
│ ├─ API routes (tRPC, auth, realtime)
│ └─ E2E Typesafe API Server & Client
├── packages/
│ ├── api/ # tRPC v11 router definition
│ ├── auth/ # Better Auth configuration
│ ├── config/ # Shared TypeScript configuration
│ └── db/ # Drizzle ORM with Turso (libSQL)- Bun installed
- Turso account and database created
- iOS/Android device or simulator/emulator (for native app)
git clone https://github.com/AugusDogus/opentab
cd opentab
bun installCopy the example env files and fill in your values for each app.
bun db:push# Start all apps
bun dev
# Or start specific apps
bun dev:extension # Chrome extension
bun dev:native # Expo app
bun dev:server # API serverFor the Chrome extension, load apps/extension/build/chrome-mv2-dev as an unpacked extension.
Note: This extension uses Manifest V2 with SSE for real-time tab delivery, targeting Helium browser. See why MV2 below.
# Development
bun dev # Start all apps in parallel
bun dev:extension # Start Chrome extension
bun dev:native # Start Expo app
bun dev:server # Start API server
# Database
bun db:push # Push schema changes to Turso
bun db:generate # Generate migrations
bun db:migrate # Run migrations
bun db:studio # Open Drizzle Studio
# Linting & Formatting
bun lint # Run oxlint and oxfmt
bun typecheck # Run TypeScript checks
# Building
bun build # Build all packagesThe browser extension uses Manifest V2 with a persistent background page to enable real-time tab delivery via Server-Sent Events (SSE). This is necessary because:
- Helium browser (the target browser) doesn't support Google's FCM/Web Push
- Manifest V3 service workers have a 30-second idle timeout and 5-minute connection limit, making SSE unreliable
- MV2's persistent background page keeps the SSE connection alive indefinitely
If you're using Chrome, the built-in "Send to your devices" feature is a better option.