Cover Letter Studio is a TanStack Start app for generating tailored cover letters from a resume and a pasted job description.
It uses:
- WorkOS AuthKit for authentication
- Convex for user data, application history, and resume file storage
- Oxlint + oxfmt for linting and formatting
- OpenRouter through the AI SDK for generation
- resume upload as
.txt,.pdf,.png,.jpg,.jpeg, or.webp - authenticated per-user workspaces
- resume parsing and OCR
- blocker detection against job requirements
- exactly 5 generated cover letter variants
- variant selection, editing, copy, and download
- saved resumes and application history in Convex
- TanStack Start + React 19
- shadcn UI
- Bun for dependency management
- pnpm for running project scripts
- Convex
- WorkOS AuthKit
- OpenRouter through the AI SDK
bun installUse Bun for dependency changes too:
bun add <package>
bun remove <package>
bun updateDo not run pnpm install, npm install, or yarn install in this project. The bun.lock file is the only dependency lockfile.
Copy the example env file:
cp .env.example .envRequired values:
VITE_CONVEX_URL=https://your-deployment.convex.cloud
CONVEX_URL=https://your-deployment.convex.cloud
VITE_WORKOS_CLIENT_ID=client_xxxxxxxxxxxxx
WORKOS_CLIENT_ID=client_xxxxxxxxxxxxx
VITE_WORKOS_REDIRECT_URI=http://localhost:5173/callback
OPENROUTER_API_KEY=your_openrouter_api_keyOptional:
VITE_WORKOS_API_HOSTNAME=https://api.workos.com
WORKOS_ISSUER=https://api.workos.com
OPENROUTER_MODEL=google/gemini-3.1-flash-lite-previewNotes:
VITE_CONVEX_URLis used by the browser.CONVEX_URLis used by the server-side workflow layer.WORKOS_CLIENT_IDis required byconvex/auth.config.ts.- The app is pinned to
http://localhost:5173in dev. If that port is busy,pnpm run devwill fail instead of silently switching ports.
Run Convex in a separate terminal:
pnpm run convex:devThe first run will link or create your Convex project and generate the local Convex metadata it needs.
Whenever you change:
convex/auth.config.tsconvex/schema.ts- Convex functions under
convex/
restart pnpm run convex:dev.
In WorkOS:
- Create an AuthKit application.
- Add
http://localhost:5173to allowed origins. - Add
http://localhost:5173/callbackas an allowed redirect URI. - Copy the client ID into
VITE_WORKOS_CLIENT_IDandWORKOS_CLIENT_ID. - Optionally set the App Homepage URL to
http://localhost:5173.
The app now passes an explicit returnTo on logout, so the homepage setting is optional for local development, but it is still a good default to configure in WorkOS.
References:
Start Convex:
pnpm run convex:devIn another terminal, start the app:
pnpm run devThen open:
http://localhost:5173If you use portless:
pnpm run dev:portlessIf you do that, update your WorkOS allowed origin and redirect URI to the actual portless URL. Do not keep localhost:5173/callback in WorkOS unless the app is really running there.
pnpm run dev
pnpm run dev:portless
pnpm run convex:dev
pnpm run lint
pnpm run lint:fix
pnpm run format
pnpm run format:check
pnpm run typecheck
pnpm run test
pnpm run build- Resume files are stored in Convex file storage.
- Resume metadata, parsed text, generated variants, and applications are stored in Convex documents.
- OCR/PDF parsing and OpenRouter generation still run in the app server layer.
- Auth is handled client-side with WorkOS AuthKit, while Convex validates the WorkOS JWTs in
convex/auth.config.ts. - The app syncs the signed-in WorkOS user into the Convex
userstable on login.
Usually means WorkOS login succeeded but Convex auth did not.
Check:
WORKOS_CLIENT_IDmatches the same WorkOS app asVITE_WORKOS_CLIENT_IDpnpm run convex:devwas restarted after changingconvex/auth.config.ts- the Convex deployment URL in
CONVEX_URL/VITE_CONVEX_URLis correct
Your WorkOS redirect URI and the actual dev server URL do not match.
For normal local dev, use:
http://localhost:5173/callbackIf you are using portless, use the real portless callback URL instead.
The app now falls back to the WorkOS client user profile when syncing the Convex user record. Sign out and sign back in after pulling the latest changes.
The app now passes an explicit logout returnTo, so local logout should return to the app root. If you still see the WorkOS homepage error, restart the dev server and verify you are running the latest code.
- If you change environment variables, restart both the Vite dev server and
convex dev. - Build output includes native dependencies like
sharp, so production runtime OS/architecture must match the build target or rebuild there.

