Node.js / Backend Quick Start
Build a REST API with Express and Varity’s zero-config database. No database setup, no connection strings, no ORM configuration.
Prerequisites
Section titled “Prerequisites”- Node.js 18 or later
- npm or pnpm
- Python 3.8+ (for the CLI, needed at deploy time)
Set Up Your Project
Section titled “Set Up Your Project”-
Create a new project
Terminal window mkdir my-api && cd my-apinpm init -y -
Install dependencies
Terminal window npm install @varity-labs/sdk expressTerminal window pnpm add @varity-labs/sdk express -
Install the CLI (for deployment)
Terminal window pip install varitykit
Build Your API
Section titled “Build Your API”1. Define your data
Section titled “1. Define your data”Create a file to set up your database collections:
const { db } = require('@varity-labs/sdk');
// Create collection helpers// Each collection is like a database tableconst products = () => db.collection('products');const orders = () => db.collection('orders');
module.exports = { products, orders };2. Create the Express server
Section titled “2. Create the Express server”const express = require('express');const { products, orders } = require('./database');
const app = express();app.use(express.json());
// ===== PRODUCTS =====
// Create a productapp.post('/api/products', async (req, res) => { try { const product = await products().add({ name: req.body.name, price: req.body.price, stock: req.body.stock || 0, createdAt: new Date().toISOString(), }); res.status(201).json(product); } catch (err) { res.status(500).json({ error: err.message }); }});
// List all productsapp.get('/api/products', async (req, res) => { try { const limit = parseInt(req.query.limit) || 50; const offset = parseInt(req.query.offset) || 0; const allProducts = await products().get({ limit, offset }); res.json(allProducts); } catch (err) { res.status(500).json({ error: err.message }); }});
// Update a productapp.put('/api/products/:id', async (req, res) => { try { const updated = await products().update(req.params.id, req.body); res.json(updated); } catch (err) { res.status(500).json({ error: err.message }); }});
// Delete a productapp.delete('/api/products/:id', async (req, res) => { try { await products().delete(req.params.id); res.json({ deleted: true }); } catch (err) { res.status(500).json({ error: err.message }); }});
// ===== ORDERS =====
// Create an orderapp.post('/api/orders', async (req, res) => { try { const order = await orders().add({ productId: req.body.productId, quantity: req.body.quantity, status: 'pending', createdAt: new Date().toISOString(), }); res.status(201).json(order); } catch (err) { res.status(500).json({ error: err.message }); }});
// List ordersapp.get('/api/orders', async (req, res) => { try { const allOrders = await orders().get({ limit: parseInt(req.query.limit) || 50, orderBy: '-createdAt', }); res.json(allOrders); } catch (err) { res.status(500).json({ error: err.message }); }});
// Start the serverconst PORT = process.env.PORT || 3000;app.listen(PORT, () => { console.log(`API running at http://localhost:${PORT}`);});3. Run your server
Section titled “3. Run your server”node server.jsYou should see:
[Varity Database] Using shared development database. Data is stored in an isolated dev schema.Deploy with `varitykit app deploy` to get your own private database.API running at http://localhost:30004. Test with curl
Section titled “4. Test with curl”# Create a productcurl -X POST http://localhost:3000/api/products \ -H "Content-Type: application/json" \ -d '{"name": "Widget", "price": 29.99, "stock": 100}'
# List productscurl http://localhost:3000/api/products
# Update a product (replace PRODUCT_ID with the id from the create response)curl -X PUT http://localhost:3000/api/products/PRODUCT_ID \ -H "Content-Type: application/json" \ -d '{"price": 24.99}'
# Delete a productcurl -X DELETE http://localhost:3000/api/products/PRODUCT_IDDatabase API Reference
Section titled “Database API Reference”The Varity database provides four operations on every collection:
| Method | Description | Returns |
|---|---|---|
collection.add(data) | Insert a new document | The inserted document with id, created_at |
collection.get(options?) | Query documents | Array of documents |
collection.update(id, data) | Update a document by ID | The updated document |
collection.delete(id) | Delete a document by ID | true on success |
Query options
Section titled “Query options”The get() method accepts an options object:
const results = await products().get({ limit: 10, // Max documents to return offset: 20, // Skip N documents (for pagination) orderBy: '-price', // Sort field ("-" prefix for descending)});TypeScript support
Section titled “TypeScript support”If you use TypeScript, collections are fully typed:
import { db } from '@varity-labs/sdk';
interface Product { name: string; price: number; stock: number; createdAt: string;}
const products = () => db.collection<Product>('products');
// Fully typed - TypeScript knows product.name is a stringconst product = await products().add({ name: 'Widget', price: 29.99, stock: 100, createdAt: new Date().toISOString(),});How Credentials Work
Section titled “How Credentials Work”Varity manages all database credentials automatically:
| Environment | How it works |
|---|---|
| Development | The db singleton uses shared dev credentials. Your data is isolated in a dev schema. No configuration needed. |
| Production | varitykit app deploy injects production credentials into your build. Each app gets its own private database schema. |
You never need to set up a database, configure connection strings, or manage credentials.
Deploy
Section titled “Deploy”-
Install the CLI
Terminal window pip install varitykit -
Deploy your API
Terminal window varitykit app deployYour API is live. Database credentials are injected automatically.
-
Submit to the App Store (optional)
Terminal window varitykit app deploy --submit-to-store
Next Steps
Section titled “Next Steps”- Database Quick Start — Full database API deep dive
- Next.js Quick Start — Full-stack app with auth and UI
- Deploy Your App — Deployment options and configuration