Better Auth Waitlist Plugin
The `better-auth-waitlist` package, currently at version 3.0.1, is a lightweight and production-ready plugin designed to integrate comprehensive waitlist management into the Better Auth authentication system. It offers features such as administrative approval workflows, restrictions based on email domains, and highly customizable validation for waitlist entries. The package is optimized for minimal bundle size, weighing approximately ~22 kB minified and ~3.5 kB gzipped, and lists `zod` as its only direct runtime dependency. Shipping exclusively as an ES module (ESM), it mandates a Node.js environment of version 18 or higher. Its primary differentiators include deep integration with Better Auth, flexible configuration options for various waitlist use cases (e.g., capacity limits, auto-approval, custom data fields), and client-side utilities for seamless application integration, supporting operations like joining, status checks, and admin-only actions such as listing, finding, approving, and rejecting entries.
Common errors
-
ERR_REQUIRE_ESM
cause Attempting to use `require()` to import `better-auth-waitlist` or its subpaths in an environment configured for ES Modules, or when the package itself is ESM-only.fixRefactor your imports to use ES module syntax: `import { waitlist } from 'better-auth-waitlist';`. -
TypeError: Cannot read properties of undefined (reading 'waitlist')
cause The `waitlistClient()` plugin was not correctly added to `createAuthClient`'s `plugins` array, or the `authClient` instance was not properly initialized.fixEnsure `waitlistClient()` is included in the `plugins` array when calling `createAuthClient`: `plugins: [waitlistClient()]`. -
SQLITE_ERROR: no such table: waitlist_entries
cause The required database table for waitlist entries has not been created by the Better Auth migration tool.fixRun the database migration command from your project root: `npx @better-auth/cli migrate`. -
ReferenceError: process is not defined
cause Accessing `process.env` directly in a client-side environment without proper polyfilling or environment variable injection by a build tool (e.g., in a vanilla browser environment).fixEnsure that environment variables like `NEXT_PUBLIC_AUTH_URL` are correctly accessed and bundled for client-side code by your framework's build process, often requiring specific syntax like `import.meta.env` or framework-specific conventions.
Warnings
- breaking `better-auth-waitlist` v3 and newer are pure ES Modules (ESM) and no longer support CommonJS `require()` syntax. This change affects how the package is imported and used in Node.js environments.
- breaking The `better-auth-waitlist` package now requires Node.js version 18 or higher. This update aligns with modern JavaScript features and dependency requirements, and older Node.js versions are no longer supported.
- gotcha Installing and configuring the waitlist plugin requires a database migration to create the necessary waitlist_entries table and any related schemas. Without this migration, the plugin will not function correctly and will likely throw database errors.
- gotcha Accessing administrative waitlist operations (e.g., `list`, `findOne`, `approve`, `reject`) through the `authClient` requires the authenticated user to possess appropriate admin roles within your Better Auth setup. Without these roles, access will be denied.
- gotcha The `createAuthClient` function on the client-side requires a `baseURL` to specify the endpoint of your Better Auth backend API. In typical web frameworks, this is often provided via environment variables.
Install
-
npm install better-auth-waitlist -
yarn add better-auth-waitlist -
pnpm add better-auth-waitlist
Imports
- waitlist
const { waitlist } = require('better-auth-waitlist');import { waitlist } from 'better-auth-waitlist'; - waitlistClient
const { waitlistClient } = require('better-auth-waitlist/client');import { waitlistClient } from 'better-auth-waitlist/client'; - WaitlistPluginOptions
import { WaitlistPluginOptions } from 'better-auth-waitlist';import type { WaitlistPluginOptions } from 'better-auth-waitlist';
Quickstart
import { betterAuth } from "better-auth";
import { waitlist } from "better-auth-waitlist";
import { createAuthClient } from "better-auth/react";
import { waitlistClient } from "better-auth-waitlist/client";
// Server-side: Initialize Better Auth with the waitlist plugin
export const auth = betterAuth({
plugins: [
waitlist({
enabled: true,
allowedDomains: ["@example.com", "@company.org"],
maximumWaitlistParticipants: 1000,
// Example of adding custom fields and auto-approval logic
additionalFields: {
department: { type: "string", required: true },
additionalInfo: { type: "string", required: false }
},
autoApprove: (entry) => entry.email.endsWith('@company.org')
})
]
});
// Client-side: Initialize the Better Auth client with the waitlist client plugin
export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_AUTH_URL ?? '', // Ensure this environment variable is set
plugins: [waitlistClient()]
});
async function demonstrateWaitlist() {
// Important: Run `npx @better-auth/cli migrate` once to create the necessary database tables.
// Join the waitlist
try {
const joinResult = await authClient.waitlist.join({
email: "user@example.com",
department: "Engineering",
name: "Jane Smith",
additionalInfo: "Need access to internal tools"
});
console.log("Joined waitlist:", joinResult);
// Check waitlist status
const status = await authClient.waitlist.checkStatus({
email: "user@example.com"
});
console.log("Waitlist status:", status);
// Example of admin operations (requires admin role and authenticated client)
// const allEntries = await authClient.waitlist.list();
// console.log('All waitlist entries (admin-only):', allEntries);
// await authClient.waitlist.approve({ id: joinResult.id }); // Assuming joinResult contains an ID
// console.log('Entry approved by admin.');
} catch (error) {
console.error("Waitlist operation failed:", error);
}
}
demonstrateWaitlist();