Introduction to Convex
Our kanban board works, but it has one important limitation: the data lives in the browser’s localStorage. That means:
- No sharing: your tasks exist only in your browser. Another person (or another device) cannot see them.
- No collaboration: two people cannot work on the same board. There is no way for one user’s changes to appear on another user’s screen.
- Fragile storage: if the user clears their browser data, everything is gone.
localStorageis meant for preferences and caches, not application data.
For a personal to-do list, localStorage might be fine. But if you want the data to persist reliably, to be available on more than one device, or to be shared between users, you need a backend: a server that stores the data and makes it available to anyone who needs it.
The Traditional Approach
Traditionally, building a backend means:
- Setting up a server framework (like
Express.js) - Choosing and configuring a database (
PostgreSQL,MongoDB, etc.) - Writing API endpoints (
RESTorGraphQL) - Handling authentication, validation, error handling
- Deploying and maintaining the server
That is a lot of infrastructure before you can even store a task. Each layer has its own concepts, configuration files, and failure modes.
Convex
Convex is a Backend-as-a-Service (BaaS) platform. Instead of setting up servers and databases yourself, you write TypeScript functions in a convex/ directory, and Convex handles everything else: the database, the server, the API layer, and deployment.
Here is the mental model:
Traditional: Convex:
┌────────────┐ ┌────────────┐
│ React │ │ React │
│ App │ │ App │
└─────┬──────┘ └─────┬──────┘
│ HTTP requests │ WebSocket
▼ ▼
┌────────────┐ ┌────────────┐
│ Express │ │ convex │
│ Server │ │ server │
└─────┬──────┘ │ │
│ SQL queries └────────────┘
▼ (database, server,
┌────────────┐ file storage,
│ Database │ authentication,
└────────────┘ and more all built-in)
With Convex, you still have a server and a database, but you do not have to set them up, deploy them, or maintain them. Convex takes care of the infrastructure:
- Your backend is TypeScript functions: instead of configuring a server framework, you export functions from
.tsfiles. Convex runs them on its managed server. - The database is built in: Convex provides a document database with automatic schema validation. No installation, no connection strings.
- Real-time by default: when data changes on the server, every connected client updates automatically. No polling, no manual refetching.
- Deployment is automatic:
npx convex devsyncs your functions to the cloud as you save. No build pipelines to configure.
Three Types of Functions
Convex has three types of server functions:
- Queries: read data from the database. They are reactive: when the underlying data changes, Convex automatically re-runs the query and pushes the new results to all connected clients.
- Mutations: write data to the database. They are transactional: if something goes wrong, the entire operation rolls back.
- Actions: call external APIs or do other side effects. They do not have direct database access (they call queries and mutations instead).
For our kanban board, we will only need queries and mutations. That is enough to replace localStorage with a real database and get real-time sync without additional work.
What We will Do
Over the next several sections, we will:
- Set up Convex in our project
- Define a schema for the
taskstable - Write a query to read tasks and a set of mutations to create, update, and delete them
- Replace TanStack Store with Convex’s React hooks (
useQueryanduseMutation) - Remove
localStorageentirely
By the end, the app will look and behave the same as it does now. The difference is that the data will live on a real server, so it persists across devices and syncs in real time across browser tabs.