Introduction
⚠️

Ents is in maintenance mode. We're open to taking PRs, and will make sure it doesn't break. There will not be active feature development from the Convex team.

Convex Ents

Convex Ents are an ergonomic layer on top of the Convex (opens in a new tab) built-in ctx.db (opens in a new tab) API for reading from and writing to the database.

Convex Ents:

  1. Build upon the relational capabilities of the database to provide an easier way to query related documents.
  2. Allow defining default values for easier document shape evolution.
  3. Simplify backend code by collocating common authorization rules in a single place.
  4. And more!

Convex Ents are loosely inspired by the powerful Ent framework developed at Facebook. You can learn more about it in this YouTube video (opens in a new tab), and see its open-source JS implementation at ent.dev (opens in a new tab).

Convex Ents provide similar capabilities to Prisma ORM (opens in a new tab), but target only Convex, and use neither proprietary schema language nor SQL concepts nor code generation. Convex Ents are a pure TypeScript/JavaScript library.

Examples

Check out these code snippets (opens in a new tab) for comparison of Prisma, Convex and Convex Ents.

SaaS Starter (opens in a new tab) is a full project template built out using Convex Ents.

convex/teams.ts
export const listTeamInvites = query({
  args: { teamId: v.id("teams") },
  async handler(ctx, { teamId }) {
    return await ctx
      .table("teams")
      .getX(teamId)
      .edge("invites")
      .map(async (invite) => ({
        _id: invite._id,
        email: invite.email,
        role: (await invite.edge("role")).name,
      })); // `{ _id: Id<"invites">, email: string, role: string }[]`
  },
});

I'm intrigued, what now?

Read the Ent Schema page to understand the improved data modeling that Convex Ents enable, and the Reading Ents and Writing Ents to see the more powerful interface to the database.

If you're sold, head over to Setup to get started.