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

@seawingai/wingdb

v1.0.0

Published

A json, csv, file, folder based database for fast MVP & SaaS development

Readme

WingDb

npm version License: Apache 2.0

A lightweight, file-based database library for fast MVP and SaaS development. WingDb provides multiple storage providers (JSON, CSV, files, folders) with a simple, unified API for rapid prototyping and small to medium-scale applications.

Features

  • 📁 Multiple Storage Providers: JSON, CSV, files, and folder-based storage
  • Lightweight & Fast: No external database dependencies
  • 🔧 TypeScript Support: Full type definitions and IntelliSense
  • 🎯 Simple API: Easy-to-use interface for common database operations
  • 🧪 Comprehensive Testing: Well-tested with Jest
  • 📊 Flexible Data Models: Support for structured and unstructured data
  • 🔄 Auto-backup: Built-in backup functionality
  • 📝 Logging: Integrated logging with WingLog

Installation

npm install @seawingai/wingdb
# or
pnpm add @seawingai/wingdb
# or
yarn add @seawingai/wingdb

Quick Start

import { WingDb, JsonTable, FileTable } from '@seawingai/wingdb';

// Create a custom database class
class MyDatabase extends WingDb {
  get tables() {
    return {
      users: { ctor: JsonTable, file: 'users.json' },
      config: { ctor: FileTable, file: 'config' }
    };
  }
}

// Initialize database
const db = new MyDatabase('./data');

// Load all tables
await db.load();

// Save user data
await db.setItem('users', 'user1', JSON.stringify({
  id: 'user1',
  name: 'John Doe',
  email: '[email protected]'
}));

// Get user data
const userData = await db.get('users');
console.log(userData);

Storage Providers

1. JsonTable - JSON-based Storage

Perfect for structured data with IDs.

import { JsonTable } from '@seawingai/wingdb';

// Define your data type
interface User {
  id: string;
  name: string;
  email: string;
  age?: number;
}

// Create table instance
const usersTable = new JsonTable<User>(db, 'users.json');

// Load data
await usersTable.load();

// Add user
usersTable.set({
  id: 'user1',
  name: 'John Doe',
  email: '[email protected]',
  age: 30
});

// Get user by ID
const user = usersTable.get('user1');

// Filter users
const youngUsers = usersTable.filter({ age: 30 });

// Save to file
await usersTable.save();

2. DelimitedTable - CSV-based Storage

Ideal for tabular data and spreadsheet-like operations.

import { DelimitedTable } from '@seawingai/wingdb';

// Create CSV table
const csvTable = new DelimitedTable('./data/employees.csv', ',', [
  'id', 'name', 'department', 'salary'
]);

// Load CSV data
await csvTable.load();

// Add employee
csvTable.set({
  id: 'emp1',
  name: 'Jane Smith',
  department: 'Engineering',
  salary: '75000'
});

// Save as CSV
await csvTable.save();

3. FileTable - File-based Storage

Store individual files with metadata.

import { FileTable } from '@seawingai/wingdb';

// Create file table for text files
const textFiles = new FileTable(db, 'documents', '.txt');

// Load all .txt files
await textFiles.load();

// Set file content
textFiles.set('readme', 'This is the README content');

// Get file content
const content = textFiles.get('readme');

// Save all files
await textFiles.save();

4. FolderTable - Folder-based Storage

Manage folder structures and paths.

import { FolderTable } from '@seawingai/wingdb';

// Create folder table
const projects = new FolderTable(db, 'projects');

// Load folder structure
await projects.load();

// Add project folder
projects.set('project1', '/path/to/project1');

// Get project path
const projectPath = projects.get('project1');

// Save folder structure
await projects.save();

Advanced Usage

Custom Database Implementation

import { WingDb, JsonTable, FileTable } from '@seawingai/wingdb';

class BlogDatabase extends WingDb {
  get tables() {
    return {
      posts: { ctor: JsonTable, file: 'posts.json' },
      users: { ctor: JsonTable, file: 'users.json' },
      assets: { ctor: FileTable, file: 'assets' },
      uploads: { ctor: FolderTable, file: 'uploads' }
    };
  }

  // Custom methods
  async getPost(id: string) {
    const postsTable = this.getJsonTable('posts');
    await postsTable.load();
    return postsTable.get(id);
  }

  async createPost(post: any) {
    const postsTable = this.getJsonTable('posts');
    await postsTable.load();
    postsTable.set(post);
    await postsTable.save();
  }

  async getPostsByAuthor(authorId: string) {
    const postsTable = this.getJsonTable('posts');
    await postsTable.load();
    return postsTable.filter({ authorId });
  }
}

// Usage
const blogDb = new BlogDatabase('./blog-data');
await blogDb.load();

// Create post
await blogDb.createPost({
  id: 'post1',
  title: 'My First Post',
  content: 'Hello World!',
  authorId: 'user1',
  createdAt: new Date().toISOString()
});

// Get post
const post = await blogDb.getPost('post1');

Data Filtering and Queries

// Filter by multiple criteria
const activeUsers = usersTable.filter({
  status: 'active',
  age: 25
});

// Get all items
const allUsers = usersTable.filter({});

// Complex filtering (custom implementation)
const premiumUsers = Array.from(usersTable).filter(user => 
  user.subscription === 'premium' && user.lastLogin > '2024-01-01'
);

Backup and Recovery

// Automatic backup on save
await usersTable.save(true);

// Manual backup
await usersTable.backup('./backups/users-backup.json');

// Load from backup
const backupTable = new JsonTable(db, 'backup-users.json');
await backupTable.load();

Error Handling

try {
  await db.load();
  await db.setItem('users', 'user1', userData);
} catch (error) {
  console.error('Database operation failed:', error);
  // Handle error appropriately
}

API Reference

WingDb (Abstract Base Class)

Constructor

constructor(dbPath: string)

Methods

  • load(): Promise<void> - Load all tables
  • loadTable(tableName: string): Promise<void> - Load specific table
  • get(tableName: string): Promise<any> - Get table data as JSON
  • set(tableName: string, json: string): Promise<void> - Set table data from JSON
  • setItem(tableName: string, id: string, json: string): Promise<void> - Set individual item

Protected Methods

  • getTable(tableName: string): any - Get table instance
  • getJsonTable<T>(tableName: string): JsonTable<T> - Get JSON table
  • getFileTable(tableName: string): FileTable - Get file table

JsonTable

Methods

  • load(create?: boolean): Promise<T[]> - Load data from file
  • save(backup?: boolean): Promise<void> - Save data to file
  • get(id: string): T | undefined - Get item by ID
  • set(row: T, unique?: boolean): boolean - Set item
  • filter(filters: Record<string, any>): T[] - Filter items
  • clear(): Promise<void> - Clear all data
  • backup(path: string): Promise<void> - Create backup

DelimitedTable

Methods

  • load(create?: boolean): Promise<T[]> - Load CSV data
  • save(): Promise<void> - Save as CSV
  • set(row: T, unique?: boolean): boolean - Add row
  • get(id: string): T | undefined - Get row by ID

FileTable

Methods

  • load(): Promise<void> - Load files
  • save(): Promise<void> - Save files
  • get(key: string): string | undefined - Get file content
  • set(key: string, value: string): void - Set file content
  • toJson(): Promise<string> - Export as JSON

FolderTable

Methods

  • load(create?: boolean): Promise<void> - Load folder structure
  • save(): Promise<void> - Save folder structure
  • get(id: string): T | undefined - Get folder path
  • set(key: string, value: string): void - Set folder path
  • toJson(): Promise<string> - Export as JSON

Examples

E-commerce Application

class EcommerceDB extends WingDb {
  get tables() {
    return {
      products: { ctor: JsonTable, file: 'products.json' },
      orders: { ctor: JsonTable, file: 'orders.json' },
      customers: { ctor: JsonTable, file: 'customers.json' },
      images: { ctor: FileTable, file: 'images' }
    };
  }

  async addProduct(product: any) {
    const productsTable = this.getJsonTable('products');
    await productsTable.load();
    productsTable.set(product);
    await productsTable.save();
  }

  async getProductsByCategory(category: string) {
    const productsTable = this.getJsonTable('products');
    await productsTable.load();
    return productsTable.filter({ category });
  }
}

Task Management System

class TaskDB extends WingDb {
  get tables() {
    return {
      tasks: { ctor: JsonTable, file: 'tasks.json' },
      projects: { ctor: JsonTable, file: 'projects.json' },
      attachments: { ctor: FileTable, file: 'attachments' }
    };
  }

  async getTasksByStatus(status: string) {
    const tasksTable = this.getJsonTable('tasks');
    await tasksTable.load();
    return tasksTable.filter({ status });
  }

  async addTaskAttachment(taskId: string, filename: string, content: string) {
    const attachmentsTable = this.getFileTable('attachments');
    attachmentsTable.set(`${taskId}_${filename}`, content);
    await attachmentsTable.save();
  }
}

Best Practices

  1. Always load tables before use: Call load() or loadTable() before accessing data
  2. Handle errors gracefully: Wrap database operations in try-catch blocks
  3. Use TypeScript interfaces: Define proper types for your data structures
  4. Regular backups: Enable automatic backups for critical data
  5. Organize your data: Use meaningful table names and file structures
  6. Monitor performance: For large datasets, consider data pagination

Limitations

  • Not suitable for high-concurrency: File-based storage has limitations for concurrent writes
  • No ACID transactions: No built-in transaction support
  • Limited scalability: Best for small to medium datasets
  • No built-in indexing: Complex queries may be slower

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support


Made with ❤️ by SeaWingAI