Skip to content

Node.js Quick Start

Varity Team Core Contributors Updated March 2026 v2.0.0 (stable)

Build and deploy backend applications with Varity’s database, authentication, and hosting. This guide gets you started in under 5 minutes.

  • Node.js 18 or later
  • npm or yarn
  • TypeScript knowledge (recommended)

Install the Varity SDK and types:

Terminal window
npm install @varity-labs/sdk @varity-labs/types

For TypeScript projects, install type definitions:

Terminal window
npm install --save-dev @types/node typescript

The fastest way to get started is with Varity’s built-in database. No configuration required.

src/index.ts
import { db } from '@varity-labs/sdk';
// The db instance is ready to use immediately
// No connection strings, no setup required
src/types.ts
export interface User {
id?: string;
name: string;
email: string;
role: 'admin' | 'user';
createdAt: string;
}
export interface Post {
id?: string;
title: string;
content: string;
authorId: string;
published: boolean;
createdAt: string;
}
  1. Create (Add Documents)

    import { db } from '@varity-labs/sdk';
    import type { User } from './types';
    async function createUser(name: string, email: string) {
    const result = await db.collection<User>('users').add({
    name,
    email,
    role: 'user',
    createdAt: new Date().toISOString(),
    });
    console.log('Created user:', result);
    // Returns: { id: 'doc_abc123', success: true }
    }
    createUser('Alice Johnson', 'alice@example.com');
  2. Read (Get Documents)

    // Get all documents
    async function getAllUsers() {
    const users = await db.collection<User>('users').get();
    console.log('All users:', users);
    // Returns: [{ id: 'doc_123', name: 'Alice', email: '...', ... }, ...]
    }
    // Get a specific user by filtering
    async function getUserById(id: string) {
    const users = await db.collection<User>('users').get();
    const user = users.find((u) => u.id === id);
    console.log('User:', user);
    // Returns: { id: 'doc_123', name: 'Alice', email: '...', ... }
    }
    // Get with pagination
    async function getRecentUsers() {
    const users = await db.collection<User>('users').get({
    limit: 10,
    offset: 0,
    orderBy: '-createdAt', // Prefix with - for descending
    });
    return users;
    }
  3. Update Documents

    async function updateUser(id: string, updates: Partial<User>) {
    await db.collection<User>('users').update(id, updates);
    console.log('User updated successfully');
    }
    // Update specific fields
    updateUser('doc_abc123', {
    name: 'Alice Updated',
    role: 'admin',
    });
  4. Delete Documents

    async function deleteUser(id: string) {
    await db.collection<User>('users').delete(id);
    console.log('User deleted successfully');
    }
    deleteUser('doc_abc123');

Here’s a complete Express.js API with CRUD operations:

src/server.ts
import express from 'express';
import { db } from '@varity-labs/sdk';
import type { User } from './types';
const app = express();
app.use(express.json());
// Get all users
app.get('/api/users', async (req, res) => {
try {
const users = await db.collection<User>('users').get();
res.json({ success: true, data: users });
} catch (error) {
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Failed to fetch users',
});
}
});
// Get user by ID
app.get('/api/users/:id', async (req, res) => {
try {
const users = await db.collection<User>('users').get();
const user = users.find((u) => u.id === req.params.id);
if (!user) {
return res.status(404).json({ success: false, error: 'User not found' });
}
res.json({ success: true, data: user });
} catch (error) {
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Failed to fetch user',
});
}
});
// Create user
app.post('/api/users', async (req, res) => {
try {
const { name, email, role } = req.body;
// Validation
if (!name || !email) {
return res.status(400).json({
success: false,
error: 'Name and email are required',
});
}
const result = await db.collection<User>('users').add({
name,
email,
role: role || 'user',
createdAt: new Date().toISOString(),
});
res.status(201).json({ success: true, data: result });
} catch (error) {
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Failed to create user',
});
}
});
// Update user
app.patch('/api/users/:id', async (req, res) => {
try {
const updates = req.body;
await db.collection<User>('users').update(req.params.id, updates);
res.json({ success: true });
} catch (error) {
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Failed to update user',
});
}
});
// Delete user
app.delete('/api/users/:id', async (req, res) => {
try {
await db.collection<User>('users').delete(req.params.id);
res.json({ success: true });
} catch (error) {
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Failed to delete user',
});
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});

Run the server:

Terminal window
npx tsx src/server.ts

During development, Varity uses shared development credentials automatically. No configuration needed.

// Works immediately - no env vars required
import { db } from '@varity-labs/sdk';
const users = await db.collection('users').get();

For production deployments, configure these environment variables:

.env
VARITY_APP_ID=your-app-id
VARITY_APP_TOKEN=your-app-token
VARITY_DB_PROXY_URL=your-db-proxy-url

Always wrap database operations in try-catch blocks:

import { db } from '@varity-labs/sdk';
async function safeGetUser(id: string) {
try {
const users = await db.collection('users').get();
const user = users.find((u) => u.id === id);
return { success: true, data: user ?? null };
} catch (error) {
console.error('Database error:', error);
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
// Get all users, then filter
const allUsers = await db.collection<User>('users').get();
// Filter by role
const admins = allUsers.filter((user) => user.role === 'admin');
// Filter by email domain
const companyUsers = allUsers.filter((user) =>
user.email.endsWith('@company.com')
);
// Combine filters
const recentAdmins = allUsers
.filter((user) => user.role === 'admin')
.filter((user) => {
const created = new Date(user.createdAt);
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
return created > weekAgo;
});
import type { User } from './types';
// Explicit type ensures type safety
const users = await db.collection<User>('users').get();
// TypeScript knows user fields are typed as User
users.forEach((user) => {
console.log(user.name); // Type-safe
console.log(user.invalid); // TypeScript error
});
async function getUser(id: string): Promise<(User & { id: string }) | undefined> {
const users = await db.collection<User>('users').get();
return users.find((u) => u.id === id);
}
async function getAllUsers(): Promise<Array<User & { id: string }>> {
return await db.collection<User>('users').get();
}
// After adding a document
const result = await db.collection<User>('users').add(userData);
const userId = result.id; // string | undefined
// Use non-null assertion if you know add() succeeded
await db.collection<User>('users').update(result.id!, updates);
// Or check explicitly
if (result.id) {
await db.collection<User>('users').update(result.id, updates);
}

Create reusable collection accessors:

src/lib/database.ts
import { db } from '@varity-labs/sdk';
import type { User, Post } from './types';
export const users = () => db.collection<User>('users');
export const posts = () => db.collection<Post>('posts');

Use in your app:

import { users, posts } from './lib/database';
// Clean, reusable syntax
const allUsers = await users().get();
const allPosts = await posts().get();
await users().add({ name: 'Bob', email: 'bob@example.com', role: 'user', createdAt: new Date().toISOString() });
async function paginate<T>(
collection: string,
page: number,
pageSize: number = 20
) {
const offset = (page - 1) * pageSize;
const items = await db.collection<T>(collection).get({
limit: pageSize,
offset,
});
return {
items,
page,
pageSize,
hasMore: items.length === pageSize,
};
}
// Usage
const result = await paginate<User>('users', 1, 10);
console.log(`Page ${result.page}:`, result.items);
async function batchCreate(users: Array<Omit<User, 'id'>>) {
const promises = users.map((user) =>
db.collection<User>('users').add(user)
);
const results = await Promise.all(promises);
return results;
}
// Create 3 users in parallel
await batchCreate([
{ name: 'Alice', email: 'alice@example.com', role: 'user', createdAt: new Date().toISOString() },
{ name: 'Bob', email: 'bob@example.com', role: 'admin', createdAt: new Date().toISOString() },
{ name: 'Carol', email: 'carol@example.com', role: 'user', createdAt: new Date().toISOString() },
]);

Once your Node.js app is ready, deploy it with one command:

  1. Install the CLI

    Terminal window
    pip install varitykit
  2. Deploy your app

    Terminal window
    varitykit app deploy
  3. Your app is live

    Varity automatically:

    • Builds your app
    • Generates production credentials
    • Deploys to global infrastructure
    • Provides a live URL

Now that you have a working Node.js backend:

For complete API documentation, see: