Skip to main content الرئيسية المنشئون kunanonj ai-skills-hub cursor-plugin-convex-convex-quickstart
cursor-plugin-convex-convex-quickstart Initialize a new Convex backend from scratch with schema, auth, and basic CRUD operations. Use when starting a new project or adding Convex to an existing app.
الانتقال إلى التثبيت سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/KunanonJ/ai-skills-hub --skill cursor-plugin-convex-convex-quickstartيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... cursor-plugin-cf-agents-sdk Build AI agents on Cloudflare Workers using the Agents SDK. Load when creating stateful agents, durable workflows, real-time WebSocket apps, scheduled tasks, MCP servers, chat applications, voice agents, or browser automation. Covers Agent class, state management, callable RPC, Workflows, durable execution, queues, retries, observability, and React hooks. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
cursor-plugin-cf-cloudflare Comprehensive Cloudflare platform skill covering Workers, Pages, storage (KV, D1, R2), AI (Workers AI, Vectorize, Agents SDK), feature flags (Flagship), networking (Tunnel, Spectrum), security (WAF, DDoS), and infrastructure-as-code (Terraform, Pulumi). Use for any Cloudflare development task. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
المهن ذات الصلة SOC
استنادا إلى تصنيف SOC المهني
name cursor-plugin-convex-convex-quickstart description Initialize a new Convex backend from scratch with schema, auth, and basic CRUD operations. Use when starting a new project or adding Convex to an existing app. metadata {"version":"0.1.0"}
Convex Quickstart
Get a production-ready Convex backend set up in minutes. This skill guides you through initializing Convex, creating your schema, setting up auth, and building your first CRUD operations.
When to Use
Starting a brand new project with Convex
Adding Convex to an existing React/Next.js app
Prototyping a new feature with real-time data
Converting from another backend to Convex
Teaching someone Convex for the first time
Prerequisites Check
Before starting, verify:
node --version
npm --version
Quick Start Flow
Step 1: Install and Initialize
npm install convex
npx convex dev
This command:
Creates convex/ directory
Sets up authentication
Starts development server
Generates TypeScript types
Step 2: Create Schema
Create convex/schema.ts:
import { defineSchema, defineTable } ;
{ v } ;
({
: ({
: v. (),
: v. (),
: v. (),
}). ( , [ ]),
: ({
: v. ( ),
: v. (),
: v. (),
: v. (),
})
. ( , [ ])
. ( , [ , ]),
});
from
"convex/server"
import
from
"convex/values"
export
default
defineSchema
users
defineTable
tokenIdentifier
string
name
string
email
string
index
"by_token"
"tokenIdentifier"
tasks
defineTable
userId
id
"users"
title
string
completed
boolean
createdAt
number
index
"by_user"
"userId"
index
"by_user_and_completed"
"userId"
"completed"
Step 3: Set Up Authentication We'll use WorkOS AuthKit, which provides a complete auth solution with minimal setup.
npm install @workos-inc/authkit-react
For React/Vite Apps:
import { AuthKitProvider , useAuth } from "@workos-inc/authkit-react" ;
import { ConvexReactClient } from "convex/react" ;
import { ConvexProvider } from "convex/react" ;
const convex = new ConvexReactClient (import .meta .env .VITE_CONVEX_URL );
convex.setAuth (useAuth);
function App ( ) {
return (
<AuthKitProvider clientId ={import.meta.env.VITE_WORKOS_CLIENT_ID} >
<ConvexProvider client ={convex} >
<YourApp />
</ConvexProvider >
</AuthKitProvider >
);
}
For Next.js Apps: npm install @workos-inc/authkit-nextjs
import { AuthKitProvider } from "@workos-inc/authkit-nextjs" ;
import { ConvexClientProvider } from "./ConvexClientProvider" ;
export default function RootLayout ({ children }: { children: React.ReactNode } ) {
return (
<html >
<body >
<AuthKitProvider >
<ConvexClientProvider >
{children}
</ConvexClientProvider >
</AuthKitProvider >
</body >
</html >
);
}
"use client" ;
import { ConvexReactClient } from "convex/react" ;
import { ConvexProvider } from "convex/react" ;
import { useAuth } from "@workos-inc/authkit-nextjs" ;
const convex = new ConvexReactClient (process.env .NEXT_PUBLIC_CONVEX_URL !);
export function ConvexClientProvider ({ children }: { children: React.ReactNode } ) {
const { getToken } = useAuth ();
convex.setAuth (async () => {
return await getToken ();
});
return <ConvexProvider client ={convex} > {children}</ConvexProvider > ;
}
Environment Variables:
VITE_CONVEX_URL=https://your-deployment.convex.cloud
VITE_WORKOS_CLIENT_ID=your_workos_client_id
NEXT_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
NEXT_PUBLIC_WORKOS_CLIENT_ID=your_workos_client_id
WORKOS_API_KEY=your_workos_api_key
WORKOS_COOKIE_PASSWORD=generate_a_random_32_character_string
Alternative auth providers: If you need to use a different provider (Clerk, Auth0, custom JWT), see the Convex auth documentation .
Step 4: Create Auth Helpers Create convex/lib/auth.ts:
import { QueryCtx , MutationCtx } from "../_generated/server" ;
import { Doc } from "../_generated/dataModel" ;
export async function getCurrentUser (
ctx : QueryCtx | MutationCtx
): Promise <Doc <"users" >> {
const identity = await ctx.auth .getUserIdentity ();
if (!identity) {
throw new Error ("Not authenticated" );
}
const user = await ctx.db
.query ("users" )
.withIndex ("by_token" , q =>
q.eq ("tokenIdentifier" , identity.tokenIdentifier )
)
.unique ();
if (!user) {
throw new Error ("User not found" );
}
return user;
}
import { mutation } from "./_generated/server" ;
export const store = mutation ({
args : {},
handler : async (ctx) => {
const identity = await ctx.auth .getUserIdentity ();
if (!identity) throw new Error ("Not authenticated" );
const existing = await ctx.db
.query ("users" )
.withIndex ("by_token" , q =>
q.eq ("tokenIdentifier" , identity.tokenIdentifier )
)
.unique ();
if (existing) return existing._id ;
return await ctx.db .insert ("users" , {
tokenIdentifier : identity.tokenIdentifier ,
name : identity.name ?? "Anonymous" ,
email : identity.email ?? "" ,
});
},
});
Step 5: Create Your First CRUD Operations import { query, mutation } from "./_generated/server" ;
import { v } from "convex/values" ;
import { getCurrentUser } from "./lib/auth" ;
export const list = query ({
args : {},
handler : async (ctx) => {
const user = await getCurrentUser (ctx);
return await ctx.db
.query ("tasks" )
.withIndex ("by_user" , q => q.eq ("userId" , user._id ))
.order ("desc" )
.collect ();
},
});
export const get = query ({
args : { taskId : v.id ("tasks" ) },
handler : async (ctx, args) => {
const user = await getCurrentUser (ctx);
const task = await ctx.db .get (args.taskId );
if (!task) throw new Error ("Task not found" );
if (task.userId !== user._id ) throw new Error ("Unauthorized" );
return task;
},
});
export const create = mutation ({
args : { title : v.string () },
handler : async (ctx, args) => {
const user = await getCurrentUser (ctx);
return await ctx.db .insert ("tasks" , {
userId : user._id ,
title : args.title ,
completed : false ,
createdAt : Date .now (),
});
},
});
export const update = mutation ({
args : {
taskId : v.id ("tasks" ),
title : v.optional (v.string ()),
completed : v.optional (v.boolean ()),
},
handler : async (ctx, args) => {
const user = await getCurrentUser (ctx);
const task = await ctx.db .get (args.taskId );
if (!task) throw new Error ("Task not found" );
if (task.userId !== user._id ) throw new Error ("Unauthorized" );
const updates : any = {};
if (args.title !== undefined ) updates.title = args.title ;
if (args.completed !== undefined ) updates.completed = args.completed ;
await ctx.db .patch (args.taskId , updates);
},
});
export const remove = mutation ({
args : { taskId : v.id ("tasks" ) },
handler : async (ctx, args) => {
const user = await getCurrentUser (ctx);
const task = await ctx.db .get (args.taskId );
if (!task) throw new Error ("Task not found" );
if (task.userId !== user._id ) throw new Error ("Unauthorized" );
await ctx.db .delete (args.taskId );
},
});
Step 6: Use in Your React App
"use client" ;
import { useQuery, useMutation } from "convex/react" ;
import { api } from "../../convex/_generated/api" ;
export default function TasksPage ( ) {
const tasks = useQuery (api.tasks .list );
const create = useMutation (api.tasks .create );
const update = useMutation (api.tasks .update );
const remove = useMutation (api.tasks .remove );
if (!tasks) return <div > Loading...</div > ;
return (
<div >
<h1 > Tasks</h1 >
{/* Create task */}
<form onSubmit ={(e) => {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
create({ title: formData.get("title") as string });
(e.target as HTMLFormElement).reset();
}}>
<input name ="title" placeholder ="New task" required />
<button type ="submit" > Add</button >
</form >
{/* Task list */}
{tasks.map(task => (
<div key ={task._id} >
<input
type ="checkbox"
checked ={task.completed}
onChange ={(e) => update({
taskId: task._id,
completed: e.target.checked
})}
/>
<span > {task.title}</span >
<button onClick ={() => remove({ taskId: task._id })}>
Delete
</button >
</div >
))}
</div >
);
}
Step 7: Development vs Production For Development (use this!):
For Production Deployment:
Important: Always use npx convex dev during development. Only use npx convex deploy when you're ready to ship to production.
Common Patterns
Paginated Queries export const listPaginated = query ({
args : {
cursor : v.optional (v.string ()),
limit : v.number (),
},
handler : async (ctx, args) => {
const user = await getCurrentUser (ctx);
const results = await ctx.db
.query ("tasks" )
.withIndex ("by_user" , q => q.eq ("userId" , user._id ))
.order ("desc" )
.paginate ({ cursor : args.cursor , limit : args.limit });
return results;
},
});
Filtering by Status export const listByStatus = query ({
args : {
completed : v.boolean (),
},
handler : async (ctx, args) => {
const user = await getCurrentUser (ctx);
return await ctx.db
.query ("tasks" )
.withIndex ("by_user_and_completed" , q =>
q.eq ("userId" , user._id ).eq ("completed" , args.completed )
)
.collect ();
},
});
Scheduled Jobs
import { cronJobs } from "convex/server" ;
import { internal } from "./_generated/api" ;
const crons = cronJobs ();
crons.daily (
"cleanup-old-tasks" ,
{ hourUTC : 0 , minuteUTC : 0 },
internal.tasks .cleanupOld
);
export default crons;
export const cleanupOld = internalMutation ({
handler : async (ctx) => {
const thirtyDaysAgo = Date .now () - 30 * 24 * 60 * 60 * 1000 ;
const oldTasks = await ctx.db
.query ("tasks" )
.filter (q =>
q.and (
q.eq (q.field ("completed" ), true ),
q.lt (q.field ("createdAt" ), thirtyDaysAgo)
)
)
.collect ();
for (const task of oldTasks) {
await ctx.db .delete (task._id );
}
},
});
Project Templates
React + Vite + Convex npm create vite@latest my-app -- --template react-ts
cd my-app
npm install convex @workos-inc/authkit-react
npx convex dev
Next.js + Convex npx create-next-app@latest my-app
cd my-app
npm install convex @workos-inc/authkit-nextjs
npx convex dev
Expo (React Native) + Convex npx create-expo-app my-app
cd my-app
npm install convex
npx convex dev
Checklist Remember: Use npx convex dev for all development work. Only use npx convex deploy when deploying to production!
Next Steps
Add more tables to schema
Implement relationships between tables
Add file storage (Convex supports file uploads)
Set up vector search for AI features
Add cron jobs for scheduled tasks
Configure production environment variables
Troubleshooting
"Not authenticated" errors
Ensure auth provider is configured
Call storeUser mutation on first sign-in
Check getCurrentUser is imported correctly
Types not updating
Run npx convex dev (regenerates types)
Restart TypeScript server in editor
Slow queries
Add indexes to schema
Use .withIndex() instead of .filter()
Check query patterns in dashboard
Learn More