What is Convex?
Convex is a full cloud backend designed to replace your database, server functions, backend functionality, and the interface all the way out to your application - Convex
I first heard about convex while watching a video of one of my favorite Youtube channels Web Dev Cody. In the video, he explains how he's switching from Postgres to a real-time database (watch the video here)
In the past, I tried coding a realtime messenger app using mongoDB. However, I remember the experience I had to go through to implement the realtime functionality. I had to use third-party APIs like Pusher which just added more burden to the developer experience and cost.
After watching Cody's video on Convex, I decided to try it out because it seemed to be packed with a lot of useful features like:
- Functions that run on the backend
- Database
- File Storage
- Authentication
- Realtime updates
So, I tried setting up convex with NextJS.
Setting Up Convex
I installed Convex.
npm install convex && npm convex dev
You will receive a message containing instructions and information about your convex workspace. It also creates a .env.local
file with the needed configurations.
CONVEX_DEPLOYMENT=*******
NEXT_PUBLIC_CONVEX_URL=*******
Then, I will wrap my entire project with a <ConvexProvider />
. (Since I'm not using Clerk for user management, I'm not using the <ConvexProviderWithClerk />
). Read more in the docs
"use client";
import {ConvexProvider, ConvexReactClient} from "convex/react";
const convex = new ConvexReactClient(process.env.NEXT_PUBLICH_CONVEX_URL!)
export const ConvexClientProvider = ({children}: {children: React.ReactNode}) => {
return (
<ConvexProvider
client={convex}
>
{children}
</ConvexProvider>
)
}
export default function RootLayout({children}: {children: React.ReactNode}) => {
return (
<html lang="en">
<ConvexClientProvider>
{children}
</ConvexClientProvider>
</html>
)
}
We can now test convex. Let's quickly try it out. First, I will make a simple user schema.
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values"
export default defineSchema({
user: defineTable({
name: v.string(),
email: v.string(),
password: v.string(),
})
})
And code a simple Convex function to mutate our data.
import { v } from "convex/values"
import { mutation } from "./_generated/server"
export const testing = mutation({
args: {
name: v.string(),
email: v.string(),
password: v.string(),
},
handler: async (ctx, args) => {
await ctx.db.insert("user", {
name: args.name,
email: args.email,
password: args.password,
})
}
})
Add some code in our frontend...
const onSubmit = (values: z.infer<typeof LoginSchema>) => {
const promise = createUser({
name: values.name,
email: values.email,
password: values.password
})
}
And it works! 😄

It was extremely fascinating to see the database update in realtime (rather than having to refresh every time I make a change).
Wrapping up: Convex is definitely a tool I will study more and use for my personal projects.
Maybe I should try building the same app with different services... 🤔