Skip to content

Getting Started with the SDK

The OstrichDB JavaScript/TypeScript SDK is the official client library for interacting with OstrichDB from Node.js applications, web browsers, and modern JavaScript frameworks. It provides both traditional method-based APIs and an intuitive builder pattern for managing hierarchical data structures.

The SDK is a comprehensive client library that provides:

  • Type-safe operations for TypeScript projects
  • Traditional API methods for familiar database operations
  • Builder pattern for intuitive, chainable operations
  • Comprehensive error handling with detailed error information
  • Framework integration examples for popular frameworks
  • Full hierarchy support for Projects → Collections → Clusters → Records
  • 🔧 Easy Installation: Simple npm/yarn/pnpm installation
  • 📝 TypeScript Support: Full TypeScript definitions included
  • 🔗 Chainable API: Intuitive builder pattern for complex operations
  • ⚡ Performance Optimized: Efficient HTTP client with connection reuse
  • 🛡️ Error Handling: Comprehensive error types and handling
  • 🚀 Framework Ready: Works with Express, Next.js, React, Vue, and more

Install the SDK using your preferred package manager:

npm:

Terminal window
npm install ostrichdb-js

Yarn:

Terminal window
yarn add ostrichdb-js

pnpm:

Terminal window
pnpm add ostrichdb-js

Create a test file to verify the installation:

test-installation.js
const OstrichDB = require('ostrichdb-js');
// or with ES6 imports
// import OstrichDB from 'ostrichdb-js';
console.log('OstrichDB SDK installed successfully!');
console.log('SDK version:', OstrichDB.version);

Run the test:

Terminal window
node test-installation.js
import OstrichDB from 'ostrichdb-js';
// Initialize the client
const db = new OstrichDB({
baseUrl: 'http://localhost:8042', // Your OstrichDB server URL
apiKey: 'your-jwt-token-here', // Your authentication token
timeout: 30000 // Request timeout (optional)
});

Let’s create a simple blog application structure:

async function createBlogStructure() {
try {
// Create a project for our blog
await db.create_project('my-blog');
console.log('✅ Project created');
// Create a collection for blog posts
await db.create_collection('my-blog', 'posts');
console.log('✅ Collection created');
// Create a cluster for published posts
await db.create_cluster('my-blog', 'posts', 'published');
console.log('✅ Cluster created');
// Add our first blog post
await db.create_record('my-blog', 'posts', 'published', 'post-1-title', 'STRING', 'Welcome to My Blog');
await db.create_record('my-blog', 'posts', 'published', 'post-1-content', 'STRING', 'This is my first blog post!');
await db.create_record('my-blog', 'posts', 'published', 'post-1-author', 'STRING', 'John Doe');
await db.create_record('my-blog', 'posts', 'published', 'post-1-date', 'DATE', '2024-01-15');
console.log('✅ First blog post created');
// Retrieve the blog post
const title = await db.get_record('my-blog', 'posts', 'published', 'post-1-title');
console.log('📖 Blog post title:', title.value);
} catch (error) {
console.error('❌ Error:', error.message);
}
}
createBlogStructure();

The same operations using the more intuitive builder pattern:

async function createBlogWithBuilder() {
try {
// Create the structure using builder pattern
const blog = db.project('my-blog');
await blog.create();
const posts = blog.collection('posts');
await posts.create();
const published = posts.cluster('published');
await published.create();
// Add blog post data
await published.record('post-1-title', 'STRING', 'Welcome to My Blog').create('post-1-title', 'STRING', 'Welcome to My Blog');
await published.record('post-1-content', 'STRING', 'This is my first blog post!').create('post-1-content', 'STRING', 'This is my first blog post!');
await published.record('post-1-author', 'STRING', 'John Doe').create('post-1-author', 'STRING', 'John Doe');
await published.record('post-1-date', 'DATE', '2024-01-15').create('post-1-date', 'DATE', '2024-01-15');
console.log('✅ Blog structure created with builder pattern');
// Query for posts
const allPosts = await published.listRecords();
console.log('📚 All posts:', allPosts.length);
} catch (error) {
console.error('❌ Error:', error.message);
}
}
createBlogWithBuilder();

Understanding OstrichDB’s Data Hierarchy

Section titled “Understanding OstrichDB’s Data Hierarchy”

OstrichDB organizes data in a four-level hierarchy:

Project (Top-level application container)
└── Collection (Database/domain grouping)
└── Cluster (Table/category equivalent)
└── Record (Individual data item)

Think of organizing an e-commerce application:

const ecommerce = db.project('ecommerce-store');
// Product catalog
const products = ecommerce.collection('products');
const electronics = products.cluster('electronics');
const clothing = products.cluster('clothing');
// Customer data
const customers = ecommerce.collection('customers');
const activeCustomers = customers.cluster('active');
const archivedCustomers = customers.cluster('archived');
// Order management
const orders = ecommerce.collection('orders');
const pendingOrders = orders.cluster('pending');
const completedOrders = orders.cluster('completed');

OstrichDB supports strongly-typed records with explicit type declaration:

Primitive Types:

  • CHAR - Single character
  • STRING - Text data
  • INTEGER - Whole numbers
  • FLOAT - Decimal numbers
  • BOOLEAN - true/false values
  • NULL - No value

Date/Time Types:

  • DATE - Calendar dates (YYYY-MM-DD)
  • TIME - Time of day (HH:MM:SS)
  • DATETIME - Combined date and time (ISO 8601)

Special Types:

  • UUID - Unique identifiers

Array Types: All primitive types can be arrays: []STRING, []INTEGER, []FLOAT, etc.

// Creating records with different types
await cluster.record('username', 'STRING', 'john_doe').create('username', 'STRING', 'john_doe');
await cluster.record('age', 'INTEGER', '25').create('age', 'INTEGER', '25');
await cluster.record('salary', 'FLOAT', '75000.50').create('salary', 'FLOAT', '75000.50');
await cluster.record('active', 'BOOLEAN', 'true').create('active', 'BOOLEAN', 'true');
await cluster.record('signup_date', 'DATE', '2024-01-15').create('signup_date', 'DATE', '2024-01-15');
await cluster.record('tags', '[]STRING', '["admin", "user", "premium"]').create('tags', '[]STRING', '["admin", "user", "premium"]');
import OstrichDB from 'ostrichdb-js';
class BlogManager {
private db: OstrichDB;
constructor(apiKey: string) {
this.db = new OstrichDB({
baseUrl: 'http://localhost:8042',
apiKey: apiKey
});
}
async setupBlog() {
// Create project structure
const blog = this.db.project('blog-app');
await blog.create();
const posts = blog.collection('posts');
await posts.create();
const published = posts.cluster('published');
await published.create();
return { blog, posts, published };
}
async createPost(title: string, content: string, author: string) {
const { published } = await this.setupBlog();
const postId = `post-${Date.now()}`;
// Create post records
await published.record(`${postId}-title`, 'STRING', title).create(`${postId}-title`, 'STRING', title);
await published.record(`${postId}-content`, 'STRING', content).create(`${postId}-content`, 'STRING', content);
await published.record(`${postId}-author`, 'STRING', author).create(`${postId}-author`, 'STRING', author);
await published.record(`${postId}-created`, 'DATETIME', new Date().toISOString()).create(`${postId}-created`, 'DATETIME', new Date().toISOString());
return postId;
}
async getPost(postId: string) {
const published = this.db.project('blog-app').collection('posts').cluster('published');
try {
const title = await published.record(`${postId}-title`).get(`${postId}-title`);
const content = await published.record(`${postId}-content`).get(`${postId}-content`);
const author = await published.record(`${postId}-author`).get(`${postId}-author`);
const created = await published.record(`${postId}-created`).get(`${postId}-created`);
return {
id: postId,
title: title.value,
content: content.value,
author: author.value,
created: created.value
};
} catch (error) {
throw new Error(`Post ${postId} not found`);
}
}
async listPosts() {
const published = this.db.project('blog-app').collection('posts').cluster('published');
const records = await published.listRecords();
// Group records by post ID
const posts = new Map();
records.forEach(record => {
const parts = record.name.split('-');
const postId = parts.slice(0, -1).join('-');
const field = parts[parts.length - 1];
if (!posts.has(postId)) {
posts.set(postId, { id: postId });
}
posts.get(postId)[field] = record.value;
});
return Array.from(posts.values());
}
async deletePost(postId: string) {
const published = this.db.project('blog-app').collection('posts').cluster('published');
// Delete all records for this post
await published.record(`${postId}-title`).delete(`${postId}-title`);
await published.record(`${postId}-content`).delete(`${postId}-content`);
await published.record(`${postId}-author`).delete(`${postId}-author`);
await published.record(`${postId}-created`).delete(`${postId}-created`);
}
}
// Usage example
async function example() {
const blogManager = new BlogManager('your-jwt-token');
// Create a new post
const postId = await blogManager.createPost(
'Getting Started with OstrichDB',
'OstrichDB is a modern hierarchical database...',
'Jane Developer'
);
console.log('Created post:', postId);
// Retrieve the post
const post = await blogManager.getPost(postId);
console.log('Retrieved post:', post);
// List all posts
const allPosts = await blogManager.listPosts();
console.log('All posts:', allPosts);
}

For security and configuration management, use environment variables:

Terminal window
# .env file
OSTRICHDB_URL=http://localhost:8042
OSTRICHDB_API_KEY=your-jwt-token-here
OSTRICHDB_TIMEOUT=30000
// Load environment variables
import OstrichDB from 'ostrichdb-js';
const db = new OstrichDB({
baseUrl: process.env.OSTRICHDB_URL || 'http://localhost:8042',
apiKey: process.env.OSTRICHDB_API_KEY,
timeout: parseInt(process.env.OSTRICHDB_TIMEOUT || '30000')
});

For TypeScript projects, ensure your tsconfig.json includes:

{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}

Now that you have the SDK installed and understand the basics:

  1. Learn Configuration - Detailed configuration options and authentication
  2. Explore the API Reference - Complete method documentation
  3. Master the Builder Pattern - Intuitive, chainable operations
  4. Framework Integration - Examples with Express, Next.js, and more
  5. Error Handling - Comprehensive error management

If you encounter issues:

The OstrichDB SDK makes it easy to build applications with hierarchical data structures while maintaining type safety and providing excellent developer experience.