Skip to content
Migrating from NextAuth.js v4? Read our migration guide.

NATS KV Adapter

Resources

Setup

Installation

npm install @nats-io/transport-node @nats-io/kv @auth/nats-kv-adapter

Environment Variables

NATS_SERVERS,
NATS_CREDS

Configuration

You can either use this with Symbol.asyncDispose or handle the disposal yourself.

With explicit resource management

If you do choose asyncDispose, make sure you environment is configured to handled that by targeting at least es2022 and the lib option to include esnext or esnext.disposable, or by providing a polyfill. Using this pattern the adapter will call the cleanup function when the adapter is after NATS operations. https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management

./auth.ts
import NextAuth from "next-auth"
import { NatsKVAdapter } from "@auth/nats-kv-adapter"
import { connect } from "@nats-io/transport-node"
import { Kvm, KV } from "@nats-io/kv"
 
async function getNats(): Promise<
  { kv: KV } & {
    [Symbol.asyncDispose]: () => Promise<void>
  }
> {
  const nc = await connect({
    servers: process.env.NATS_SERVERS,
    authenticator: process.env.NATS_CREDS,
  })
  const kvm = new Kvm(nc)
  const kv = await kvm.create("name-of-auth-bucket")
 
  return {
    kv: kv,
    [Symbol.asyncDispose]: async () => {
      await nc.drain()
      await nc.close()
    },
  }
}
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: NatsKVAdapter(getNats),
  providers: [],
})

Without explicit resource management

You can instead provide the adapter with a KV instance, and handle the connection and disposal yourself. Useful if you want to keep the connection alive, or have explicit control over the connection.

./auth.ts
import NextAuth from "next-auth"
import { NatsKVAdapter } from "@auth/nats-kv-adapter"
import { connect } from "@nats-io/transport-node"
import { Kvm, KV } from "@nats-io/kv"
 
const nc = await connect({
  servers: process.env.NATS_SERVERS,
  authenticator: process.env.NATS_CREDS,
})
const kvm = new Kvm(nc)
const kv = await kvm.create("name-of-auth-bucket")
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: NatsKVAdapter(kv),
  providers: [],
})

Advanced usage

If you have multiple Auth.js connected apps using this instance, you need different key prefixes for every app.

You can change the prefixes by passing an options object as the second argument to the adapter factory function.

The default values for this object are:

const defaultOptions = {
  baseKeyPrefix: "",
  accountKeyPrefix: "user:account:",
  accountByUserIdPrefix: "user:account:by-user-id:",
  emailKeyPrefix: "user:email:",
  sessionKeyPrefix: "user:session:",
  sessionByUserIdKeyPrefix: "user:session:by-user-id:",
  userKeyPrefix: "user:",
  verificationTokenKeyPrefix: "user:token:",
}

Usually changing the baseKeyPrefix should be enough for this scenario, but for more custom setups, you can also change the prefixes of every single key.

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: NatsKVAdapter(kv, { baseKeyPrefix: "app2:" }),
})
Auth.js © Balázs Orbán and Team - 2025