Username
Add username sign-up and username/password sign-in.
The username plugin lets users sign up and sign in with a username instead of an
email. Kernia stores a normalized (lower-cased) username for uniqueness plus an
optional displayUsername that preserves the casing the user typed.
Installation
Add the plugin to your server
Pass username() to your Kernia config. Length bounds and validators are
optional constructor arguments.
import os
from kernia import KerniaOptions
from kernia.auth import init
from kernia.plugins.username import username
auth = init(KerniaOptions(
database=adapter,
secret=os.environ["KERNIA_SECRET"],
base_url=os.environ["KERNIA_BASE_URL"],
plugins=[username(min_username_length=3, max_username_length=30)],
))Add the client plugin
Kernia speaks the Better Auth wire protocol, so the official JavaScript client
works unchanged. Add the username client plugin:
import { createAuthClient } from "better-auth/client";
import { usernameClient } from "better-auth/client/plugins";
export const authClient = createAuthClient({
baseURL: "/api/auth",
plugins: [usernameClient()],
});Usage
Sign up with a username
Sign-up attaches the username to a standard account. Pass username (and
optionally displayUsername) alongside the usual fields.
await authClient.signUp.email({
email: "user@example.com",
name: "Ada",
password: "the-password",
username: "ada",
displayUsername: "Ada",
});Sign in with a username
await authClient.signIn.username({
username: "ada",
password: "the-password",
});Check whether a username is available
Useful for inline validation on a sign-up form before submitting.
const { data } = await authClient.isUsernameAvailable({ username: "ada" });
// data.available -> booleanOptions
Pass these as keyword arguments to username(...):
| Option | Type | Default | Description |
|---|---|---|---|
min_username_length | int | 3 | Minimum allowed username length. |
max_username_length | int | 30 | Maximum allowed username length. |
username_validator | (str) -> bool | — | Custom check; return False to reject a username. |
display_username_validator | (str) -> bool | — | Custom check for the display username. |
username_normalization | (str) -> str | bool | lowercase | Normalizer applied before storage; pass False to keep casing. |
display_username_normalization | (str) -> str | bool | — | Normalizer for the display username. |
Schema
The plugin extends the core user table:
usernamedisplayUsernameGenerate a migration before enabling it against a persistent database.
Lookups use the normalized username, so Ada and ada collide. Keep
displayUsername for presentation and never query against it for uniqueness.