Skip to main content

JavaScript SDK Reference

Complete API reference for @naijabase/js.

Installation

npm install @naijabase/js

Initialize

import { createClient } from '@naijabase/js'

const nb = createClient(
'https://api.naijabase.dev', // Your NaijaBase URL
'nb_anon_...' // Your anon key (safe for browser)
)

Database

.from(table)

Returns a query builder for the given table.

nb.from('products')

.select(columns)

Fetch rows. Returns all columns by default.

// All columns
const { data, error } = await nb.from('products').select()

// Specific columns
const { data, error } = await nb.from('products').select('id, name, price')

// Foreign table join
const { data, error } = await nb.from('orders').select('id, total, customers(name, email)')

// Count rows
const { count, error } = await nb.from('products').select('*', { count: 'exact', head: true })

.insert(rows)

Insert one or more rows.

// Single row
const { data, error } = await nb
.from('products')
.insert({ name: 'Puff Puff', price: 200 })
.select()

// Multiple rows
const { data, error } = await nb
.from('products')
.insert([
{ name: 'Jollof Rice', price: 1500 },
{ name: 'Egusi Soup', price: 2000 },
])
.select()

.update(values)

Update rows matching the filter.

const { data, error } = await nb
.from('products')
.update({ price: 250 })
.eq('id', 'uuid-here')
.select()

.upsert(rows)

Insert or update (by primary key).

const { data, error } = await nb
.from('profiles')
.upsert({ user_id: 'uuid', full_name: 'Ada' }, { onConflict: 'user_id' })
.select()

.delete()

Delete rows matching the filter.

const { error } = await nb
.from('products')
.delete()
.eq('id', 'uuid-here')

Filters

Chain these after .select(), .update(), or .delete().

MethodSQL equivalentExample
.eq(col, val)col = val.eq('status', 'active')
.neq(col, val)col != val.neq('status', 'deleted')
.gt(col, val)col > val.gt('price', 100)
.gte(col, val)col >= val.gte('price', 100)
.lt(col, val)col < val.lt('stock', 10)
.lte(col, val)col <= val.lte('stock', 10)
.like(col, pat)col LIKE pat.like('name', '%rice%')
.ilike(col, pat)col ILIKE pat.ilike('name', '%rice%')
.in(col, vals)col IN (vals).in('status', ['active', 'pending'])
.is(col, val)col IS val.is('deleted_at', null)
.contains(col, val)col @> val.contains('tags', ['food'])
.order(col, opts)ORDER BY col.order('created_at', { ascending: false })
.limit(n)LIMIT n.limit(20)
.range(from, to)LIMIT/OFFSET.range(0, 19)
.single()Expect 1 row.single()
.maybeSingle()0 or 1 row.maybeSingle()

Combining filters

// AND (chain multiple filters)
const { data } = await nb
.from('products')
.select()
.eq('category', 'food')
.gt('price', 500)
.order('name')
.limit(10)

// OR filter
const { data } = await nb
.from('products')
.select()
.or('price.gt.1000,stock.lt.5')

RPC (Remote Procedure Calls)

Call a PostgreSQL function:

// Function with no arguments
const { data, error } = await nb.rpc('get_stats')

// Function with arguments
const { data, error } = await nb.rpc('search_products', {
search_term: 'rice',
min_price: 500,
})

Auth

Sign up

const { data, error } = await nb.auth.signUp({ email, password })

Sign in

const { data, error } = await nb.auth.signInWithPassword({ email, password })

Sign out

const { error } = await nb.auth.signOut()

Get current user

const { data: { user } } = await nb.auth.getUser()

Get current session

const { data: { session } } = await nb.auth.getSession()

Update user

const { data, error } = await nb.auth.updateUser({
password: 'newpassword',
data: { full_name: 'Ada Okonkwo' },
})

Reset password

await nb.auth.resetPasswordForEmail('user@example.ng', {
redirectTo: 'https://yourapp.com/reset',
})

Listen for auth changes

const { data: { subscription } } = nb.auth.onAuthStateChange((event, session) => {
console.log(event, session)
})

// Cleanup
subscription.unsubscribe()

Storage

Create bucket

const { data, error } = await nb.storage.createBucket('avatars', { public: true })

Upload

const { data, error } = await nb.storage
.from('avatars')
.upload('user-123.jpg', file, { upsert: true, contentType: 'image/jpeg' })

Get public URL

const { data } = nb.storage.from('avatars').getPublicUrl('user-123.jpg')
// data.publicUrl = 'https://...'

Create signed URL

const { data, error } = await nb.storage
.from('documents')
.createSignedUrl('file.pdf', 3600) // expires in 1 hour

Download

const { data, error } = await nb.storage.from('avatars').download('user-123.jpg')
// data is a Blob

List

const { data, error } = await nb.storage
.from('avatars')
.list('public/', { limit: 50, sortBy: { column: 'name', order: 'asc' } })

Remove

const { error } = await nb.storage.from('avatars').remove(['user-123.jpg'])

Realtime

Subscribe to table changes

const channel = nb
.channel('my-channel')
.on('postgres_changes', { event: '*', schema: 'public', table: 'messages' }, (payload) => {
console.log(payload)
})
.subscribe()

Broadcast

// Send
await channel.send({ type: 'broadcast', event: 'my-event', payload: { foo: 'bar' } })

// Receive
channel.on('broadcast', { event: 'my-event' }, ({ payload }) => console.log(payload))

Presence

// Track
await channel.track({ user_id: 'abc', online_at: new Date().toISOString() })

// Listen
channel.on('presence', { event: 'sync' }, () => {
console.log(channel.presenceState())
})

Unsubscribe

await nb.removeChannel(channel)
await nb.removeAllChannels()

Error handling

All methods return { data, error }. Check error before using data:

const { data, error } = await nb.from('products').select()

if (error) {
console.error(error.message, error.code)
return
}

console.log(data)

Common error codes

CodeMeaning
PGRST116No rows found (when using .single())
42501Row Level Security violation
23505Unique constraint violation
23503Foreign key constraint violation
auth/invalid-emailMalformed email address
auth/email-already-existsEmail already registered
auth/invalid-passwordWrong password