Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Initialize a new Convex project or add Convex to an existing React, Next.js, Vue, or Svelte app.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: convex-quickstart3description:4Creates or adds Convex to an app. Use for new Convex projects, npm create5convex@latest, frontend setup, env vars, or the first npx convex dev run.6---78# Convex Quickstart910Set up a working Convex project as fast as possible.1112## When to Use1314- Starting a brand new project with Convex15- Adding Convex to an existing React, Next.js, Vue, Svelte, or other app16- Scaffolding a Convex app for prototyping1718## When Not to Use1920- The project already has Convex installed and `convex/` exists - just start21building22- You only need to add auth to an existing Convex app - use the23`convex-setup-auth` skill2425## Workflow26271. Determine the starting point: new project or existing app282. If new project, pick a template and scaffold with `npm create convex@latest`293. If existing app, install `convex` and wire up the provider304. Run `npx convex dev` to connect a deployment and start the dev loop315. Verify the setup works3233## Path 1: New Project (Recommended)3435Use the official scaffolding tool. It creates a complete project with the36frontend framework, Convex backend, and all config wired together.3738### Pick a template3940| Template | Stack |41| -------------------------- | ----------------------------------------- |42| `react-vite-shadcn` | React + Vite + Tailwind + shadcn/ui |43| `nextjs-shadcn` | Next.js App Router + Tailwind + shadcn/ui |44| `react-vite-clerk-shadcn` | React + Vite + Clerk auth + shadcn/ui |45| `nextjs-clerk` | Next.js + Clerk auth |46| `nextjs-convexauth-shadcn` | Next.js + Convex Auth + shadcn/ui |47| `nextjs-lucia-shadcn` | Next.js + Lucia auth + shadcn/ui |48| `bare` | Convex backend only, no frontend |4950If the user has not specified a preference, default to `react-vite-shadcn` for51simple apps or `nextjs-shadcn` for apps that need SSR or API routes.5253You can also use any GitHub repo as a template:5455```bash56npm create convex@latest my-app -- -t owner/repo57npm create convex@latest my-app -- -t owner/repo#branch58```5960### Scaffold the project6162Always pass the project name and template flag to avoid interactive prompts:6364```bash65npm create convex@latest my-app -- -t react-vite-shadcn66cd my-app67npm install68```6970The scaffolding tool creates files but does not run `npm install`, so you must71run it yourself.7273To scaffold in the current directory (if it is empty):7475```bash76npm create convex@latest . -- -t react-vite-shadcn77npm install78```7980### Start the dev loop8182`npx convex dev` is a long-running watcher process that syncs backend code to a83Convex deployment on every save. It also requires authentication on first run84(browser-based OAuth). Both of these make it unsuitable for an agent to run85directly.8687**Ask the user to run this themselves:**8889Tell the user to run `npx convex dev` in their terminal. On first run it will90prompt them to log in or develop anonymously. Once running, it will:9192- Create a Convex project and dev deployment93- Write the deployment URL to `.env.local`94- Create the `convex/` directory with generated types95- Watch for changes and sync continuously9697The user should keep `npx convex dev` running in the background while you work98on code. The watcher will automatically pick up any files you create or edit in99`convex/`.100101**Exception - cloud or headless agents:** Environments that cannot open a102browser for interactive login should use Agent Mode (see below) to run103anonymously without user interaction.104105### Start the frontend106107The user should also run the frontend dev server in a separate terminal:108109```bash110npm run dev111```112113Vite apps serve on `http://localhost:5173`, Next.js on `http://localhost:3000`.114115### What you get116117After scaffolding, the project structure looks like:118119```120my-app/121convex/ # Backend functions and schema122_generated/ # Auto-generated types (check this into git)123schema.ts # Database schema (if template includes one)124src/ # Frontend code (or app/ for Next.js)125package.json126.env.local # CONVEX_URL / VITE_CONVEX_URL / NEXT_PUBLIC_CONVEX_URL127```128129The template already has:130131- `ConvexProvider` wired into the app root132- Correct env var names for the framework133- Tailwind and shadcn/ui ready (for shadcn templates)134- Auth provider configured (for auth templates)135136Proceed to adding schema, functions, and UI.137138## Path 2: Add Convex to an Existing App139140Use this when the user already has a frontend project and wants to add Convex as141the backend.142143### Install144145```bash146npm install convex147```148149### Initialize and start dev loop150151Ask the user to run `npx convex dev` in their terminal. This handles login,152creates the `convex/` directory, writes the deployment URL to `.env.local`, and153starts the file watcher. See the notes in Path 1 about why the agent should not154run this directly.155156### Wire up the provider157158The Convex client must wrap the app at the root. The setup varies by framework.159160Create the `ConvexReactClient` at module scope, not inside a component:161162```tsx163// Bad: re-creates the client on every render164function App() {165const convex = new ConvexReactClient(166import.meta.env.VITE_CONVEX_URL as string,167);168return <ConvexProvider client={convex}>...</ConvexProvider>;169}170171// Good: created once at module scope172const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string);173function App() {174return <ConvexProvider client={convex}>...</ConvexProvider>;175}176```177178#### React (Vite)179180```tsx181// src/main.tsx182import { StrictMode } from "react";183import { createRoot } from "react-dom/client";184import { ConvexProvider, ConvexReactClient } from "convex/react";185import App from "./App";186187const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string);188189createRoot(document.getElementById("root")!).render(190<StrictMode>191<ConvexProvider client={convex}>192<App />193</ConvexProvider>194</StrictMode>,195);196```197198#### Next.js (App Router)199200```tsx201// app/ConvexClientProvider.tsx202"use client";203204import { ConvexProvider, ConvexReactClient } from "convex/react";205import { ReactNode } from "react";206207const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);208209export function ConvexClientProvider({ children }: { children: ReactNode }) {210return <ConvexProvider client={convex}>{children}</ConvexProvider>;211}212```213214```tsx215// app/layout.tsx216import { ConvexClientProvider } from "./ConvexClientProvider";217218export default function RootLayout({219children,220}: {221children: React.ReactNode;222}) {223return (224<html lang="en">225<body>226<ConvexClientProvider>{children}</ConvexClientProvider>227</body>228</html>229);230}231```232233#### Other frameworks234235For Vue, Svelte, React Native, TanStack Start, Remix, and others, follow the236matching quickstart guide:237238- [Vue](https://docs.convex.dev/quickstart/vue)239- [Svelte](https://docs.convex.dev/quickstart/svelte)240- [React Native](https://docs.convex.dev/quickstart/react-native)241- [TanStack Start](https://docs.convex.dev/quickstart/tanstack-start)242- [Remix](https://docs.convex.dev/quickstart/remix)243- [Node.js (no frontend)](https://docs.convex.dev/quickstart/nodejs)244245### Environment variables246247The env var name depends on the framework:248249| Framework | Variable |250| ------------ | ------------------------ |251| Vite | `VITE_CONVEX_URL` |252| Next.js | `NEXT_PUBLIC_CONVEX_URL` |253| Remix | `CONVEX_URL` |254| React Native | `EXPO_PUBLIC_CONVEX_URL` |255256`npx convex dev` writes the correct variable to `.env.local` automatically.257258## Agent Mode (Cloud and Headless Agents)259260When running in a cloud or headless agent environment where interactive browser261login is not possible, set `CONVEX_AGENT_MODE=anonymous` to use a local262anonymous deployment.263264Add `CONVEX_AGENT_MODE=anonymous` to `.env.local`, or set it inline:265266```bash267CONVEX_AGENT_MODE=anonymous npx convex dev268```269270This runs a local Convex backend on the VM without requiring authentication, and271avoids conflicting with the user's personal dev deployment.272273## Verify the Setup274275After setup, confirm everything is working:2762771. The user confirms `npx convex dev` is running without errors2782. The `convex/_generated/` directory exists and has `api.ts` and `server.ts`2793. `.env.local` contains the deployment URL280281## Writing Your First Function282283Once the project is set up, create a schema and a query to verify the full loop284works.285286`convex/schema.ts`:287288```ts289import { defineSchema, defineTable } from "convex/server";290import { v } from "convex/values";291292export default defineSchema({293tasks: defineTable({294text: v.string(),295completed: v.boolean(),296}),297});298```299300`convex/tasks.ts`:301302```ts303import { query, mutation } from "./_generated/server";304import { v } from "convex/values";305306export const list = query({307args: {},308handler: async (ctx) => {309return await ctx.db.query("tasks").collect();310},311});312313export const create = mutation({314args: { text: v.string() },315handler: async (ctx, args) => {316await ctx.db.insert("tasks", { text: args.text, completed: false });317},318});319```320321Use in a React component (adjust the import path based on your file location322relative to `convex/`):323324```tsx325import { useQuery, useMutation } from "convex/react";326import { api } from "../convex/_generated/api";327328function Tasks() {329const tasks = useQuery(api.tasks.list);330const create = useMutation(api.tasks.create);331332return (333<div>334<button onClick={() => create({ text: "New task" })}>Add</button>335{tasks?.map((t) => (336<div key={t._id}>{t.text}</div>337))}338</div>339);340}341```342343## Development vs Production344345Always use `npx convex dev` during development. It runs against your personal346dev deployment and syncs code on save.347348When ready to ship, deploy to production:349350```bash351npx convex deploy352```353354This pushes to the production deployment, which is separate from dev. Do not use355`deploy` during development.356357## Next Steps358359- Add authentication: use the `convex-setup-auth` skill360- Design your schema: see361[Schema docs](https://docs.convex.dev/database/schemas)362- Build components: use the `convex-create-component` skill363- Plan a migration: use the `convex-migration-helper` skill364- Add file storage: see365[File Storage docs](https://docs.convex.dev/file-storage)366- Set up cron jobs: see [Scheduling docs](https://docs.convex.dev/scheduling)367368## Checklist369370- [ ] Determined starting point: new project or existing app371- [ ] If new project: scaffolded with `npm create convex@latest` using372appropriate template373- [ ] If existing app: installed `convex` and wired up the provider374- [ ] User has `npx convex dev` running and connected to a deployment375- [ ] `convex/_generated/` directory exists with types376- [ ] `.env.local` has the deployment URL377- [ ] Verified a basic query/mutation round-trip works378