About convex-tenants
A Convex package for managing organizations, teams, memberships, and authorization in multi-tenant applications. It provides a configurable API and optional React components, with permissions handled through the sibling `@djpanda/convex-authz` component.
Key features
- 01Organization and team management
- 02Membership and invitation APIs
- 03Flexible roles and permission mapping
- 04Prebuilt React components and hooks
Use cases
- 01Adding organizations to a Convex application
- 02Managing team membership and invitations
- 03Building organization-switching interfaces
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ dbjpanda/ convex-tenants --skill convex-tenantsAfter installing, type/convex-tenantsin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
api-reference.mderror-handling.mdflexible-roles.mdhooks-guide.mdinvitation-system.mdknown-limitations.mdorganization-store.mdpermission-map.mdquick-start.mdreact-components.mdREADME.mdtesting-guide.mdDetails
From the project READMEConvex Tenants
Multi-tenant organization and team management for Convex with flexible authorization via @djpanda/convex-authz.
Quick Start
- Register components in
convex/convex.config.ts:
import { defineApp } from "convex/server";
import tenants from "@djpanda/convex-tenants/convex.config";
import authz from "@djpanda/convex-authz/convex.config";
const app = defineApp();
app.use(tenants);
app.use(authz);
export default app;
-
Define authz in
convex/authz.ts— useTENANTS_PERMISSIONSandTENANTS_ROLESfrom the package. Seenode_modules/@djpanda/convex-tenants/docs/quick-start.md. -
Create tenants API in
convex/tenants.ts:
import { makeTenantsAPI } from "@djpanda/convex-tenants";
import { components } from "./_generated/api";
import { authz } from "./authz";
export const { listOrganizations, createOrganization, inviteMember, ... } =
makeTenantsAPI(components.tenants, {
authz,
creatorRole: "owner",
auth: async (ctx) => (await getAuthUserId(ctx)) ?? null,
getUser: async (ctx, userId) => {
const user = await ctx.db.get(userId);
return user ? { name: user.name, email: user.email } : null;
},
});
- Use in React —
useQuery(api.tenants.listOrganizations), or use pre-built components withTenantsProvider. Seenode_modules/@djpanda/convex-tenants/docs/react-components.md.
Key Concepts
- authz is a sibling component — Register
authzalongsidetenants, not as a child. Other parts of your app can use authz outside tenants. - Roles are plain strings — Define them in authz.ts. Default roles:
owner,admin,member. Seenode_modules/@djpanda/convex-tenants/docs/flexible-roles.md. - Structural owner — Each org has an
ownerId. UsetransferOwnershipbefore owner leaves. All permission checks go through authz. - Organization status —
suspendedorarchivedblocks mutations; onlyupdateOrganizationwithstatus: "active"can reactivate.
Exports
| Export | Description |
|---|---|
TENANTS_PERMISSIONS | Default permissions for definePermissions() |
TENANTS_ROLES | Default roles (owner, admin, member) for defineRoles() |
DEFAULT_TENANTS_PERMISSION_MAP | Operation → permission mapping |
TENANTS_REQUIRED_PERMISSIONS | Flat list of permission strings |
Documentation (read from package)
Base path: node_modules/@djpanda/convex-tenants/docs/. Select the doc that matches the user's keywords or task — load only what's needed:
| Doc | Path | Load when user asks about… |
|---|---|---|
| quick-start | docs/quick-start.md | Setup, install, first-time integration, convex.config, authz.ts, tenants.ts, getting started, initial setup |
| api-reference | docs/api-reference.md | Function names (listOrganizations, createOrganization, addMember, inviteMember, etc.), makeTenantsAPI options, event hooks, mutation/query args, pagination (listMembers/listTeams/listTeamMembers/listInvitations with optional paginationOpts), API signatures |
| permission-map | docs/permission-map.md | Permissions, permissionMap, who can do what, operation permissions, overriding permissions, guards, access control per operation |
| flexible-roles | docs/flexible-roles.md | Roles, custom roles, owner/admin/member, creatorRole, defineRoles, structural owner, transferOwnership, add/remove roles |
| invitation-system | docs/invitation-system.md | Invitations, inviteMember, acceptInvitation, validateInvitationCreate, validateInvitationAccept, identifier type, email/phone/username, domain whitelist, rate limiting invitations |
| react-components | docs/react-components.md | TenantsProvider, OrganizationSwitcher, MembersSection, TeamsSection, InviteMemberDialog, useOrganization, useMembers, useTeams, useOrganizationInvitations, MembersTable, TeamsGrid, AcceptInvitation, JoinByDomainSection, paginated hooks |
| organization-store | docs/organization-store.md | Active organization, switching orgs, useOrganizationStore, setActiveOrganizationId, localStorage, storageKey, configureOrganizationStore |
Installation
npm install @djpanda/convex-tenants @djpanda/convex-authz
For React UI: npm install clsx tailwind-merge (optional peer deps).