better-auth AT Protocol (Bluesky) Plugin

0.1.0 · active · verified Wed Apr 22

This package provides an AT Protocol (Bluesky) OAuth plugin for the `better-auth` framework. It enables users to sign in with their Bluesky or any AT Protocol Personal Data Server (PDS) account, leveraging OAuth 2.0 with PKCE and DPoP for secure authentication. Currently at version 0.1.0 (initial release), its release cadence is expected to be event-driven as a new, specialized plugin. Key differentiators include built-in support for localhost development without tunnels via AT Protocol's loopback client, automatic hosting of necessary OAuth discovery endpoints (`client-metadata.json` and `jwks.json`), and persistence of OAuth state and session data through `better-auth`'s database adapter. It also features automatic profile synchronization, updating user details like DID, handle, and display name.

Common errors

Warnings

Install

Imports

Quickstart

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');

view raw JSON →