New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@startupkit/auth

Package Overview
Dependencies
Maintainers
2
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@startupkit/auth

Auth package for StartupKit

Source
npmnpm
Version
0.7.0
Version published
Weekly downloads
0
Maintainers
2
Weekly downloads
 
Created
Source

@startupkit/auth

Lightweight Authentication and Authorization components and hooks for StartupKit projects.

Part of StartupKit - The Zero to One Startup Framework.

Installation

pnpm add @startupkit/auth better-auth

Or use the StartupKit CLI to get started with a complete monorepo setup:

npx startupkit init

What's Included

This package provides lightweight wrappers around Better Auth:

  • 🎨 AuthProvider - React context provider for client components
  • 🪝 useAuth() - Authentication hook for client components
  • 🔒 Full TypeScript support

You call betterAuth() directly in your project for full control over configuration.

Usage

1. Configure Better Auth (Server-Side)

Create your auth configuration with Better Auth directly:

// lib/auth.ts
import { betterAuth } from "better-auth"
import { drizzleAdapter } from "better-auth/adapters/drizzle"
import { nextCookies } from "better-auth/next-js"
import { emailOTP } from "better-auth/plugins"
import { db } from "@/lib/db"

export const auth = betterAuth({
  basePath: "/auth",
  database: drizzleAdapter(db, {
    provider: "pg"
  }),
  session: {
    expiresIn: 60 * 60 * 24 * 7, // 7 days
    updateAge: 60 * 60 * 24 // Refresh every 24 hours
  },
  plugins: [
    emailOTP({
      sendVerificationOTP: async ({ email, otp }) => {
        // Send OTP via your email provider
        await sendEmail({
          to: email,
          subject: "Your verification code",
          template: "otp",
          data: { code: otp }
        })
      }
    }),
    nextCookies()
  ],
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!
    }
  }
})

2. Create API Route Handler

Create the auth API route at app/auth/[...all]/route.ts:

// app/auth/[...all]/route.ts
import { auth } from "@/lib/auth"
import { toNextJsHandler } from "better-auth/next-js"

export const { GET, POST } = toNextJsHandler(auth.handler)

3. Create Auth Client (Client-Side)

Create your auth client using Better Auth:

// lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
import { emailOTPClient } from "better-auth/client/plugins"

export const authClient = createAuthClient({
  basePath: "/auth",
  plugins: [emailOTPClient()]
})

4. Set Up Providers

Wrap your app with the AuthProvider from @startupkit/auth:

// app/providers.tsx
"use client"

import { AuthProvider } from "@startupkit/auth"
import { authClient } from "@/lib/auth-client"

interface ProvidersProps {
  children: React.ReactNode
  user?: User
}

export function Providers({ children, user }: ProvidersProps) {
  return (
    <AuthProvider 
      authClient={authClient}
      user={user}
      onIdentify={(user) => {
        // Optional: Track user identification (e.g., analytics)
        console.log("User identified:", user)
      }}
      onReset={() => {
        // Optional: Reset state on logout (e.g., clear analytics)
        console.log("User logged out")
      }}
    >
      {children}
    </AuthProvider>
  )
}

Pass the user from your root layout:

// app/layout.tsx
import { auth } from "@/lib/auth"
import { headers } from "next/headers"
import { Providers } from "./providers"

export default async function RootLayout({ children }) {
  const session = await auth.api.getSession({
    headers: await headers()
  })

  return (
    <html>
      <body>
        <Providers user={session?.user}>
          {children}
        </Providers>
      </body>
    </html>
  )
}

5. Use Authentication in Components

Access authentication state and methods with the useAuth hook:

"use client"

import { useAuth } from "@startupkit/auth"

export function UserProfile() {
  const { isAuthenticated, isLoading, user, logout } = useAuth()

  if (isLoading) {
    return <div>Loading...</div>
  }

  if (!isAuthenticated) {
    return <a href="/sign-in">Sign In</a>
  }

  return (
    <div>
      <p>Welcome, {user.name}</p>
      <button onClick={logout}>Sign Out</button>
    </div>
  )
}

Authentication Methods

Email OTP (One-Time Password)

"use client"

import { useAuth } from "@startupkit/auth"
import { useState } from "react"

export function EmailSignIn() {
  const { sendAuthCode, verifyAuthCode } = useAuth()
  const [email, setEmail] = useState("")
  const [code, setCode] = useState("")
  const [step, setStep] = useState<"email" | "code">("email")

  const handleSendCode = async (e: React.FormEvent) => {
    e.preventDefault()
    await sendAuthCode(email)
    setStep("code")
  }

  const handleVerifyCode = async (e: React.FormEvent) => {
    e.preventDefault()
    await verifyAuthCode(email, code)
    // User is now authenticated
  }

  if (step === "email") {
    return (
      <form onSubmit={handleSendCode}>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="Enter your email"
          required
        />
        <button type="submit">Send Code</button>
      </form>
    )
  }

  return (
    <form onSubmit={handleVerifyCode}>
      <input
        type="text"
        value={code}
        onChange={(e) => setCode(e.target.value)}
        placeholder="Enter verification code"
        required
      />
      <button type="submit">Verify</button>
    </form>
  )
}

Google OAuth

"use client"

import { useAuth } from "@startupkit/auth"

export function GoogleSignIn() {
  const { googleAuth } = useAuth()

  return (
    <button onClick={googleAuth}>
      Sign in with Google
    </button>
  )
}

Sign Out

"use client"

import { useAuth } from "@startupkit/auth"

export function SignOutButton() {
  const { logout } = useAuth()

  return (
    <button onClick={logout}>
      Sign Out
    </button>
  )
}

Server-Side Authentication

Protect Server Components

// app/dashboard/page.tsx
import { auth } from "@/lib/auth"
import { headers } from "next/headers"
import { redirect } from "next/navigation"

export default async function DashboardPage() {
  const session = await auth.api.getSession({
    headers: await headers()
  })

  if (!session) {
    redirect("/sign-in")
  }

  return (
    <div>
      <h1>Dashboard</h1>
      <p>Welcome, {session.user.name}</p>
    </div>
  )
}

Use in API Routes

// app/api/profile/route.ts
import { auth } from "@/lib/auth"
import { headers } from "next/headers"
import { NextResponse } from "next/server"

export async function GET() {
  const session = await auth.api.getSession({
    headers: await headers()
  })

  if (!session) {
    return NextResponse.json(
      { error: "Unauthorized" },
      { status: 401 }
    )
  }

  return NextResponse.json({
    user: session.user
  })
}

Features

Supported Authentication Methods

  • ✅ Email OTP - One-time password via email (10-minute expiration)
  • ✅ Google OAuth - Sign in with Google
  • ✅ Session Management - 7-day sessions with 24-hour auto-refresh
  • ✅ TypeScript - Full type safety

Built With

This package is a lightweight wrapper around Better Auth, providing:

  • React context and hooks for easy integration
  • Server utilities for Next.js
  • TypeScript type definitions
  • Minimal configuration required

API Reference

Client Exports

AuthProvider

React context provider wrapping Better Auth client.

interface AuthProviderProps {
  children: React.ReactNode
  user?: User
  authClient: BetterAuthClient
  onIdentify?: (user: User) => void
  onReset?: () => void
}

useAuth()

Hook to access authentication state and methods.

const {
  isAuthenticated,    // boolean - Is user authenticated?
  isLoading,          // boolean - Is session loading?
  user,               // User | null | undefined - Current user
  logout,             // () => Promise<void> - Sign out user
  sendAuthCode,       // (email: string) => Promise<void> - Send OTP
  verifyAuthCode,     // (email: string, code: string) => Promise<void> - Verify OTP
  googleAuth          // () => Promise<void> - Sign in with Google
} = useAuth()

AuthContext

React context (if you need direct access).

import { AuthContext } from "@startupkit/auth"

Configuration

All authentication configuration happens in Better Auth directly. See the Better Auth documentation for complete configuration options including:

  • Email/password authentication
  • Social providers (Google, GitHub, etc.)
  • Magic links
  • Two-factor authentication
  • Custom database adapters
  • Hooks and middleware

Environment Variables

Required for Google OAuth:

GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

Learn More

Support

Having issues? Open an issue on GitHub

License

ISC © 2025 01 Studio

FAQs

Package last updated on 01 Sep 2026

Related posts