npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@docstack/client

v0.1.5

Published

One does not simply stack documents.

Downloads

1,760

Readme

Donate

@docstack/client

The Intelligent, Offline-First Database Engine for Modern Web Apps.

DocStack Client is a standalone, browser-based datastore built on PouchDB. It bridges the gap between simple client-side storage and full-fledged backend databases by bringing schemas, relationships, SQL-like querying, and background processing directly to the browser.

It is designed for applications that require offline capabilities, strong data consistency, and secure local storage, all while sharing the same powerful data model as the DocStack server.

🚀 Why DocStack?

Business Advantages

  • Logic as Data: Store business rules, validation scripts, and background jobs as documents in the database. Update your application's behavior dynamically without redeploying the entire codebase.
  • Zero-Latency UX: By running the database locally, your UI updates instantly. Data syncs to the server in the background when a connection is available.
  • Enterprise-Grade Security: Built-in field-level encryption ensures that sensitive user data (PII, health records) is encrypted before it hits the disk, protecting it even if the device is compromised.

Technical Highlights

  • Structured NoSQL: Enjoy the flexibility of JSON documents with the rigor of strict schemas (powered by Zod).
  • SQL in the Browser: Stop writing complex map/reduce functions. Query your local data using standard SQL syntax, including JOINs, UNIONs, and aggregations.
  • Reactive Architecture: Subscribe to changes on specific classes or documents to update your UI in real-time.
  • Background Jobs: Offload heavy processing (data cleanup, report generation) to background workers that run independently of the UI thread.

📦 Installation

To add the client to your project, use your preferred package manager.

npm install @docstack/client

⚡ Quick Start

Initialize the stack and create your first data model.

import { ClientStack, Class, Attribute } from '@docstack/client';

// 1. Initialize the stack (creates a local PouchDB instance)
const stack = await ClientStack.create('my-app-db');

// 2. Define a 'Task' class
const taskClass = await Class.create(stack, 'Task', 'class', 'User Tasks');

// 3. Add attributes to the schema
await Attribute.create(taskClass, 'title', 'string', 'Task Title', { mandatory: true });
await Attribute.create(taskClass, 'isComplete', 'boolean', 'Done?', { defaultValue: false });

// 4. Create a document
const myTask = await taskClass.add({
    title: 'Install DocStack',
    isComplete: true
});

console.log('Created Task:', myTask);

📚 Core Features & Usage

1. Advanced Querying (SQL-like)

DocStack includes a powerful query engine that translates SQL into optimized PouchDB selectors and in-memory operations.

// Find all high-priority tasks, join with Assignee, and sort
const { rows } = await stack.query(`
    SELECT t.title, u.username AS assignee
    FROM Task AS t
    JOIN User AS u ON u._id = t.assigneeId
    WHERE t.priority = 'high' AND t.isComplete = false
    ORDER BY t.createdAt DESC
`);

2. Relationships & Domains

In addition to foreign keys, define strict relationships between data types using Domains.

import { Domain } from '@docstack/client';

// Define a 1:N relationship between Projects and Tasks
const domain = await Domain.create(
    stack,
    null,
    'ProjectTasks',
    'domain',
    '1:N',
    projectClass,
    taskClass
);

// Now you can traverse relationships easily or enforce referential integrity.

3. Background Jobs

Define executable logic stored in the database. Jobs run in a sandboxed environment and can be triggered manually or by system events.

// Define a job that archives old tasks
const archiveJob = {
    _id: 'Job-ArchiveOldTasks',
    '~class': '~Job',
    name: 'Archive Tasks',
    type: 'user',
    workerPlatform: 'client',
    isEnabled: true,
    content: `
        async function execute(stack, params) {
            const { rows } = await stack.query("SELECT _id FROM Task WHERE isComplete = true");
            for (const row of rows) {
                // Custom logic to move task to archive...
                console.log('Archiving:', row._id);
            }
            return { metadata: { archivedCount: rows.length } };
        }
    `
};

// Save the job definition
await stack.db.bulkDocs([archiveJob]);

// Execute it
const run = await stack.jobEngine.executeJob('Job-ArchiveOldTasks');
console.log('Job Status:', run.status);

4. Triggers

Define custom data validations and transformations that execute automatically before or after document operations. Trigger logic is stored as data and hydrated at runtime.

// This trigger automatically generates a URL-friendly slug from a document's title
const generateSlugTrigger = {
    name: 'generate-slug-from-title',
    order: 'before',
    run: `document.slug = document.title.toLowerCase().replace(/\\s+/g, '-'); return document;`
};

// Add the trigger to a class schema
await blogPostClass.addTrigger(generateSlugTrigger);

// Now when you save a BlogPost, the slug is generated automatically
const post = await blogPostClass.add({ title: 'Hello World' });
console.log(post.slug); // 'hello-world'

5. Access Policies

Control who can read or write data with granular, rule-based policies. Great for implementing role-based access control (RBAC) and multi-tenant applications.

// Policy: Only users in the 'editors' group can write to Article documents
const editorsOnlyWritePolicy = {
    _id: 'Policy-Article-EditorsWrite',
    '~class': '~Policy',
    targetClass: ['Class-Article'],
    groupId: 'Group-Editors',
    rule: `
        // 'session' and 'document' are injected at runtime
        return session && session.sessionStatus === 'active';
    `
};

// Policy: Published articles are readable by anyone
const publicReadPolicy = {
    _id: 'Policy-Article-PublicRead',
    '~class': '~Policy',
    targetClass: ['Class-Article'],
    rule: `
        if (document.status === 'published') {
            return true;
        }
    `
};

// Save policies to activate them
await stack.db.bulkDocs([editorsOnlyWritePolicy, publicReadPolicy]);

6. Security & Encryption

Protect sensitive data transparently.

// Define a class with an encrypted field
await Attribute.create(userClass, 'socialSecurityNumber', 'string', 'SSN', {
    encrypted: true
});

// When you save a document, 'socialSecurityNumber' is encrypted using a document secure key.
// It is stored as ciphertext in PouchDB and only decrypted when accessed via the API.

🧩 Architecture

DocStack Client is composed of several modular engines:

| Engine | Description | |--------|-------------| | Core DB | PouchDB for storage and sync | | Schema Engine | Zod-based validation and schema hydration | | Query Engine | SQL parser and planner for complex data retrieval | | Job Engine | Manages asynchronous tasks and background workers | | Crypto Engine | Handles key derivation (PBKDF2) and AES-GCM encryption | | Policy Engine | Enforces granular read/write access rules per class or user-targeted, based on user sessions and document's content |


Built with ❤️ for the modern web.