Plugin
defaultA better-auth plugin. Tables come from the plugin schema, endpoints from createAuthEndpoint.
betterAuth({ plugins: [inbox()] })The rules that let BYO packages work as one system instead of a pile of plugins.
One identity, one permission model, one way to run background work, one UI style. Part 1 is required today. Its rules need plain better-auth primitives plus two shared packages, @byo-oss/core and @byo-oss/mailer. Part 2 holds proposals that aren't rules yet.
A package is an app only when it needs something a plugin can't give it: its own route tree or a separate database. Inbound webhooks stay plugins.
A better-auth plugin. Tables come from the plugin schema, endpoints from createAuthEndpoint.
betterAuth({ plugins: [inbox()] })A larger product with its own migrations and request handler, mapped to better-auth through an identify(request) adapter.
identify(request) // → user, orgs, permissionsA package exports its permission statements. Your app spreads them into its catalog and decides which roles get which actions.
import { createAccessControl } from "better-auth/plugins/access";
import { defaultStatements } from "better-auth/plugins/organization/access";
export const statements = {
...defaultStatements,
...feedbackStatements, // exported by the package
project: ["create", "update"],
} as const;
export const ac = createAccessControl(statements);Proposals, not rules. Each one stays here until it's promoted, and nothing in Part 1 depends on them.
MUST, SHOULD andMAY mean what RFC 2119 says. A rule marked (plugin) applies to plugins only; everything else applies to both tiers.