Lingdb is a modern, full-stack language-learning platform inspired by Quizlet. It allows users to create multilingual dictionaries, manage word lists with drag-and-drop, and study using interactive flashcards and quiz tools. The app also features AI-powered word suggestions and example phrase generation. You can invite a friend to co-create a dictionary together!
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Database: Supabase (PostgreSQL)
- ORM: Drizzle ORM
- Styling: Tailwind CSS 4
- Animations: GSAP v3.15
- Server State: TanStack Query (client caching, invalidation, mutations, hydration)
- Authentication: Supabase Auth (+ Google OAuth)
- Internationalization: next-intl
| Package | Purpose |
|---|---|
| Zod | Runtime schema validation for API inputs and form data, ensuring type safety and data integrity. |
| Jest & Playwright | A combination of unit/component testing (Jest) and End-to-End browser testing (Playwright). |
| Drizzle ORM | A lightweight, TypeScript-first ORM used for interacting with the PostgreSQL database. |
| TanStack Query | Handles server-state caching, query invalidation, mutation flows, and hydration for faster UX. |
| Inngest | Handles background processing, cron jobs, and event-driven workflows (e.g., sending reminder emails). |
| OpenAI | Powers the AI word suggestions and example phrase generation features. |
| next-intl | Manages the application's multi-language support (English, French, German, Spanish, Turkish). |
- Lingdb uses TanStack Query as the default client-side server-state layer.
- Use the shared query key factory in
src/lib/tanstack/query-keys.ts. - Use API wrappers in
src/lib/api/*instead of direct component-levelfetchcalls. - Use
useQueryfor reads anduseMutationfor writes. - Invalidate only affected keys after mutations for predictable updates.
- Prefer hydrated initial data on pages that already fetch on the server.
- Query provider/client/defaults:
src/lib/tanstack/query-provider.tsx,src/lib/tanstack/query-client.ts,src/lib/tanstack/query-defaults.ts - Query keys:
src/lib/tanstack/query-keys.ts - Hydration helpers:
src/lib/tanstack/hydration.ts
- pnpm installed.
- A Supabase project for Auth and Database.
- An OpenRouter API key for AI features.
-
Clone the repository:
git clone <your-repo-url> cd lingdbapp
-
Install dependencies:
pnpm install
-
Setup Environment Variables: Create a
.env.localfile in the root directory and populate it with the required values (see the table below). -
Database Migration: Push the schema to your Supabase database:
pnpm run db:push
Or run migrations if you have existing migration files:
pnpm run db:migrate
-
Run the Development Server:
pnpm dev
Open http://localhost:3000 with your browser to see the result.
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string for Drizzle. |
NEXT_PUBLIC_SUPABASE_URL |
Your Supabase project URL. |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Your Supabase anonymous key. |
SUPABASE_SERVICE_ROLE_KEY |
Supabase service role key for admin tasks. |
OPENROUTER_API_KEY |
Your OpenRouter API key. |
OPENROUTER_PRIMARY_MODEL |
Primary OpenRouter model ID (default: mistralai/mistral-small-creative). |
OPENROUTER_FALLBACK_MODEL |
Fallback OpenRouter model ID used when primary is unavailable. |
GOOGLE_OAUTH2_CLIENT_ID |
Client ID for Google Authentication. |
GOOGLE_OAUTH2_CLIENT_SECRET |
Client Secret for Google Authentication. |
NEXT_PUBLIC_APP_URL |
The base URL of your application (e.g., http://localhost:3000). |
Run unit tests with Jest:
pnpm testRun E2E tests with Playwright:
npx playwright test