Linglix is an online 1‑to‑1 language tutoring service. This repository is the monorepo that hosts the production web app and shared UI library. It is built on Next.js (App Router + Turbopack), TypeScript, and a reusable design system powered by shadcn/ui-style primitives.
- Package manager: pnpm (workspaces)
- Monorepo task runner: Turborepo
- Web app: Next.js 16 (App Router, Turbopack)
- Language: TypeScript (strict)
- UI: React 19,
@workspace/uidesign system - Styling: Tailwind tokens via
@workspace/ui/globals.css - Testing:
- Unit: Jest (+ Testing Library)
- E2E: Playwright (
@linglix/e2e)
- Observability:
- Sentry (errors, performance, replays)
- PostHog (product analytics)
apps/
web/ # Next.js application
packages/
ui/ # Shared UI library and design system
e2e/ # Playwright end-to-end tests
eslint-config/ # Shared ESLint configs
typescript-config/ # Shared TS configs
config/jest/ # Shared Jest config
- Node.js ≥ 20
- pnpm (see
packageManagerfield inpackage.jsonfor the exact version)
pnpm installFrom the repo root:
pnpm devThis runs turbo dev and starts the Next.js app at:
Key scripts:
pnpm --filter web dev # next dev --turbopack
pnpm --filter web build # next build
pnpm --filter web start # next start
pnpm --filter web lint # eslint . --max-warnings 0
pnpm --filter web typecheck # tsc --noEmit
pnpm --filter web test # jest (currently passes with no tests)
pnpm --filter web test:e2e # run Playwright tests via TurborepoThe app imports all styling from the shared UI package:
- Global styles:
@workspace/ui/globals.css - Components:
@workspace/ui/components/*
Key points:
- React component library used by
apps/web - Exports:
./globals.css– base styles & design tokens./components/*– UI components (e.g.button)./lib/*,./hooks/*
Scripts:
pnpm --filter @workspace/ui lint
pnpm --filter @workspace/ui testEnd-to-end tests for the web app using Playwright.
Scripts:
pnpm --filter @linglix/e2e playwright install --with-deps # install browsers
pnpm --filter @linglix/e2e test:e2e # playwright test
pnpm --filter @linglix/e2e test:headed # headed mode
pnpm --filter @linglix/e2e test:ui # Playwright UI mode
pnpm --filter @linglix/e2e test:report # open last HTML reportThe Playwright config lives in:
packages/e2e/playwright.config.ts
By default:
- Locally: runs Chromium + WebKit
- CI: runs Chromium, Firefox, and WebKit (and retries are enabled)
From the repo root:
pnpm dev # turbo dev (local development)
pnpm build # turbo build (all packages)
pnpm lint # turbo lint (all packages)
pnpm turbo test # run Jest tests in web + uiEnd-to-end tests:
pnpm --filter @linglix/e2e playwright install --with-deps
pnpm turbo test:e2e --filter=@linglix/e2eThe app expects configuration via environment variables. Typical ones include:
NEXT_PUBLIC_POSTHOG_KEYNEXT_PUBLIC_POSTHOG_HOSTPOSTHOG_API_KEYPOSTHOG_HOSTSENTRY_DSNNEXT_PUBLIC_SENTRY_DSN
Create an .env.local in apps/web (or configure these in your deployment
platform) before running in production.
The repo
.gitignorealready excludes.env*files.
Sentry is wired via:
apps/web/instrumentation.tsapps/web/sentry.server.config.tsapps/web/sentry.edge.config.tsapps/web/instrumentation-client.ts
The DSN and behavior are controlled via environment variables and the current
NODE_ENV. Production defaults are tuned for lower sampling and no default PII.
PostHog analytics are initialized from apps/web/instrumentation-client.ts and
server helpers in apps/web/lib/posthog.ts (if present). The client only
initializes when NEXT_PUBLIC_POSTHOG_KEY is set, so missing configuration
does not crash the app.
The repo uses a shared ESLint configuration and Prettier.
Root package.json:
pnpm lint– runsturbo lintpnpm format– formats*.ts,*.tsx,*.mdwith Prettier
Lint-staged is configured to run ESLint/Prettier on changed files before commit.
GitHub Actions is configured to run:
- Unit tests (Jest) via
pnpm turbo test - E2E tests (Playwright) via
pnpm turbo test:e2e --filter=@linglix/e2e - Build & lint pipelines via Turborepo
Builds use Next.js with Turbopack and a shared Turborepo cache. Production builds are created by running:
pnpm turbo build --filter='...[origin/main]'This command is what CI uses before deploying.