npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tacobase/client

v1.0.4

Published

tacobase client SDK — auth, database, storage, and realtime for your apps

Readme


Auth, database, realtime, and file storage — all wrapped in one tight TypeScript SDK.

npm install @tacobase/client

Table of Contents


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_here

Authentication

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 upfront

Error 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