DEV Community

Alex Spinov
Alex Spinov

Posted on

Convex Has a Free Backend Platform That Replaces Firebase With TypeScript

Firebase forces you into NoSQL, has terrible TypeScript support, and locks you into Google's ecosystem. Convex is a reactive backend platform with real-time queries, TypeScript-first design, and ACID transactions.

What Convex Gives You for Free

  • Real-time database — UI updates automatically when data changes
  • TypeScript end-to-end — server functions and client are fully typed
  • ACID transactions — no stale reads, no write conflicts
  • File storage — upload and serve files
  • Scheduled functions — cron jobs and delayed execution
  • Authentication — Clerk, Auth0, custom auth integration
  • Free tier — generous limits for side projects

Quick Start

npm create convex@latest
Enter fullscreen mode Exit fullscreen mode

Define Your Schema

// convex/schema.ts
import { defineSchema, defineTable } from 'convex/server';
import { v } from 'convex/values';

export default defineSchema({
  tasks: defineTable({
    text: v.string(),
    isCompleted: v.boolean(),
    userId: v.id('users'),
  }).index('by_user', ['userId']),

  users: defineTable({
    name: v.string(),
    email: v.string(),
  }),
});
Enter fullscreen mode Exit fullscreen mode

Server Functions (Queries & Mutations)

// convex/tasks.ts
import { query, mutation } from './_generated/server';
import { v } from 'convex/values';

// Real-time query — UI auto-updates when data changes
export const list = query({
  args: { userId: v.id('users') },
  handler: async (ctx, args) => {
    return await ctx.db
      .query('tasks')
      .withIndex('by_user', (q) => q.eq('userId', args.userId))
      .collect();
  },
});

// Mutation — ACID transaction guaranteed
export const create = mutation({
  args: { text: v.string(), userId: v.id('users') },
  handler: async (ctx, args) => {
    return await ctx.db.insert('tasks', {
      text: args.text,
      isCompleted: false,
      userId: args.userId,
    });
  },
});

export const toggle = mutation({
  args: { id: v.id('tasks') },
  handler: async (ctx, args) => {
    const task = await ctx.db.get(args.id);
    if (!task) throw new Error('Task not found');
    await ctx.db.patch(args.id, { isCompleted: !task.isCompleted });
  },
});
Enter fullscreen mode Exit fullscreen mode

React Client (Real-Time by Default)

import { useQuery, useMutation } from 'convex/react';
import { api } from '../convex/_generated/api';

export function TaskList({ userId }) {
  // This query is REAL-TIME — UI updates automatically!
  const tasks = useQuery(api.tasks.list, { userId });
  const createTask = useMutation(api.tasks.create);
  const toggleTask = useMutation(api.tasks.toggle);

  return (
    <div>
      <form onSubmit={(e) => {
        e.preventDefault();
        const text = new FormData(e.target).get('text');
        createTask({ text, userId });
      }}>
        <input name="text" placeholder="New task" />
        <button>Add</button>
      </form>

      {tasks?.map(task => (
        <div key={task._id} onClick={() => toggleTask({ id: task._id })}>
          {task.isCompleted ? '' : ''} {task.text}
        </div>
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

No refetch. No polling. No WebSocket setup. Data is just always current.

Convex vs Firebase vs Supabase

Feature Convex Firebase Supabase
Database Document + relational NoSQL only PostgreSQL
Type safety Full TypeScript Manual Manual
Real-time Built-in, automatic Built-in Add-on
Transactions ACID Limited Full
Server functions TypeScript JavaScript SQL/Edge
Auth Clerk/Auth0/custom Firebase Auth Built-in
File storage Built-in Built-in Built-in

The Verdict

Convex is what Firebase should have been: real-time, type-safe, transactional, and TypeScript-native. If you're building a real-time app and want the DX of Firebase without its limitations, Convex is the modern choice.


Need help building production web scrapers or data pipelines? I build custom solutions. Reach out: spinov001@gmail.com

Check out my awesome-web-scraping collection — 400+ tools for extracting web data.

Top comments (0)