Cosmoose

Quick Start

Install cosmoose, connect to Cosmos DB, and perform CRUD operations in minutes

Prerequisites

Install

pnpm add @cosmoose/core
yarn add @cosmoose/core
npm install @cosmoose/core

The package has the following peer dependencies that are installed automatically:

  • @azure/cosmos — Azure Cosmos DB SDK
  • zod — Schema validation
  • uuid — ID generation

Cosmoose is written in TypeScript and ships type definitions out of the box. No additional @types packages are needed.

Usage

This guide walks you through the core workflow: connect, define a schema, register a model, sync containers, and perform CRUD operations.

Connect to Cosmos DB

index.ts
import { Cosmoose } from '@cosmoose/core';

const cosmoose = new Cosmoose({
  endpoint: process.env.COSMOS_ENDPOINT!,
  key: process.env.COSMOS_KEY!,
  databaseName: 'my-app',
});

await cosmoose.connect();

The database is created automatically if it doesn't exist.

Define a Schema

schema.ts
import { Schema, Type } from '@cosmoose/core';

interface User {
  name: string;
  email: string;
  age: number;
  role: string;
}

const userSchema = new Schema<User>(
  {
    name: { type: Type.STRING, trim: true },
    email: { type: Type.EMAIL },
    age: { type: Type.NUMBER },
    role: { type: Type.STRING, default: 'member' },
  },
  {
    timestamps: true,
    container: {
      partitionKey: '/email',
    },
  },
);

Schemas validate data before it reaches Cosmos DB. The timestamps option automatically manages createdAt and updatedAt fields.

Register a Model

index.ts
const User = cosmoose.model('users', userSchema);

The first argument is the container name in Cosmos DB. The model provides type-safe CRUD operations for that container.

Sync Containers

Before inserting data, ensure the container exists with the correct configuration:

index.ts
const report = await cosmoose.syncContainers();

for (const result of report) {
  console.log(`${result.name}: ${result.status}`);
  // "users: created" on first run
  // "users: unchanged" on subsequent runs
}

syncContainers() creates missing containers and detects drift between your schema and the actual container configuration.

Create and Query Documents

index.ts
// Create a document
const user = await User.create({
  name: 'Alice',
  email: 'alice@example.com',
  age: 30,
});

console.log(user.id); // auto-generated UUID v7
console.log(user.createdAt); // auto-set timestamp
index.ts
// Get by ID
const found = await User.getById(user.id, {
  partitionKeyValue: user.email,
});

// Query with filters
const results = await User.find({ age: { $gte: 18 } })
  .sort({ name: 1 })
  .limit(10);

// Count
const count = await User.count({ role: 'member' });

Update and Patch

index.ts
// Full replacement
await User.updateById(user.id, {
  ...user,
  age: 31,
}, { partitionKeyValue: user.email });
index.ts
// Partial patch (only updates specified fields)
await User.patchById(user.id, {
  $set: { age: 31 },
  $incr: { loginCount: 1 },
}, { partitionKeyValue: user.email });

Patches are more efficient than full replacements — they only update the fields you specify.

Next Steps

On this page