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

better-auth-supabase-plugin

v0.0.3

Published

Supabase JWT authentication plugin for Better Auth

Readme

Better Auth Supabase JWT Plugin

This plugin for Better Auth provides JWT authentication for Supabase. It generates JWTs that can be used with Supabase's JWT authentication, allowing your Better Auth users to seamlessly authenticate with Supabase services.

Installation

Using npm:

npm install better-auth-supabase-plugin

Using Bun:

bun add better-auth-supabase-plugin

Using Yarn:

yarn add better-auth-supabase-plugin

Usage

Server-side Setup

Add the Supabase JWT plugin to your Better Auth setup:

import { betterAuth } from "better-auth";
import { supabaseJWT } from "better-auth-supabase-plugin";

export const auth = betterAuth({
  plugins: [
    supabaseJWT({
      // Required: Secret key used to sign the JWT
      // This should match your Supabase JWT secret
      jwtSecret: process.env.SUPABASE_JWT_SECRET,
      
      // Optional: JWT expiration time (default: "1h")
      expiresIn: "24h",
      
      // Optional: Additional claims to include in the JWT
      additionalClaims: {
        app_metadata: {
          role: "user"
        }
      }
    })
  ]
});

Client-side Setup

Import the client plugin in your frontend code:

import { createAuthClient } from "better-auth/client";
import { supabaseJWTClient } from "better-auth-supabase-plugin/client";

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

Using with Supabase Client

Here's how to use the JWT with the Supabase client in a React component:

import { useEffect } from 'react';
import { useStore } from '@nanostores/react'; // or the appropriate framework adapter
import { createClient } from '@supabase/supabase-js';
import { authClient } from './auth-client';

// Initialize Supabase client
const supabaseUrl = 'https://your-project.supabase.co';
const supabaseAnonKey = 'your-anon-key';
const supabase = createClient(supabaseUrl, supabaseAnonKey);

function SupabaseAuthComponent() {
  // Use the hook to get the JWT
  const { jwt, token, getJWT } = useStore(authClient.useGetJWT);
  
  // Fetch the JWT when the component mounts
  useEffect(() => {
    getJWT();
  }, []);
  
  // Set the Supabase session when the token is available
  useEffect(() => {
    if (token) {
      supabase.auth.setSession({
        access_token: token,
        refresh_token: '', // No refresh token needed for JWT auth
      });
      
      // Now you can use supabase client with the authenticated session
      // For example:
      supabase.from('your_table').select('*').then(console.log);
    }
  }, [token]);
  
  return (
    <div>
      {jwt ? (
        <div>
          <h2>Authenticated with Supabase</h2>
          <p>User ID: {jwt.user.id}</p>
          <p>User Email: {jwt.user.email}</p>
          <button onClick={getJWT}>Refresh JWT</button>
        </div>
      ) : (
        <p>Loading authentication...</p>
      )}
    </div>
  );
}

Using with Other Frameworks

Vue.js

import { computed, onMounted, ref } from 'vue';
import { useStore } from '@nanostores/vue';
import { authClient } from './auth-client';

export default {
  setup() {
    const authStore = useStore(authClient.useGetJWT);
    
    onMounted(() => {
      authStore.value.getJWT();
    });
    
    const isAuthenticated = computed(() => !!authStore.value.token);
    
    return {
      auth: authStore,
      isAuthenticated
    };
  }
};

Svelte

<script>
  import { useStore } from '@nanostores/svelte';
  import { authClient } from './auth-client';
  import { onMount } from 'svelte';
  
  const auth = useStore(authClient.useGetJWT);
  
  onMount(() => {
    auth.getJWT();
  });
</script>

{#if $auth.jwt}
  <p>User ID: {$auth.jwt.user.id}</p>
  <p>User Email: {$auth.jwt.user.email}</p>
  <button on:click={() => $auth.getJWT()}>Refresh JWT</button>
{:else}
  <p>Loading...</p>
{/if}

API Reference

Server Plugin Options

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | jwtSecret | string | Yes | - | Secret key used to sign the JWT. Must match your Supabase JWT secret | | expiresIn | string | No | "1h" | JWT expiration time in zeit/ms format | | additionalClaims | object | No | {} | Additional claims to include in the JWT payload |

Client Plugin

The client plugin provides the following atoms and actions:

Atoms

  • jwtAtom: Stores the full JWT response
  • tokenAtom: Computed atom that extracts just the token
  • useGetJWT: Main atom for use with framework adapters

Actions

  • getSupabaseJWT(): Fetches a new JWT from the server

JWT Payload

The generated JWT includes the following claims:

{
  "id": "user-id",
  "email": "user-email",
  "aud": "authenticated",
  "role": "authenticated",
  // Any additional claims provided in additionalClaims
}

Security Considerations

  • Store your JWT secret securely and never expose it in client-side code
  • Use environment variables to manage your JWT secret
  • Consider using a strong, randomly generated secret key
  • Rotate your JWT secret periodically for enhanced security
  • Set an appropriate expiration time for your JWTs

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT