Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@butterbase/sdk

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@butterbase/sdk

Universal TypeScript SDK for Butterbase

latest
Source
npmnpm
Version
2.4.0
Version published
Weekly downloads
320
492.59%
Maintainers
2
Weekly downloads
 
Created
Source

@butterbase/sdk

Universal TypeScript SDK for Butterbase - works in browser, Node.js, and Deno environments.

Installation

npm install @butterbase/sdk

Quick Start

import { createClient } from '@butterbase/sdk';

// Initialize client.
// apiUrl is the same regardless of which region your app lives in —
// requests are routed to the right region automatically.
const butterbase = createClient({
  appId: 'app_abc123',
  apiUrl: 'https://api.butterbase.ai',
  anonKey: 'your-anon-key' // Optional, for public access
});

// Query data
const { data, error } = await butterbase
  .from('posts')
  .select('*')
  .eq('status', 'published')
  .order('created_at', { ascending: false })
  .limit(10);

// Insert data
const { data, error } = await butterbase
  .from('posts')
  .insert({ title: 'Hello World', content: 'My first post' });

// Update data
const { data, error } = await butterbase
  .from('posts')
  .update({ status: 'archived' })
  .eq('id', '123');

// Delete data
const { data, error } = await butterbase
  .from('posts')
  .delete()
  .eq('id', '123');

Migration from 0.x to 1.0

Breaking Change: The authUrl parameter has been removed. All auth endpoints now run on the same URL as the API.

Before (0.x):

const butterbase = createClient({
  appId: 'app_abc123',
  apiUrl: 'https://api.butterbase.ai',
  authUrl: 'https://auth.butterbase.com', // ❌ No longer needed
});

After (1.0):

const butterbase = createClient({
  appId: 'app_abc123',
  apiUrl: 'https://api.butterbase.ai', // ✅ All endpoints use this URL
});

Authentication

Sessions are automatically persisted to localStorage and restored on page refresh. Access tokens are automatically refreshed before they expire.

// Sign up
const { data, error } = await butterbase.auth.signUp({
  email: 'user@example.com',
  password: 'secure123'
});

// Sign in (session is automatically persisted)
const { data, error } = await butterbase.auth.signIn({
  email: 'user@example.com',
  password: 'secure123'
});

// Get current user (works after page refresh)
const { data: user } = await butterbase.auth.getUser();

// Sign out (clears persisted session)
await butterbase.auth.signOut();

// Refresh session manually (uses stored refresh token if none provided)
const { data } = await butterbase.auth.refreshSession();

// OAuth
const { url } = butterbase.auth.signInWithOAuth({
  provider: 'google',
  redirectTo: 'http://localhost:3000/callback'
});
window.location.href = url;

Auth State Changes

Subscribe to authentication events to react to sign-ins, sign-outs, and token refreshes:

const { unsubscribe } = butterbase.onAuthStateChange((event, session) => {
  // event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'SESSION_RESTORED'
  console.log(event, session?.user);
});

// Stop listening
unsubscribe();

React Usage

import { useEffect, useState } from 'react';
import { butterbase } from './lib';

function App() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // Session is auto-restored — check current state
    const session = butterbase.sessionManager.getSession();
    if (session) setUser(session.user);

    // React to future auth changes
    const { unsubscribe } = butterbase.onAuthStateChange((event, session) => {
      setUser(session?.user ?? null);
    });
    return unsubscribe;
  }, []);
}

Custom Storage

By default, the SDK uses localStorage with an in-memory fallback for SSR/Node.js environments. You can provide a custom storage adapter:

import { createClient, MemorySessionStorage } from '@butterbase/sdk';

// Memory-only (no persistence)
const butterbase = createClient({
  appId: 'app_abc123',
  apiUrl: 'https://api.butterbase.ai',
  persistSession: false,
});

// Custom storage adapter (e.g., for React Native)
const butterbase = createClient({
  appId: 'app_abc123',
  apiUrl: 'https://api.butterbase.ai',
  sessionStorage: myCustomStorage, // implements { getItem, setItem, removeItem }
});

Storage

// Upload file
const { data, error } = await butterbase.storage.upload(file);

// Get download URL
const { data } = await butterbase.storage.getDownloadUrl(objectId);

// List files
const { data: objects } = await butterbase.storage.list();

// Delete file
await butterbase.storage.delete(objectId);

Functions

// Invoke serverless function
const { data, error } = await butterbase.functions.invoke('my-function', {
  body: { key: 'value' },
  method: 'POST'
});

Query Builder

Operators

  • eq(column, value) - Equal to
  • neq(column, value) - Not equal to
  • gt(column, value) - Greater than
  • gte(column, value) - Greater than or equal to
  • lt(column, value) - Less than
  • lte(column, value) - Less than or equal to
  • like(column, pattern) - Pattern matching (case-sensitive)
  • ilike(column, pattern) - Pattern matching (case-insensitive)
  • in(column, values) - Value in array
  • is(column, value) - Is null/true/false

Modifiers

  • select(columns) - Select specific columns
  • order(column, options) - Order results
  • limit(count) - Limit results
  • offset(count) - Skip results

Usage in Deno

import { createClient } from 'npm:@butterbase/sdk';

const butterbase = createClient({
  appId: Deno.env.get('BUTTERBASE_APP_ID')!,
  apiUrl: Deno.env.get('BUTTERBASE_API_URL')!,
});

// Use in serverless functions
export async function handler(req: Request, ctx: any) {
  const { data } = await butterbase.from('posts').select('*');
  return Response.json({ data });
}

TypeScript Support

The SDK is fully typed with TypeScript. All methods return ButterbaseResponse<T> with proper type inference:

interface Post {
  id: string;
  title: string;
  content: string;
  status: 'draft' | 'published';
}

const { data, error } = await butterbase
  .from<Post>('posts')
  .select('*')
  .eq('status', 'published');

// data is typed as Post[] | null
// error is typed as Error | null

Integrations

Connect third-party services to your app and execute actions on behalf of your users.

Admin configuration (API key)

// Enable a toolkit
await bb.integrations.configure('gmail', { displayName: 'Gmail' });

// List enabled integrations
const { data } = await bb.integrations.getConfig();

// Disable a toolkit
await bb.integrations.disable('gmail');

// Search available toolkits
const { data } = await bb.integrations.listAvailable({ search: 'salesforce' });

End-user OAuth flow (user JWT)

// Generate connect URL — redirect the user to authUrl
const { data } = await bb.integrations.connect('gmail', {
  redirectUrl: 'https://yourapp.com/settings',
});
window.location.href = data.authUrl;

// List user's connected accounts
const { data } = await bb.integrations.listConnections();

// Disconnect an account
await bb.integrations.disconnect(connectionId);

Executing tools

// List tools for a toolkit
const { data } = await bb.integrations.getTools('gmail');
// data[0] = { name: 'GMAIL_SEND_EMAIL', description: '...', parameters: { ... } }

// Execute a tool (user JWT auth)
const { data } = await bb.integrations.execute('GMAIL_SEND_EMAIL', {
  to: 'user@example.com',
  subject: 'Hello',
  body: 'Sent via Butterbase integrations.',
});

// Execute on behalf of a user (API key + userId, e.g. in a cron)
const { data } = await bb.integrations
  .asUser('user-uuid')
  .execute('GOOGLECALENDAR_EVENTS_LIST', { timeMin: new Date().toISOString() });

Error handling

All client methods return { data, error }. When the backend returned a recognizable agent-friendly error, error is a typed ButterbaseError subclass (AuthError, ValidationError, NotFoundError, QuotaError, NetworkError) carrying code, status, remediation, and details.

import {
  ButterbaseClient, ErrorCodes,
  AuthError, NotFoundError, QuotaError,
} from '@butterbase/sdk';

const r = await client.from('posts').select('*').execute();

if (r.error instanceof NotFoundError) {
  console.error('Missing table:', r.error.remediation);
}
if (r.error?.code === ErrorCodes.AUTH_INVALID_API_KEY) {
  // rotate the key
}
if (r.error instanceof QuotaError) {
  console.error(`Quota hit (${r.error.code}): ${r.error.remediation}`);
}

The full set of codes lives in ErrorCodes (re-exported from @butterbase/shared). Use parseApiError(status, body) if you're wrapping fetch yourself and want to dispatch to the same typed classes.

License

MIT

Keywords

butterbase

FAQs

Package last updated on 01 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts