npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stripe/link-integrations-better-auth

v0.2.0

Published

Sign in with Link and connect Link wallets using Better Auth

Readme

Link for Better Auth

Sign in with Link or connect a Link wallet to an existing user. Better Auth manages OAuth, token storage, and refresh.

Setup

Requires Node.js 22+ and Better Auth 1.7.5+.

pnpm add @stripe/link-integrations-better-auth better-auth

Register a Link OAuth client with the callback URL https://yourapp.com/api/auth/callback/link. Adjust the path if you use a custom Better Auth base path, and register any local development callback too.

Add the plugin to your server configuration:

import { betterAuth } from 'better-auth';
import { link } from '@stripe/link-integrations-better-auth';

export const auth = betterAuth({
  account: {
    encryptOAuthTokens: true,
    accountLinking: {
      trustedProviders: ['link'],
      // Allow the wallet email to differ from the app user's email.
      allowDifferentEmails: true,
    },
  },
  plugins: [
    link({
      clientId: process.env.LINK_CLIENT_ID!,
      clientSecret: process.env.LINK_CLIENT_SECRET!,
      publishableKey: process.env.STRIPE_PUBLISHABLE_KEY!,
    }),
  ],
});

Then register the client plugin:

import { linkClient } from '@stripe/link-integrations-better-auth/client';
import { createAuthClient } from 'better-auth/react';

export const authClient = createAuthClient({ plugins: [linkClient()] });

Default scopes are payment_methods.agentic and userinfo:read. For sign-in only, set scopes: ['userinfo:read'] in link(...). Keep userinfo:read when customizing scopes.

Connect a wallet

After the user signs in to your app:

await authClient.link.connect({ callbackURL: '/settings' });

For server-side usage:

await auth.api.connectLink({
  body: { callbackURL: '/settings' },
  headers: await headers(),
});

This starts Better Auth's OAuth linking flow and returns the user to /settings after authorization.

connect follows Better Auth's configured client error handling.

Disconnect a wallet

Find the connected account and pass its Better Auth record ID:

const { data: accounts, error } = await authClient.listAccounts();
if (error) throw new Error(error.message);

const account = accounts?.find((account) => account.providerId === 'link');
if (account) {
  const { error } = await authClient.link.disconnect({ accountId: account.id });
  if (error) throw new Error(error.message);
}

Disconnect requires a fresh session and protects the user's last sign-in method by default. It revokes Link access before deleting the local account; failed revocation keeps the connection intact for retry.

Use account.id for account operations. account.accountId is the stable Link user ID.

Sign in with Link

To let users sign in or create an app account with Link:

await authClient.signIn.social({
  provider: 'link',
  callbackURL: '/dashboard',
});

Better Auth's account-linking and email-verification policies apply. Use authClient.accountInfo() for the connected profile and server-side auth.api.getAccessToken() for Link API calls.

Example

See the Next.js example for a runnable app with sign-in, wallet connection, and disconnect.