Skip to main content


Creating a new Next.js project

To create a new Next.js project with TypeScript in the directory my-convex-app/, run

npx create-next-app@latest -e convex my-convex-app
cd my-convex-app
npm run dev

npm dev both runs a frontend dev server and pushes your Convex functions to your dev deployment each time you modify files in my-convex-app/convex/. The first time you run the command you'll create a new Convex project that you'll be able to see on your dashboard.

That's it! Once your app is running, visit localhost:3000 in a browser to see it.

Adding Convex to an existing React app

Install Convex and run the development servers

From your project root, install Convex.

npm install convex

The Convex dev server watches the local filesystem, pushing your Convex functions to your deployment and updating generated code each time you modify the code for your backend.

You'll probably want to set up a custom package.json dev command to run your frontend dev server and the Convex dev server at the same time, but in a pinch you can open two terminals and in one terminal run

npx convex dev

and in the other terminal run

npm run dev

Configure the client and wire up the provider

Create a new Convex project with npx convex init. Creating a new project will run you through creating a Convex account if you don't already have one.

npx convex init

Your new project's production deployment is located at a URL displayed during the init process and potentially also saved to a .env file. You can find the URLs of all deployments in a project by visiting the settings section of each deployment in the Convex dashboard.

Construct a Convex React client by passing in the URL of the Convex deployment.

import { ConvexProvider, ConvexReactClient } from "convex/react";

const address = import.meta.env.VITE_CONVEX_URL;

const convex = new ConvexReactClient(address);

Use an environment variable name accessible from your client code according to the frontend framework or bundler you're using. For example, Next.js requires these start with NEXT_PUBLIC_ and Vite requires these start with VITE_.

Finally, wrap your application component in a ConvexProvider that uses the Convex client you created.

<ConvexProvider client={convex}>
<App />

Place this provider high enough in the React component tree to available everywhere you want communicate with your Convex backend. In Next.js for example, the _app.jsx component is a good spot.

Writing backend code

Now when you write query, mutation, and action functions in the newly created convex/ folder to access your data...

import { mutation } from "./_generated/server";

export default mutation(({ db }, body, author) => {
const message = { body, author };
db.insert("messages", message);
import { query } from "./_generated/server";

export default query(async ({ db }) => {
return await db.query("messages").collect();

Writing frontend code can use these queries and mutations in React components.

import { useQuery } from "../convex/_generated/react";
import { useMutation } from "../convex/_generated/react";

function MyApp() {
// data will be `undefined` while the query is first loading
const data = useQuery("listMessages");
const sendMessage = useMutation("sendMessage");
const sendHello = () => sendMessage("Hello!", "me");
return (
<MyListView data={data} />
<button onClick={sendHello}>click me!</button>