A highly opinionated Next.js starter with better-auth, convex, shadcn/ui, react-email, and turborepo. Pre-configured for rapid, scalable development.
convex-starter/
├── apps/
│ └── web/ # Main Next.js application
├── packages/
│ ├── backend/ # Convex backend
│ ├── eslint-config/ # Shared ESLint configurations
│ ├── typescript-config/ # Shared TypeScript configurations
│ └── ui/ # Shared UI components (shadcn/ui)
└── turbo/ # Turborepo configuration
- Authentication with Better Auth
- Backend platform (db, functions, storage, jobs) using Convex
- UI components built with shadcn/ui and Tailwind CSS
- Email support with react-email and Resend
- Form handling via react-hook-form
- Monorepo setup using Turborepo
npx create-next-app@latest [project-name] --use-pnpm --example https://github.com/jordanliu/convex-startercd [project-name]
pnpm installCopy the example environment file into .env.local in apps/web, then update it with your real values.
cp apps/web/.env.example apps/web/.env.localpnpm --filter @repo/backend run setupThis initializes your Convex project. Next, ensure your backend environment variables are uploaded to the Convex dashboard. From root run:
cp packages/backend/.env.example packages/backend/.env.localYou will then need to upload the environment variables into your Convex dashboard manually or via convex env. You can find more details here.
The auth integration expects SITE_URL in the Convex deployment and the
following public variables in apps/web/.env.local:
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://your-deployment.convex.site
NEXT_PUBLIC_SITE_URL=http://localhost:3000Keep the existing BETTER_AUTH_SECRET unchanged when upgrading an existing
deployment so current sessions remain valid.
Skip this step for a new deployment with no users. For an existing deployment,
deploy the additive schema and auth changes first, then backfill the Better Auth
ID into the application users table:
pnpm --filter @repo/backend exec convex run migrations:runBackfillAuthId
pnpm --filter @repo/backend exec convex run migrations:runBackfillAuthId --prodVerify that every application user has an authId. Only then clear the legacy
application user ID stored on the Better Auth user:
pnpm --filter @repo/backend exec convex run migrations:runClearLegacyUserId
pnpm --filter @repo/backend exec convex run migrations:runClearLegacyUserId --prodThe application supports both relationships during the migration. After both
production migrations succeed and existing sessions have aged out, remove
jwksRotateOnTokenGenerationError, make users.authId required, and remove the
temporary migrations component.
pnpm devThis will start both the Next.js application at http://localhost:3000 and the Convex development server at http://127.0.0.1:6790.
pnpm dev # Start development servers for all packages
pnpm build # Build all packages for production
pnpm start # Start production server (requires build)pnpm lint # Run ESLint across all packages
pnpm format # Format code with Prettier
pnpm check-types # Run TypeScript type checkingpnpm --filter @repo/backend setup # Initialize Convex project (run once)
pnpm --filter @repo/backend dev # Start Convex development server only
pnpm --filter @repo/backend deploy # Deploy Convex backend to productionpnpm --filter web dev # Run only the Next.js applicationturbo genFollow the prompts to scaffold a new package with proper TypeScript and build configurations.
cd apps/web
pnpm dlx shadcn@canary add [component-name]Components are automatically added to the UI package and can be imported across the monorepo.
# Add to specific package
pnpm --filter web add [package-name]
pnpm --filter @repo/ui add [package-name]
pnpm --filter @repo/backend add [package-name]
# Add to workspace root (affects all packages)
pnpm add -w [package-name]
# Add dev dependencies
pnpm --filter web add -D [package-name]pnpm --filter @repo/backend run deployThis creates your production Convex deployment and provides you with production cloud and site URLs.
Update your hosting platform (Vercel, Netlify, etc.) with the production Convex URL:
NEXT_PUBLIC_CONVEX_URL=https://your-production-deployment.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://your-production-deployment.convex.site
NEXT_PUBLIC_SITE_URL=https://your-app.example.compnpm buildThen deploy the built application using your preferred hosting platform's deployment method.