Convex Client and Backend SDK

1.36.0 · active · verified Wed Apr 22

Convex is a comprehensive backend application platform offering a real-time database, serverless functions (queries, mutations, actions), and client libraries for JavaScript/TypeScript, with strong support for React. The current stable version is 1.36.0, with frequent precompiled releases indicating rapid development and continuous improvements. A key differentiator is its real-time reactivity, where client-side `useQuery` hooks automatically update whenever the underlying database data changes, eliminating manual subscription management. It provides end-to-end type safety, optional schema definitions, and a TypeScript-first approach for both backend function definitions and client-side consumption. The platform includes SDKs for defining backend logic, integrating with React, and handling authentication with providers like Auth0 and Clerk. Convex aims to simplify full-stack development by unifying the database and backend logic within a single reactive environment.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up the Convex React client, connect to a Convex backend, and display real-time data fetched using the `useQuery` hook within a React component. It assumes a basic backend query `getTasks` is defined.

import React from 'react';
import { ConvexReactClient, ConvexProvider, useQuery } from 'convex/react';
import { api } from '../convex/_generated/api'; // Adjust path as needed

// Initialize the Convex client
const convexUrl = process.env.VITE_CONVEX_URL ?? 'https://your-convex-url.convex.cloud'; // Replace with your actual URL or env var
const convex = new ConvexReactClient(convexUrl);

// Backend function definition (e.g., in convex/tasks.ts)
/*
  import { query } from './_generated/server';
  import { v } from 'convex/values';

  export const getTasks = query({
    args: { status: v.optional(v.string()) },
    handler: async (ctx, args) => {
      return await ctx.db.query('tasks')
        .filter(q => args.status ? q.eq(q.field('status'), args.status) : true)
        .collect();
    },
  });
*/

interface Task {
  _id: string;
  text: string;
  status: 'todo' | 'done';
}

function TaskList() {
  // Fetch tasks in real-time. The component re-renders when data changes.
  const tasks = useQuery(api.tasks.getTasks, { status: 'todo' });

  if (tasks === undefined) {
    return <div>Loading tasks...</div>;
  }

  if (tasks.length === 0) {
    return <div>No tasks to display.</div>;
  }

  return (
    <div>
      <h1>Todo List</h1>
      <ul>
        {tasks.map((task: Task) => (
          <li key={task._id}>{task.text}</li>
        ))}
      </ul>
    </div>
  );
}

export default function App() {
  return (
    <ConvexProvider client={convex}>
      <TaskList />
    </ConvexProvider>
  );
}

view raw JSON →