better-auth plugins
better-auth ships its feature set as plugins — organizations,
two-factor, API keys, bearer and JWT tokens, magic links, passkeys, and more. NetScript's
better-auth backend mounts them through a single typed passthrough on createNetscriptBetterAuth,
so you enable a plugin the same way you would in a standalone better-auth app while NetScript keeps
ownership of the Prisma-backed database adapter.
This page covers how to enable plugins, which ones run as-is, and the two prerequisites — database tables and interactive sign-in — that decide whether a given plugin is turnkey today.
Enabling a plugin
createNetscriptBetterAuth accepts a plugins array typed as better-auth's own
BetterAuthOptions["plugins"]. Pass plugin instances exactly as better-auth documents them;
NetScript forwards them into the underlying better-auth server while supplying the Prisma adapter
itself.
import { organization } from "better-auth/plugins";
import {
createBetterAuthBackend,
createNetscriptBetterAuth,
} from "@netscript/auth-better-auth";
const auth = createNetscriptBetterAuth({
prisma,
provider: "postgresql",
secret: Deno.env.get("BETTER_AUTH_SECRET")!,
plugins: [organization()],
});
const backend = createBetterAuthBackend({
auth,
sessionTokenSecret: Deno.env.get("BETTER_AUTH_SECRET")!,
});
For better-auth options that NetScript does not surface directly, use betterAuthOptions (typed as
Omit<BetterAuthOptions, "database" | "plugins">). NetScript owns database through its Prisma
adapter, and plugins use the dedicated plugins field, so both are excluded from that escape hatch.
When the organization plugin is enabled, the active-organization fields better-auth writes onto the
session (activeOrganizationId, role, roles, and permissions) and the user's roles flow through
NetScript's authenticator onto the Principal — its scopes, roles, and claims — so downstream
services and pages can authorize on organization context without any extra wiring.
What runs today, and what needs a prerequisite
A plugin enabled through the passthrough type-checks and is mounted at the better-auth layer. Whether it is runnable depends on what the plugin needs at runtime.
Stateless plugins run as-is
bearer and jwt add no tables of their own. They run through the passthrough alone, with no
further setup.
Table-backed plugins need a schema migration
Interactive plugins are driven by better-auth directly
Where to go next
Auth model — how Principals, sessions, and backends fit together.
Authentication — the authentication capability overview.
- Reference: auth-better-auth — generated symbols for every export shown here.