@tacobase/client
v1.0.4
Published
tacobase client SDK — auth, database, storage, and realtime for your apps
Maintainers
Readme
Auth, database, realtime, and file storage — all wrapped in one tight TypeScript SDK.
npm install @tacobase/clientTable of Contents
- Quickstart
- Authentication
- Database
- Realtime
- File Storage
- RPC
- Admin API
- Advanced
- API Reference
- Related packages
Quickstart
import { createClient } from '@tacobase/client'
// Zero-config — reads TACOBASE_URL and TACOBASE_API_KEY from env
const db = createClient()
// Or pass them explicitly
const db = createClient('https://myapp.tacobase.dev', 'tbk_xxxxxxxx_...')Get your URL and API key from the tacobase dashboard.
# .env.local
TACOBASE_URL=https://your-app.tacobase.dev
TACOBASE_API_KEY=tbk_your_key_here
# Next.js client-side? Prefix it.
NEXT_PUBLIC_TACOBASE_URL=https://your-app.tacobase.dev
NEXT_PUBLIC_TACOBASE_API_KEY=tbk_your_key_hereAuthentication
Sign up, sign in, OAuth — the whole spread.
// Sign up
const { token, record } = await db.auth.signUp({
email: '[email protected]',
password: 'securepassword',
name: 'Jane Doe',
})
// Sign in
const { token, record } = await db.auth.signIn({
email: '[email protected]',
password: 'securepassword',
})
// OAuth (Google, GitHub, etc. — configure providers in the dashboard)
const { token, record } = await db.auth.signInWithOAuth({ provider: 'google' })
// Current session
const user = db.auth.user // RecordModel | null
const isValid = db.auth.isValid // boolean
// Listen for auth changes
const unsubscribe = db.auth.onStateChange((event, record) => {
// event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED'
console.log(event, record?.email)
})
// Password reset
await db.auth.requestPasswordReset('[email protected]')
// Sign out
db.auth.signOut()Database
Collections auto-create on first write. No migrations, no setup hell.
// List with pagination, filtering, and sorting
const result = await db.collection('posts').getList(1, 20, {
filter: 'published = true',
sort: '-created',
expand: 'author',
})
// result.items, result.totalItems, result.totalPages
// Single record
const post = await db.collection('posts').getOne('RECORD_ID')
// First match
const admin = await db.collection('users').getFirstListItem('role = "admin"')
// All records (auto-paginates — careful on large collections)
const allPosts = await db.collection('posts').getFullList({ filter: 'published = true' })
// Create
const newPost = await db.collection('posts').create({
title: 'Hello World',
content: 'My first post',
published: true,
})
// Update
const updated = await db.collection('posts').update('RECORD_ID', { title: 'Updated Title' })
// Delete
await db.collection('posts').delete('RECORD_ID')TypeScript generics
interface Post {
id: string
title: string
content: string
published: boolean
created: string
updated: string
}
const posts = await db.collection<Post>('posts').getList(1, 20)
// posts.items is Post[] ✓File uploads
const formData = new FormData()
formData.append('title', 'Photo post')
formData.append('image', fileInput.files[0])
const record = await db.collection('posts').create(formData)Filter syntax — the secret sauce 🌶️
| Operator | Example | Meaning |
|---|---|---|
| = | status = "active" | Exact match |
| ~ | title ~ "hello" | Contains (ILIKE) |
| > < >= <= | score > 5 | Numeric comparison |
| ?~ | tags ?~ "featured" | Array contains |
| && / \|\| | a = "x" && b = "y" | AND / OR |
Realtime
Live updates over SSE. Subscribe and forget.
// All changes on a collection
const unsubscribe = await db.collection('posts').subscribe((event) => {
console.log(event.action, event.record) // 'create' | 'update' | 'delete'
})
// One specific record
const unsubscribe = await db.collection('posts').subscribeOne('RECORD_ID', (event) => {
console.log(event.action, event.record)
})
await unsubscribe()
await db.realtime.disconnectAll()File Storage
Files live as fields on records. Grab URLs, thumbnails, and protected tokens.
const user = await db.collection('users').getOne('USER_ID')
// Public URL
const url = db.storage.getFileUrl(user, 'avatar.jpg')
// Thumbnail
const thumb = db.storage.getFileUrl(user, 'avatar.jpg', { thumb: '100x100' })
// Protected file — get a temp token first
const token = await db.storage.getFileToken()
const protectedUrl = db.storage.getFileUrl(user, 'document.pdf', { token })RPC
Call server-side functions like a pro.
const result = await db.rpc('calculate_cart_total', { cart_id: '123' })
// Typed response
interface DashboardStats { posts: number; comments: number; followers: number }
const stats = await db.rpc<DashboardStats>('get_dashboard_stats', { user_id: currentUser.id })Admin API
Manage collections programmatically. Requires an admin API key.
const adminDb = createClient('https://myapp.tacobase.dev', 'tbk_admin_xxxxxxxx')
// Flexible collection — schema-free JSONB, great for prototyping
await adminDb.admin.createCollection({ name: 'posts', type: 'flexible' })
// Strict collection — typed SQL columns, great for production
await adminDb.admin.createCollection({
name: 'products',
type: 'strict',
schema: [
{ name: 'title', type: 'text', required: true },
{ name: 'price', type: 'numeric' },
{ name: 'in_stock', type: 'boolean', default: true },
],
})
await adminDb.admin.listCollections()
await adminDb.admin.getCollection('posts')
await adminDb.admin.updateCollection('posts', { name: 'articles' })
await adminDb.admin.deleteCollection('articles')Collection types
| Type | Storage | Best for |
|---|---|---|
| flexible | JSONB — schema-free | Prototyping, variable-structure data |
| strict | Typed SQL columns | Production data, enforced schema |
Strict field types: text · integer · bigint · boolean · jsonb · timestamptz · uuid · numeric · real
Advanced
Cold-start handling
tacobase instances may scale to zero when idle. The SDK retries automatically on 503 with exponential backoff (2s → 4s → 8s).
const db = createClient('https://myapp.tacobase.dev', 'tbk_...', {
maxColdStartRetries: 5, // default: 3
})
// Warm the connection before a critical flow
await db.wake() // GET /api/db/health — absorbs cold-start latency upfrontError handling
Every error includes a code and fix with actionable suggestions. No mystery errors.
import { TacoError, AuthorizationError, CollectionNotFoundError } from '@tacobase/client'
try {
await db.collection('posts').getList()
} catch (err) {
if (err instanceof TacoError) {
console.log(err.message) // "Collection 'posts' not found."
console.log(err.code) // "COLLECTION_NOT_FOUND"
console.log(err.fix) // "Make sure the collection 'posts' exists..."
}
}| Error | Code | When |
|---|---|---|
| ConfigurationError | CONFIGURATION_ERROR | Missing URL, API key, or bad config |
| AuthorizationError | UNAUTHORIZED | Invalid or missing API key |
| CollectionNotFoundError | COLLECTION_NOT_FOUND | Collection doesn't exist |
| RecordNotFoundError | RECORD_NOT_FOUND | Record ID not found |
| InstanceUnavailableError | INSTANCE_UNAVAILABLE | Instance down after retries |
| RpcError | RPC_ERROR | RPC function call failed |
| RequestError | REQUEST_FAILED | Generic HTTP error |
API Reference
createClient(url?, apiKey?, options?)
| Parameter | Type | Description |
|---|---|---|
| url | string | Your tacobase instance URL |
| apiKey | string | API key from the dashboard (starts with tbk_) |
| options.timeout | number | Request timeout in ms. Default: 30000 |
| options.maxColdStartRetries | number | Max retries on 503. Default: 3 |
| options.fetch | typeof fetch | Custom fetch implementation |
Modules
| Module | Type | Description |
|---|---|---|
| db.auth | TacoAuth | Sign up, sign in, OAuth, session management |
| db.collection(name) | TacoCollection | CRUD on a collection |
| db.realtime | TacoRealtime | Realtime subscriptions (SSE) |
| db.storage | TacoStorage | File URLs and tokens |
| db.admin | TacoAdmin | Collection management (admin key required) |
Related packages
| Package | Description |
|---|---|
| @tacobase/react | React hooks — useAuth, useCollection, useRealtime |
| @tacobase/cli | CLI — taco init, taco dev, taco typegen |
| @tacobase/taco | Drop-in AI context — installs this + writes TACOBASE.md |
| @tacobase/mcp-server | MCP server — let your AI manage schema via natural language |
tacobase.dev · docs · github
License
MIT
