Skip to main content

JavaScript SDK Reference

Complete API reference for @naijabase/js.

Installation​

npm install @naijabase/js

Latest version: v0.1.1 — npmjs.com/package/@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