@nexabase/sdk

Official JavaScript/TypeScript SDK for NexaBase - Build apps faster with auto-generated APIs
12,567
Install
npm install @nexabase/sdk
Latest Version:2.22.0
License:MIT
Last Updated:Aug 26, 2026
Links: npm
Maintainer: fmirpe

@nexabase/sdk

Official JavaScript/TypeScript SDK for NexaBase - Build apps faster with auto-generated APIs

npm version npm downloads License: MIT TypeScript Node.js


📖 Quick Links


✨ What is NexaBase?

NexaBase is a powerful Backend as a Service (BaaS) platform that automatically generates REST APIs from your data schemas. Think of it as Supabase + Firebase with auto-generated endpoints.

The @nexabase/sdk is the official JavaScript/TypeScript client that makes it easy to interact with your NexaBase backend from any JavaScript environment.

Key Benefits

  • 🚀 Zero Backend Code - Define your schema, get instant REST APIs
  • 🔌 Type-Safe - Full TypeScript support with IntelliSense
  • ⚡ Real-time Ready - WebSocket subscriptions out of the box
  • 🔐 Secure by Default - JWT, API keys, OAuth support
  • 📦 All-in-One - Auth, Storage, Functions, Webhooks included

📦 Installation

npm

npm install @nexabase/sdk

yarn

yarn add @nexabase/sdk

pnpm

pnpm add @nexabase/sdk

CDN (for browsers)

<script src="https://cdn.jsdelivr.net/npm/@nexabase/sdk@latest/dist/index.min.js"></script>

🚀 Quick Start

1️⃣ Initialize the Client

import { createApiClient } from '@nexabase/sdk';

const nexabase = createApiClient(
  'https://your-tenant.nexabase.app',
  'your-api-key'  // Get from NexaBase dashboard
);

2️⃣ Authenticate (Optional)

// Sign in with email/password (API Key required)
const { access_token, user } = await nexabase.signInApi(
  'user@example.com',
  'your-password'
);

console.log(`Welcome, ${user.name}!`);

3️⃣ Start Using APIs

// List all collections
const collections = await nexabase.listCollections();
console.log('Collections:', collections);

// Query documents with filters
const users = await nexabase.listDocuments('users', {
  filter: { status: 'active' },
  sort: '-created_at',
  page: 1,
  per_page: 20,
});

// Create a document
const newUser = await nexabase.createDocument('users', {
  name: 'John Doe',
  email: 'john@example.com',
  role: 'user',
});

// Update a document
await nexabase.updateDocument('users', newUser.id, {
  last_login: new Date().toISOString(),
});

// Delete a document
await nexabase.deleteDocument('users', userId);

// Complex Query with Logical Groups (NEW)
const { data } = await nexabase
  .from('products')
  .where('status', 'active')
  .whereGroup(q => {
    q.where('price', '>', 100).where('category', 'electronics')
  }, 'OR')
  .get();

// Create document with file upload (NEW)
const file = document.querySelector('input[type="file"]').files[0];
await nexabase.createDocumentWithFile('products', { name: 'New Item' }, file, 'image');


🎯 Core Features

🔐 Authentication

Multiple authentication methods supported:

import { 
  createApiClient,      // API Key auth
  createTokenClient,    // Bearer token auth
  createAuthenticatedApiClient  // Auto login
} from '@nexabase/sdk';

// API Key (server-to-server)
const client = createApiClient(
  'https://api.nexabase.app',
  'your-api-key'
);

// Bearer Token (user-authenticated)
const client = createTokenClient(
  'https://api.nexabase.app',
  'jwt-token-here'
);

// Auto login (API Key + user credentials)
const client = await createAuthenticatedApiClient(
  'https://api.nexabase.app',
  'api-key',
  'user@example.com',
  'password'
);

// Subdomain client
const client = createSubdomainClient(
  'mytenant',      // Your tenant subdomain
  'api-key'
);
// Connects to: https://mytenant.nexabase.app

📚 Collections & Documents

Full CRUD operations with advanced querying:

// Create collection
await nexabase.createCollection({
  name: 'products',
  schema: {
    fields: {
      name: { type: 'string', required: true, maxLength: 255 },
      price: { type: 'number', required: true, min: 0 },
      description: { type: 'text' },
      in_stock: { type: 'boolean', default: true },
    },
    timestamps: true,
  },
});

// List collections
const collections = await nexabase.listCollections();

// Get collection by name
const collection = await nexabase.getCollection('products');

// Update collection
await nexabase.updateCollection('products', {
  description: 'Product catalog',
  is_active: true,
});

// Delete collection
await nexabase.deleteCollection('products');
Document Operations
// Create document
const product = await nexabase.createDocument('products', {
  name: 'iPhone 15',
  price: 999.99,
  in_stock: true,
});

// Get document
const doc = await nexabase.getDocument('products', productId);

// Update document
await nexabase.updateDocument('products', productId, {
  price: 899.99,
});

// Delete document
await nexabase.deleteDocument('products', productId);

🔍 Fluent Query Builder

Advanced querying with chainable syntax:

import { NexaQuery } from '@nexabase/sdk';

// Basic query
const { data } = await nexabase
  .from('products')
  .select('id,name,price')
  .where('price', '>', 50)
  .where('in_stock', true)
  .sort('-created_at')
  .limit(10)
  .get();

// Advanced filters
const { data } = await nexabase
  .from('products')
  .where('category', 'in', ['electronics', 'books'])
  .where('price', 'between', [100, 500])
  .where('name', 'like', '%iphone%')
  .logical('OR')
  .get();

// Complex Logical Groups (v2.17.0+)
// Generates: (status = 'active') AND (price > 100 OR stock < 10)
const { data: complex } = await nexabase
  .from('products')
  .where('status', 'active')
  .whereGroup(q => {
    q.where('price', '>', 100).where('stock', '<', 10)
  }, 'OR')
  .get();


// Aggregations
const { data } = await nexabase
  .from('orders')
  .groupBy('status')
  .count('*', 'total')
  .sum('amount', 'total_amount')
  .avg('amount', 'avg_amount')
  .get();

// Date grouping
const { data } = await nexabase
  .from('orders')
  .groupBy('year(created_at)', 'month(created_at)')
  .count('*', 'total')
  .get();

// Search
const { data } = await nexabase
  .from('products')
  .search('iphone')
  .get();

// First result
const first = await nexabase
  .from('users')
  .where('email', 'test@example.com')
  .first();

// Date extractions and groups (NEW)
const { data: stats } = await nexabase
  .from('orders')
  .month('created_at', 'mes')
  .year('created_at', 'anio')
  .count('*', 'total')
  .groupBy(['mes', 'anio'])
  .get();

🚀 Fluent Query Builder (v2.17.0+) - INSERT, UPDATE, DELETE

The new Query Builder allows write operations with a fluent API:

import { NexaQueryBuilder } from '@nexabase/sdk';

// ========== INSERT ==========

// Simple insert
const user = await nexabase
  .query('users')
  .set({ name: 'John', email: 'john@example.com' })
  .insertGetId();

// Direct insert
const product = await nexabase
  .query('products')
  .insertGetId({ name: 'iPhone', price: 999 });

// Bulk insert
const users = await nexabase
  .query('users')
  .insertBulk([
    { name: 'User 1', email: 'user1@example.com' },
    { name: 'User 2', email: 'user2@example.com' },
  ]);

// ========== UPDATE ==========

// Update with condition (updates all matching)
const modified = await nexabase
  .query('products')
  .where('category', 'electronics')
  .update({ price: 899, active: true })
  .updateGetModified();

// Update first matching
const updated = await nexabase
  .query('products')
  .where('name', 'like', '%iphone%')
  .update({ stock: 0 })
  .updateFirst();

// Update with idempotency
await nexabase
  .query('orders')
  .where('id', orderId)
  .withIdempotency('update-order-123')
  .update({ status: 'completed' })
  .updateFirst();

// ========== DELETE ==========

// Delete with condition
const deletedCount = await nexabase
  .query('temp_data')
  .where('created_at', '<', thirtyDaysAgo)
  .deleteGetCount();

// Delete first matching
const deleted = await nexabase
  .query('users')
  .where('email', 'temp@example.com')
  .deleteFirst();

// Delete by ID directly
await nexabase
  .query('users')
  .deleteById(userId);

// ========== SELECT shortcuts ==========

// Find by ID
const user = await nexabase.query('users').find(userId);

// Check existence
const exists = await nexabase.query('users').where('email', email).exists();

// Count records
const count = await nexabase.query('products').where('active', true).count();

// Select with filters
const { data } = await nexabase.query('users').select('id', 'name', 'email');

// ========== Combine with existing Query ==========

// Convert to NexaQuery for get/first
const results = await nexabase
  .query('products')
  .where('price', '>', 100)
  .toQuery() // Converts to NexaQuery
  .limit(20)
  .get();
Query Builder Methods
Method Description
set(data) Set data for insert/update
insert(data) Alias of set for insert
insertGetId(data?) Insert and return the document
insertBulk(docs[]) Insert multiple documents
update(data) Alias of set for update
updateGetModified() Update all matching, return count
updateFirst() Update only the first one
deleteGetCount() Delete all matching, return count
deleteFirst() Delete only the first one
deleteById(id) Delete by ID directly
find(id) Find document by ID
count() Count matching documents
exists() Check if any document exists
select(...fields) Select specific fields
withIdempotency(key) Add idempotency key
toQuery() Convert to NexaQuery for chaining
Query Methods
Method Description Example
select() Select fields .select('id,name,email')
fields() Alias for select .fields('id,name')
where() Add filter .where('status', 'active')
where() Operator filter .where('price', '>', 100)
whereGroup() Nested group .whereGroup(q => q.where(...), 'OR')
logical() AND/OR logic .logical('OR')

| sort() | Sort results | .sort('-created_at') | | limit() | Limit results | .limit(20) | | page() | Pagination | .page(2) | | include() | Include metadata | .include('schema') | | groupBy() | Group by field | .groupBy('status') | | count() | Count records | .count('*', 'total') | | sum() | Sum values | .sum('amount', 'total') | | avg() | Average | .avg('price', 'avg_price') | | min() | Minimum value | .min('price') | | max() | Maximum value | .max('price') | | month() | Extract month | .month('created_at') | | year() | Extract year | .year('created_at') | | day() | Extract day | .day('created_at') | | search() | Text search | .search('keyword') | | get() | Execute query | .get() | | first() | Get first result | .first() |


👥 User Management

Complete user CRUD operations:

import { NexaUsers } from '@nexabase/sdk';

// List users
const users = await nexabase.users.list({
  page: 1,
  limit: 20,
  search: 'john', // Search by name/email
});

// Get user
const user = await nexabase.users.get(userId);

// Create user
const newUser = await nexabase.users.create({
  email: 'newuser@example.com',
  password: 'SecurePassword123!',
  first_name: 'New',
  last_name: 'User',
  role: 'user', // 'user' | 'admin' | 'superadmin'
  status: 'active',
});

// Update user
await nexabase.users.update(userId, {
  first_name: 'Updated',
  role: 'admin',
  is_active: true,
});

// Resend invite
await nexabase.users.resendInvite(userId);

// Delete user
await nexabase.users.delete(userId);

☁️ Cloud Functions

Invoke serverless functions:

import { NexaFunctions } from '@nexabase/sdk';

// Invoke function (POST)
const result = await nexabase.functions.invoke('calculate-totals', {
  cartId: 'cart_123',
});

// Invoke with options
const result = await nexabase.functions.invoke('send-email', {
  to: 'user@example.com',
  subject: 'Welcome!',
  body: 'Hello!',
}, {
  method: 'POST',
  timeout: 10000,
  headers: {
    'X-Custom-Header': 'value',
  },
});

// Invoke with GET
const result = await nexabase.functions.invoke('get-stats', {}, {
  method: 'GET',
});

// List functions
const functions = await nexabase.functions.list();

📁 Storage

File upload and management:

import { NexaStorage } from '@nexabase/sdk';

// Upload a file
const file = await nexabase.storage.upload(
  'avatars',           // Bucket name
  fileBlob,            // File object/Blob
  'user-avatar.png'    // Optional path
);

// Download a file
const blob = await nexabase.storage.download(fileId);

// Get signed URL (temporary access)
const url = await nexabase.storage.getSignedUrl(fileId, {
  expiresIn: 3600, // 1 hour
});

// List files in bucket
const files = await nexabase.storage.listFiles('avatars', {
  prefix: 'users/',
});

// Delete a file
await nexabase.storage.delete(fileId);

🪝 Webhooks

Create and manage webhooks:

import { NexaWebhooks } from '@nexabase/sdk';

// List webhooks
const webhooks = await nexabase.webhooks.list();

// Create webhook
const webhook = await nexabase.webhooks.create({
  name: 'Order Created',
  url: 'https://your-api.com/webhooks/orders',
  events: ['document:created'],
  is_active: true,
});

// Get webhook
const webhook = await nexabase.webhooks.get(webhookId);

// Update webhook
await nexabase.webhooks.update(webhookId, {
  name: 'Updated Name',
  is_active: false,
});

// Delete webhook
await nexabase.webhooks.delete(webhookId);

🔄 Real-time Subscriptions

Listen to data changes in real-time:

import { NexaBaseRealtime } from '@nexabase/sdk';

const realtime = new NexaBaseRealtime({
  baseURL: 'https://your-tenant.nexabase.app',
  apiKey: 'your-api-key',
  token: 'jwt-token', // Optional
  reconnect: true,
  maxReconnectAttempts: 5,
  reconnectInterval: 5000,
  heartbeatInterval: 30000,
});

// Connect
await realtime.connect();

// Subscribe to collection events
const subscriptionId = realtime.subscribe(
  'products',
  (message) => {
    console.log('Product changed:', message);
  },
  {
    events: ['*'], // ['insert', 'update', 'delete'] or ['*']
  }
);

// Subscribe with filters
realtime.subscribe(
  'orders',
  (message) => {
    console.log('New admin order:', message);
  },
  {
    events: ['insert'],
    filters: { role: 'admin' },
  }
);

// Broadcast message
realtime.broadcast('products', 'product:updated', {
  productId: '123',
  action: 'restock',
});

// Unsubscribe
realtime.unsubscribe(subscriptionId);

// Disconnect
realtime.disconnect();

🎯 TypeScript Support

The SDK is built with TypeScript and provides full type definitions:

import {
  NexaBase,
  NexaBaseConfig,
  Document,
  Collection,
  StandardResponse,
  DocumentQueryOptions,
  User,
  CreateUser,
} from '@nexabase/sdk';

// Fully typed configuration
const config: NexaBaseConfig = {
  baseURL: 'https://api.nexabase.app',
  apiKey: 'your-key',
  timeout: 30000,
  debug: false,
};

// Type-safe queries
const options: DocumentQueryOptions = {
  filter: { status: 'active' },
  sort: '-created_at',
  page: 1,
  per_page: 20,
  fields: 'id,name,email',
};

// Typed response
const response: StandardResponse<Document[]> = await nexabase.listDocuments(
  'users',
  options
);

// Access typed data
response.data.forEach((doc: Document) => {
  console.log(doc.id, doc.created_at);
});

🏭 Factory Functions

Pre-configured clients for common scenarios:

import {
  createApiClient,
  createTokenClient,
  createAuthenticatedApiClient,
  createSubdomainClient,
  createDevelopmentClient,
  createTestClient,
} from '@nexabase/sdk';

// API Key client (recommended)
const client = createApiClient(
  'https://api.nexabase.app',
  'your-api-key'
);

// Bearer token client
const client = createTokenClient(
  'https://api.nexabase.app',
  'jwt-token'
);

// Auto-login client
const client = await createAuthenticatedApiClient(
  'https://api.nexabase.app',
  'api-key',
  'user@example.com',
  'password'
);

// Subdomain client
const client = createSubdomainClient(
  'mytenant',
  'api-key',
  'nexabase.app'
);

// Development client
const client = createDevelopmentClient(
  'http://localhost:3000',
  'dev-key',
  {
    debug: true,
    timeout: 30000,
  }
);

// Test client
const client = createTestClient(
  'http://localhost:3000',
  'test-key',
  {
    debug: true,
    mockMode: true,
  }
);

🚨 Error Handling

Comprehensive error handling:

try {
  const doc = await nexabase.getDocument('users', 'invalid-id');
} catch (error) {
  if (error.statusCode === 404) {
    console.error('Document not found');
  } else if (error.statusCode === 401) {
    console.error('Unauthorized - check your API key');
  } else if (error.statusCode === 429) {
    console.error('Rate limit exceeded');
  } else {
    console.error('Error:', error.message, error.details);
  }
}

⚙️ Configuration Options

Client Configuration

const client = new NexaBase({
  // Required
  baseURL: 'https://your-tenant.nexabase.app',
  apiKey: 'your-api-key',
  
  // Optional
  token: 'jwt-token',              // Bearer token
  timeout: 30000,                   // Request timeout (ms)
  debug: false,                     // Enable debug logging
  customHeaders: {                  // Custom headers
    'X-Custom-Header': 'value',
  },
});

Realtime Configuration

const realtime = new NexaBaseRealtime({
  baseURL: 'https://your-tenant.nexabase.app',
  apiKey: 'your-api-key',
  token: 'jwt-token',
  reconnect: true,
  maxReconnectAttempts: 5,
  reconnectInterval: 5000,
  heartbeatInterval: 30000,
});

🌍 Browser Support

Browser Version Support
Chrome Last 2 versions ✅
Firefox Last 2 versions ✅
Safari Last 2 versions ✅
Edge Last 2 versions ✅
Node.js >= 18.0.0 ✅

📚 Complete Documentation

This README provides a quick overview. For complete documentation:

Guides

API Reference


🤝 Contributing

We welcome contributions! Here's how you can help:

Ways to Contribute

  • 🐛 Report bugs
  • 💡 Suggest features
  • 📝 Improve documentation
  • 🔧 Submit pull requests
  • 💬 Help others in discussions

Development Setup

# Fork and clone
git clone https://github.com/fmirpe/nexabase-sdk.git
cd nexabase-sdk/javascript

# Install dependencies
npm install

# Start development
npm run dev

# Run tests
npm test

# Build
npm run build

See CONTRIBUTING.md for detailed guidelines.


📄 License

MIT License - see LICENSE file for details.


📞 Support


NexaBase SDK - Build Apps Faster
Backend as a Service Platform

Made with ❤️ by Fabrica de Algoritmos

Related Packages

@ackplus/nest-crud-request

Framework-agnostic query builder for REST APIs - build complex queries with filt...

15,220 2
cr-numeral

cr-numeral is a lightweight and versatile npm package designed to effortlessly c...

8,248 3
paymid-sdk

A frontend SDK for Paymid payment processing

15,682
@propeller-commerce/propeller-sdk-v2

TypeScript GraphQL client for Propeller eCommerce V2 Platform - works with React...

8,078 1

Version History

Version Released License
2.22.0 MIT
2.21.0 MIT
2.20.0 MIT
2.19.1 MIT
2.19.0 MIT