New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@startupkit/auth

Package Overview
Dependencies
Maintainers
2
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@startupkit/auth

Auth package for StartupKit

latest
Source
npmnpm
Version
0.6.6
Version published
Maintainers
2
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 31 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts