Tacobase SDK Integration Guide
A step-by-step guide for adding Tacobase to your project. No backend experience required.
What You Get
Tacobase gives your app a complete backend with four building blocks:
| Building block | What it does |
|---|---|
| Auth | Sign up, sign in, sign out, password reset, Google/GitHub login |
| Database | Store, read, update, and delete data (called "collections") |
| Storage | Upload and serve files (images, PDFs, etc.) |
| Realtime | Get instant updates when data changes (no refreshing) |
Before You Start
You need two things from the Tacobase dashboard:
- Your instance URL — looks like
https://myapp.tacobase.dev - Your API key — starts with
tbk_(e.g.tbk_abc12345_xxxxxxxxxxxxxxxx)
To get these:
1. Sign in at the Tacobase dashboard
2. Click Create Instance and give it a name
3. Once created, click into your instance
4. Click Create API Key and copy it somewhere safe — it is only shown once
You also need Node.js installed (version 18 or newer).
Step 1 — Install the SDK
Open your terminal, navigate to your project folder, and run:
npm install @tacobase/clientIf you're using React, also install the React helpers:
npm install @tacobase/client @tacobase/reactStep 2 — Create Your Client
The "client" is the object you use to talk to tacobase. You create it once and use it everywhere.
For any JavaScript/TypeScript project
Create a file called taco.ts (or taco.js) wherever you keep your utility files:
import { createClient } from '@tacobase/client'
const db = createClient(
'https://myapp.tacobase.dev', // <-- replace with your URL
'tbk_abc12345_xxxxxxxxxxxxxxxx' // <-- replace with your API key
)
export default dbFor React projects (recommended)
Instead of importing the client everywhere, wrap your app with the TacoProvider. This gives every component access to Tacobase through hooks.
import { TacoProvider } from '@tacobase/react'
function App() {
return (
<TacoProvider
url="https://myapp.tacobase.dev"
apiKey="tbk_abc12345_xxxxxxxxxxxxxxxx"
>
{/* Everything inside here can use Tacobase hooks */}
<YourApp />
</TacoProvider>
)
}Keep your API key out of your code
Optional but recommended
Store your URL and key in a .env file so they don't end up in git:
NEXT_PUBLIC_TACOBASE_URL=https://myapp.tacobase.dev
NEXT_PUBLIC_TACOBASE_API_KEY=tbk_abc12345_xxxxxxxxxxxxxxxx
# Admin API Key (Keep this secret! Do not expose to client)
TACOBASE_ADMIN_API_KEY=tbk_xyz98765_xxxxxxxxxxxxxxxxThen reference them in your code:
// Vite projects
const db = createClient(
import.meta.env.VITE_TACOBASE_URL,
import.meta.env.VITE_TACOBASE_API_KEY
)
// Next.js projects
const db = createClient(
process.env.NEXT_PUBLIC_TACOBASE_URL!,
process.env.NEXT_PUBLIC_TACOBASE_API_KEY!
)Next.js TIP: Name the variables with a NEXT_PUBLIC_ prefix to make them available in the browser.
Step 3 — Add User Authentication
Option A: Drop-in Auth Form (fastest)
Use the AuthForm component for a full login/signup form with zero config.
import { AuthForm } from '@tacobase/react'
function LoginPage() {
return (
<AuthForm
providers={['google', 'github']}
onSuccess={(user) => {
console.log('Logged in as', user.email)
window.location.href = '/dashboard'
}}
/>
)
}Option B: Build Your Own Login Form
Use the useAuth hook for full control.
Sign-up form
import { useState } from 'react'
import { useAuth } from '@tacobase/react'
function SignUpForm() {
const { signUp } = useAuth()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
async function handleSubmit(e) {
e.preventDefault()
await signUp(email, password)
// Redirect or update UI
}
return (
<form onSubmit={handleSubmit}>
<input type="email" value={email} onChange={e => setEmail(e.target.value)} required />
<input type="password" value={password} onChange={e => setPassword(e.target.value)} required />
<button type="submit">Sign Up</button>
</form>
)
}Step 4 — Protect Pages
Show different content depending on whether the user is logged in.
import { useAuth } from '@tacobase/react'
function App() {
const { user, loading } = useAuth()
// Still checking if user is logged in
if (loading) return <p>Loading...</p>
// Not logged in
if (!user) return <LoginPage />
// Logged in
return (
<div>
<p>Welcome, {user.email}!</p>
<Dashboard />
</div>
)
}Step 5 — Read and Write Data
Collections are like database tables. You can create them from the Tacobase dashboard or programmatically from a secure server environment using the Admin API Key, then read/write from your code.
Create a collection from code (Admin Only)
If you are running in a secure server environment (like a Node.js script or a Next.js API route), you can use the Admin API Key to automatically create your collections. Never use the admin key in client-side code.
import { createClient } from '@tacobase/client'
// 1. Initialize with your Admin API Key
const dbAdmin = createClient(
process.env.NEXT_PUBLIC_TACOBASE_URL!, // The URL is the same
process.env.TACOBASE_ADMIN_API_KEY! // SECRET admin key
)
// 2. Create the collection programmatically
const newCollection = await dbAdmin.admin.createCollection({
name: 'posts',
type: 'base',
schema: [
{ name: 'title', type: 'text', required: true },
{ name: 'content', type: 'editor' },
{ name: 'published', type: 'bool' }
]
})
console.log('Created collection:', newCollection.id)React shortcut: useCollection hook
Fetches data and handles loading/error states automatically.
import { useCollection } from '@tacobase/react'
function PostList() {
const { items, loading, error } = useCollection('posts', {
sort: '-created',
filter: 'published = true',
})
if (loading) return <p>Loading posts...</p>
if (error) return <p>Error: {error.message}</p>
return (
<ul>
{items.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}CRUD Operations (Vanilla JS / Handlers)
// Create
const newPost = await db.collection('posts').create({
title: 'My First Post',
published: true,
})
// Read (List)
const result = await db.collection('posts').getList(1, 20, {
sort: '-created',
})
// Update
await db.collection('posts').update('RECORD_ID', {
title: 'Updated Title',
})
// Delete
await db.collection('posts').delete('RECORD_ID')Step 6 — Upload Files
Files are attached to records. Add a file field to your collection in the dashboard first.
const formData = new FormData()
formData.append('title', 'My photo')
formData.append('image', fileInput.files[0])
const record = await db.collection('posts').create(formData)Get the file URL
const url = db.storage.getFileUrl(record, 'photo.jpg')
// With thumbnail transform
const thumbUrl = db.storage.getFileUrl(record, 'photo.jpg', {
thumb: '100x100',
})Step 7 — Listen for Live Updates
Realtime subscriptions let your app update instantly when data changes.
// Watch for any changes
const unsubscribe = await db.collection('messages').subscribe((event) => {
console.log(event.action) // 'create', 'update', or 'delete'
console.log(event.record) // the data that changed
})
// Stop listening
await unsubscribe()Full Working Example
A complete React app with auth and data — ready to copy.
import { TacoProvider, useAuth, useCollection, AuthForm } from '@tacobase/react'
const URL = import.meta.env.VITE_TACOBASE_URL
const KEY = import.meta.env.VITE_TACOBASE_API_KEY
export default function App() {
return (
<TacoProvider url={URL} apiKey={KEY}>
<Main />
</TacoProvider>
)
}
function Main() {
const { user, loading, signOut } = useAuth()
if (loading) return <p>Loading...</p>
if (!user) {
return (
<div style={{ maxWidth: 400, margin: '100px auto' }}>
<AuthForm
providers={['google']}
onSuccess={() => window.location.reload()}
/>
</div>
)
}
return (
<div style={{ maxWidth: 600, margin: '40px auto' }}>
<h1>Welcome, {user.email}</h1>
<button onClick={signOut}>Sign Out</button>
<hr />
<PostsList />
</div>
)
}
function PostsList() {
const { items, loading, error } = useCollection('posts', {
sort: '-created',
filter: 'published = true',
})
if (loading) return <p>Loading posts...</p>
if (items.length === 0) return <p>No posts yet.</p>
return (
<ul>
{items.map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.content}</p>
</li>
))}
</ul>
)
}Quick Reference
import { createClient } from '@tacobase/client'
const db = createClient(url, apiKey)
// Auth
await db.auth.signUp({ email, password })
await db.auth.signIn({ email, password })
await db.auth.signInWithOAuth({ provider: 'google' })
await db.auth.requestPasswordReset(email)
db.auth.signOut()
db.auth.user // current user or null
db.auth.isValid // true if logged in
db.auth.onStateChange((event, record) => { ... })
// Database
await db.collection('x').getList(page, perPage, { filter, sort, expand })
await db.collection('x').getOne(id)
await db.collection('x').getFirstListItem(filter)
await db.collection('x').getFullList({ filter, sort })
await db.collection('x').create(data)
await db.collection('x').update(id, data)
await db.collection('x').delete(id)
// Realtime
const unsub = await db.collection('x').subscribe(callback)
await unsub()
// Storage
db.storage.getFileUrl(record, filename)
db.storage.getFileUrl(record, filename, { thumb: '100x100' })Common Mistakes
"useTaco* hooks must be used within a TacoProvider"
Make sure <TacoProvider> wraps your entire app or at least the part that uses the hooks.
"Instance unavailable after 3 retries"
Your Tacobase instance might be stopped. Check the dashboard. The SDK retries automatically, but if it wakes up too slowly, you might see this error.
Forgetting "await"
Most SDK calls are asynchronous. If you forget await, you get a Promise instead of data.
Wrong environment variable names
Use TACOBASE_URL and TACOBASE_API_KEY (with framework prefixes like NEXT_PUBLIC_ or VITE_ for client-side code).
❌ TACOBASE_SECRET, TACOBASE_KEY, tacobase_url
✅ TACOBASE_URL, TACOBASE_API_KEY
Using platform URL instead of instance URL
The URL should point to your instance, not the platform dashboard.
❌ https://tacobase.dev
✅ https://myapp.tacobase.dev
Model Context Protocol (MCP) Server
Tacobase provides an official Model Context Protocol (MCP) server. This allows AI assistants like Cursor and Claude to directly manage your Tacobase schema and collections via natural language.
Using with Cursor
- Open Cursor Settings (
Cmd/Ctrl + ,) - Go to Features → MCP (Model Context Protocol)
- Click + Add new MCP server
- Configure it as follows:
- Type:
command - Name:
tacobase-mcp - Command:
npx - Args:
-y @tacobase/mcp-server
- Type:
- Add the following environment variables:
TACOBASE_URL: e.g.https://your-instance.tacobase.devTACOBASE_ADMIN_API_KEY: Your Admin API Key
💡 Tip: Once connected, you can ask Cursor: "Create a tasks collection with a title and a boolean completed field" and it will execute the schema modifications for you!
Using with Claude Desktop
Add the following to your claude_desktop_config.json (located via Claude Desktop settings → Developer → Edit Config):
{
"mcpServers": {
"Tacobase": {
"command": "npx",
"args": ["-y", "@tacobase/mcp-server"],
"env": {
"TACOBASE_URL": "https://your-instance.tacobase.dev",
"TACOBASE_ADMIN_API_KEY": "tbk_xyz98765_xxxxxxxxxxxxxxxx"
}
}
}
}Restart Claude Desktop to apply the configuration.
Next Steps
- Create collections in the dashboard to define your data structure
- Set up collection rules to control who can read/write data
- Enable OAuth providers in your instance's auth settings
- Real the full API reference in the @tacobase/client README