Supabase JavaScript Client: Complete SDK Guide

The Supabase JavaScript client (@supabase/supabase-js) is your primary interface for interacting with Supabase from web and mobile applications, providing a clean, intuitive API for database queries, authentication, storage, and real-time subscriptions. This comprehensive guide covers client installation, initialization with TypeScript support, database operations with query builders, authentication methods, error handling patterns, and best practices for production applications. Whether you're building with React, Next.js, Vue, Svelte, or vanilla JavaScript, mastering the Supabase client enables rapid development while maintaining type safety and performance. The client automatically handles authentication tokens, request retries, and connection management, letting you focus on building features instead of infrastructure. Before starting, complete Supabase setup to have your project credentials ready.
Installing Supabase Client
# Install Supabase JavaScript client
# Using npm
npm install @supabase/supabase-js
# Using yarn
yarn add @supabase/supabase-js
# Using pnpm
pnpm add @supabase/supabase-js
# For TypeScript projects (recommended)
npm install --save-dev typescript @types/node
# Generate TypeScript types from your database schema
npx supabase gen types typescript --project-id your-project-ref > src/types/supabase.tsClient Initialization
// Basic JavaScript initialization
// supabaseClient.js
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
// TypeScript initialization with type safety
// supabaseClient.ts
import { createClient } from '@supabase/supabase-js'
import { Database } from './types/supabase'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
export const supabase = createClient<Database>(
supabaseUrl,
supabaseAnonKey,
{
auth: {
persistSession: true,
autoRefreshToken: true,
detectSessionInUrl: true
},
db: {
schema: 'public'
},
global: {
headers: { 'x-application-name': 'my-app' }
}
}
)
// Now TypeScript knows your database schema!
const { data } = await supabase
.from('users') // ✅ Autocomplete works
.select('id, email, created_at') // ✅ Column names validatedCreate a single Supabase client instance and reuse it throughout your application. The client handles authentication state automatically, refreshing tokens before expiration. TypeScript integration provides autocomplete for table names, column selections, and query operations, catching errors at compile time instead of runtime. Learn database queries for advanced query patterns.
Query Builder Basics
// SELECT queries
// Get all rows
const { data, error } = await supabase
.from('posts')
.select('*')
// Select specific columns
const { data } = await supabase
.from('posts')
.select('id, title, author_id')
// Filter with conditions
const { data } = await supabase
.from('posts')
.select('*')
.eq('status', 'published')
.gt('views', 100)
.order('created_at', { ascending: false })
.limit(10)
// INSERT data
const { data, error } = await supabase
.from('posts')
.insert([
{ title: 'First Post', content: 'Hello World' }
])
.select()
// UPDATE data
const { data, error } = await supabase
.from('posts')
.update({ status: 'published' })
.eq('id', postId)
.select()
// DELETE data
const { error } = await supabase
.from('posts')
.delete()
.eq('id', postId)
// Count rows
const { count } = await supabase
.from('posts')
.select('*', { count: 'exact', head: true })Authentication Methods
// Sign up new user
const { data, error } = await supabase.auth.signUp({
email: '[email protected]',
password: 'secure-password'
})
// Sign in
const { data, error } = await supabase.auth.signInWithPassword({
email: '[email protected]',
password: 'secure-password'
})
// OAuth sign in
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google'
})
// Get current user
const { data: { user } } = await supabase.auth.getUser()
// Sign out
await supabase.auth.signOut()
// Listen to auth changes
supabase.auth.onAuthStateChange((event, session) => {
if (event === 'SIGNED_IN') console.log('User signed in')
if (event === 'SIGNED_OUT') console.log('User signed out')
})The client manages authentication state automatically, storing sessions in localStorage by default. All database queries include the user's JWT token, enabling Row Level Security policies to enforce access control. Learn complete authentication patterns for production apps.
Error Handling Best Practices
// Always check for errors
const { data, error } = await supabase
.from('posts')
.select('*')
if (error) {
console.error('Database error:', error.message)
// Handle error appropriately
return
}
// TypeScript error handling
type Post = Database['public']['Tables']['posts']['Row']
const { data, error } = await supabase
.from('posts')
.select('*')
.returns<Post[]>()
if (error) throw error
// data is now typed as Post[]
console.log(data[0].title)
// Try-catch with async operations
try {
const { data, error } = await supabase
.from('posts')
.insert({ title: 'New Post' })
.select()
.single()
if (error) throw error
console.log('Created:', data)
} catch (err) {
console.error('Failed to create post:', err)
}Real-time Subscriptions
// Subscribe to database changes
const channel = supabase
.channel('posts-changes')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'posts' },
(payload) => {
console.log('Change received!', payload)
}
)
.subscribe()
// Cleanup subscription
supabase.removeChannel(channel)Production Best Practices
- Use Environment Variables: Store credentials in .env files, never commit to version control
- Enable TypeScript: Generate types from schema for autocomplete and type safety
- Handle Errors: Always check error objects and provide user-friendly messages
- Implement Loading States: Show loaders during async operations for better UX
- Use Row Level Security: Protect data at database level, not just client validation
- Optimize Queries: Select only needed columns, use indexes, implement pagination
Conclusion
The Supabase JavaScript client provides a powerful, type-safe interface for building modern applications with minimal boilerplate. Its query builder simplifies database operations while maintaining flexibility, authentication integration handles user sessions automatically, and real-time subscriptions enable live features without complex infrastructure. TypeScript support catches errors early and provides excellent developer experience with autocomplete and inline documentation. Whether you're building a simple CRUD app or complex SaaS platform, the Supabase client scales from prototype to production while maintaining clean, maintainable code. With client installation complete and initialization configured, you're ready to build full-stack applications. Continue learning with database query patterns, authentication implementation, and framework integrations to build production-ready applications.
$ share --platform
$ cat /comments/ (0)
$ cat /comments/
// No comments found. Be the first!


