Username
The username plugin is a lightweight plugin that adds username support to the email and password authenticator. This allows users to sign in and sign up with their username instead of their email.
Installation
Add Plugin to the server
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
username()
]
})
Migrate the database
Run the migration or generate the schema to add the necessary fields and tables to the database.
npx @better-auth/cli migrate
npx @better-auth/cli generate
See the Schema section to add the fields manually.
Add the client plugin
import { createAuthClient } from "better-auth/client"
import { usernameClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [
usernameClient()
]
})
Usage
Sign up
To sign up a user with username, you can use the existing signUp.email
function provided by the client. The signUp
function should take a new username
property in the object.
const data = await authClient.signUp.email({
email: "[email protected]",
name: "Test User",
password: "password1234",
username: "test"
})
You can also provide a displayUsername
const data = await authClient.signUp.email({
email: "[email protected]",
name: "Test User",
password: "password1234",
username: "test",
displayUsername: "Test User123"
})
If only username
is provided, the displayUsername
will be set to the pre normalized version of the username
. You can see the Username Normalization and Display Username Normalization sections for more details.
Sign in
To sign in a user with username, you can use the signIn.username
function provided by the client. The signIn
function takes an object with the following properties:
username
: The username of the user.password
: The password of the user.
const data = await authClient.signIn.username({
username: "test",
password: "password1234",
})
Update username
To update the username of a user, you can use the updateUser
function provided by the client.
const data = await authClient.updateUser({
username: "new-username"
})
Check if username is available
To check if a username is available, you can use the isUsernameAvailable
function provided by the client.
const response = await authClient.isUsernameAvailable({
username: "new-username"
});
if(response.data?.available) {
console.log("Username is available");
} else {
console.log("Username is not available");
}
Options
Min Username Length
The minimum length of the username. Default is 3
.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
minUsernameLength: 5
})
]
})
Max Username Length
The maximum length of the username. Default is 30
.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
maxUsernameLength: 100
})
]
})
Username Validator
A function that validates the username. The function should return false if the username is invalid. By default, the username should only contain alphanumeric characters, underscores, and dots.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
usernameValidator: (username) => {
if (username === "admin") {
return false
}
return true
}
})
]
})
Display Username Validator
A function that validates the display username. The function should return false if the display username is invalid. By default, no validation is applied to display username.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
displayUsernameValidator: (displayUsername) => {
// Allow only alphanumeric characters, underscores, and hyphens
return /^[a-zA-Z0-9_-]+$/.test(displayUsername)
}
})
]
})
Username Normalization
A function that normalizes the username, or false
if you want to disable normalization.
By default, usernames are normalized to lowercase, so "TestUser" and "testuser", for example, are considered the same username. The username
field will contain the normalized (lower case) username, while displayUsername
will contain the original username
.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
usernameNormalization: (username) => {
return username.toLowerCase()
.replaceAll("0", "o")
.replaceAll("3", "e")
.replaceAll("4", "a");
}
})
]
})
Display Username Normalization
A function that normalizes the display username, or false
to disable normalization.
By default, display usernames are not normalized. When only username
is provided during signup or update, the displayUsername
will be set to match the original username
value (before normalization). You can also explicitly set a displayUsername
which will be preserved as-is. For custom normalization, provide a function that takes the display username as input and returns the normalized version.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
displayUsernameNormalization: (displayUsername) => displayUsername.toLowerCase(),
})
]
})
Validation Order
By default, username and display username are validated before normalization. You can change this behavior by setting validationOrder
to post-normalization
.
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
plugins: [
username({
validationOrder: {
username: "post-normalization",
displayUsername: "post-normalization",
}
})
]
})
Schema
The plugin requires 2 fields to be added to the user table:
Field Name | Type | Key | Description |
---|---|---|---|
username | string | - | The username of the user |
displayUsername | string | - | Non normalized username of the user |