An open-source language learning platform built to help learners practice real English in realistic situations. The project combines an AI-powered web experience, a mobile app, and a shared TypeScript backend so new features can ship across platforms without duplicating business logic.
Most language products are either too generic, too game-like, or too disconnected from real conversation. This project focuses on practical learning:
- AI conversations for speaking practice
- instant feedback on grammar and fluency
- pronunciation support
- vocabulary review and spaced repetition
- adaptive lessons and progress tracking
- shared infrastructure for web, mobile, auth, payments, email, and data
- Cross-platform: web app, API server, and Expo mobile app in one monorepo
- Type-safe end to end: TypeScript, tRPC, shared packages, and Zod validation
- AI-assisted learning: OpenAI-powered practice flows and translation features
- Speech and audio workflows: pronunciation and speaking support
- Production-oriented foundation: auth, database, email, storage, and payments already wired in
- Designed for iteration: Turborepo + pnpm workspace structure for faster development
- Web: React 19, Vite, TanStack Start, Tailwind CSS
- Server: Hono, tRPC, Node.js, Better Auth
- Mobile: Expo, React Native, Expo Router
- Database: PostgreSQL + Drizzle ORM
- Validation: Zod
- Tooling: pnpm, Turborepo, Biome, TypeScript
- Integrations: OpenAI, Deepgram, Cloudflare R2, Paddle, AutoSend
.
βββ apps/
β βββ web/ # React + TanStack Start frontend
β βββ server/ # Hono + tRPC API server
β βββ native/ # Expo / React Native app
βββ packages/
β βββ api/ # Shared API routers, services, and domain logic
β βββ auth/ # Better Auth configuration and auth helpers
β βββ db/ # Drizzle schema, DB client, and migration scripts
β βββ env/ # Shared environment validation
β βββ email/ # Email helpers and templates
β βββ i18n/ # Translation tooling and dictionaries
βββ package.json # Root scripts and workspace configuration
apps/webandapps/nativeconsume shared code frompackages/*apps/serverexposes the backend API and integrates auth, payments, AI, storage, and background workflowspackages/apikeeps business logic and API contracts reusable across clientspackages/db,packages/auth, andpackages/envcentralize the sensitive parts of the stack so behavior stays consistent everywhere
Before running the project locally, make sure you have:
- Node.js 20+
- pnpm 10.2+
- PostgreSQL
- Optional accounts or API keys for the integrations you want to test locally
pnpm installUse the example files as your starting point:
apps/server/.env.exampleapps/web/.env.exampleapps/native/.env.example
cp apps/server/.env.example apps/server/.env
cp apps/web/.env.example apps/web/.env
cp apps/native/.env.example apps/native/.envAt minimum, you will usually need:
- a PostgreSQL connection string
- Better Auth secrets and base URL
- the web and native app server URLs
If you want full feature parity locally, also configure the optional integrations for AI, storage, email, and payments.
pnpm db:pushThis applies the current Drizzle schema to your configured database.
pnpm devTypical local targets:
- Web app: Vite dev server from
apps/web(configured on port3001) - API server: Hono server from
apps/server(commonly port3000) - Mobile app: Expo dev server from
apps/native
If you only need one surface, you can run it independently:
pnpm dev:web
pnpm dev:server
pnpm dev:native| Command | What it does |
|---|---|
pnpm dev |
Run all app dev tasks through Turbo |
pnpm build |
Build the workspace |
pnpm check-types |
Run TypeScript checks across the workspace |
pnpm dev:web |
Start only the web app |
pnpm dev:server |
Start only the API server |
pnpm dev:native |
Start only the Expo app |
pnpm db:push |
Push the Drizzle schema to the database |
pnpm db:generate |
Generate Drizzle migrations |
pnpm db:migrate |
Run Drizzle migrations |
pnpm db:studio |
Open Drizzle Studio |
pnpm check |
Run Biome with --write across the repo |
There is no single repo-wide test command set up yet, so use the smallest relevant check for the area you changed:
- Server changes:
pnpm -F server check-types - Web changes:
pnpm -F web build - Shared package changes:
pnpm check-types
Note that pnpm check is a write command because it runs biome check --write ..
- Make your changes in the relevant app or package.
- Run targeted validation for the code you touched.
- Keep shared logic in
packages/*when it is used by more than one app. - Be careful with auth, env, and database changes because they affect multiple surfaces.
Contributions are welcome.
If you want to open a PR, a good default workflow is:
- Fork the project and create a feature branch.
- Keep changes focused and easy to review.
- Run the relevant validation commands before submitting.
- Include setup notes or screenshots when changing developer experience or UI.
Areas where contributions are especially valuable:
- learner experience and onboarding
- lesson generation and feedback quality
- mobile polish
- documentation
- tests and CI coverage
- accessibility and internationalization
A large part of the system is driven by server-side environment variables. The server env controls important integrations such as:
- database access
- Better Auth
- Cloudflare R2 storage
- OpenAI and Deepgram
- AutoSend email delivery
- Paddle billing
If something fails during local setup, the first thing to verify is usually the relevant .env file.
This repository started from the excellent Better-T-Stack and has been expanded into a multi-app product architecture.