Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
atprotoAuth
✓ import { atprotoAuth } from 'better-auth-atproto';
✗ const atprotoAuth = require('better-auth-atproto');
This is the primary named export for the server-side plugin. The package is ESM-first.
atprotoAuthClient
✓ import { atprotoAuthClient } from 'better-auth-atproto/client';
✗ import { atprotoAuthClient } from 'better-auth-atproto';
The client-side plugin is imported from a specific subpath. The README snippet incorrectly references 'better-auth-bsky/client' due to a likely typo.
betterAuth
✓ import { betterAuth } from 'better-auth';
✗ import betterAuth from 'better-auth';
The core 'better-auth' factory function is a named export, not a default export.
createAuthClient
✓ import { createAuthClient } from 'better-auth/client';
✗ import { createAuthClient } from 'better-auth';
The client-side factory for 'better-auth' is imported from its dedicated client subpath.
This quickstart demonstrates how to integrate the better-auth-atproto plugin on both the server and client sides, including basic configuration with a private key (for production) and initiating a Bluesky sign-in flow.
import { betterAuth } from 'better-auth';
import { atprotoAuth } from 'better-auth-atproto';
import { createAuthClient } from 'better-auth/client';
import { atprotoAuthClient } from 'better-auth-atproto/client';
// 1. (Optional) Generate a private key for production:
// openssl ecparam -name prime256v1 -genkey -noout -out ec-private.pem
// 2. Server-side configuration
export const auth = betterAuth({
baseURL: process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000', // Required for callbacks and discovery endpoints
plugins: [
atprotoAuth({
privateKey: process.env.BSKY_PRIVATE_KEY ?? '', // Required for production, optional for localhost
clientMetadata: {
clientName: 'My Awesome App',
scope: 'atproto transition:generic'
},
mapProfileToUser: (profile) => ({
name: profile.displayName || `@${profile.handle}`,
image: profile.avatar,
}),
}),
],
});
// 3. Run migrations after adding plugin: `npx auth migrate` or `npx auth generate`
// 4. Client-side configuration
export const authClient = createAuthClient({
plugins: [atprotoAuthClient()],
});
// 5. Example client-side sign-in flow
async function initiateSignIn(handle: string, callbackURL: string) {
try {
await authClient.signIn.bsky({
handle: handle,
callbackURL: callbackURL,
});
console.log('Bluesky sign-in initiated successfully!');
} catch (error) {
console.error('Failed to initiate Bluesky sign-in:', error);
}
}
// Example usage (e.g., in a React component or server action)
// initiateSignIn('example.bsky.social', '/dashboard');
Errors
Common errors & fixes
TypeError: Cannot read properties of undefined (reading 'split') OR Invalid DPoP Private Key: The privateKey option must be a valid PEM-encoded ES256 private key.
Missing, invalid, or improperly formatted private key provided in a production environment.
fixVerify that `process.env.BSKY_PRIVATE_KEY` contains the full PEM-encoded ES256 private key string and is correctly passed to the `privateKey` option in `atprotoAuth`.
Error: Failed to initiate Bluesky sign-in: authClient.signIn.bsky is not a function
The client-side `atprotoAuthClient` plugin was not correctly configured or imported into `createAuthClient`.
fixEnsure `import { atprotoAuthClient } from 'better-auth-atproto/client';` is used and `atprotoAuthClient()` is passed within the `plugins` array to `createAuthClient`. Database error: column "bskyDid" of relation "user" does not exist (or similar schema mismatch error)
Database migrations were not executed after the `better-auth-atproto` plugin was added to the server configuration.
fixRun `npx auth migrate` in your project's root directory to apply the necessary database schema changes for the plugin.
Audit
Dependencies
better-authrequiredCore authentication framework dependency.
zodrequiredSchema validation, likely for configuration or API responses within the better-auth ecosystem.