Skip to content

MauricioPerera/easydb-server

Repository files navigation

EasyDB Server

A MongoDB-compatible server powered by EasyDB. Connect with any standard MongoDB client and store data on your choice of backend.

mongosh ──┐
pymongo ──┤              ┌─────────┐
          ├── TCP:27017 ─│ EasyDB  │── SQLite
Compass ──┤              │ Server  │── PostgreSQL
          ├──────────────│         │── Memory
mongoose ─┘              └─────────┘── Redis, MySQL, Turso...

Why?

FerretDB gives you MongoDB compatibility on PostgreSQL. EasyDB Server gives you MongoDB compatibility on any backend — SQLite, PostgreSQL, MySQL, Redis, in-memory, and more. One server, 10+ storage engines.

This project serves as a real-world showcase of EasyDB's universal storage abstraction.

Quick Start

# Run with in-memory storage (no persistence)
npx @rckflr/easydb-server

# Run with SQLite (persistent)
npx @rckflr/easydb-server --adapter sqlite --data ./mydata

# Then connect with mongosh
mongosh mongodb://localhost:27017
// Or connect with the Node.js driver
import { MongoClient } from 'mongodb';

const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
const db = client.db('test');

await db.collection('users').insertOne({ name: 'Alice', age: 30 });
const user = await db.collection('users').findOne({ name: 'Alice' });
console.log(user); // { _id: ObjectId('...'), name: 'Alice', age: 30 }

Installation

npm install -g @rckflr/easydb-server

# SQLite support (recommended for persistent storage)
npm install -g @rckflr/easydb-server better-sqlite3

# PostgreSQL support
npm install -g @rckflr/easydb-server pg

CLI Usage

easydb-server [options]

Options:
  --port, -p <port>           Port to listen on (default: 27017)
  --host <host>               Host to bind to (default: 0.0.0.0)
  --adapter, -a <name>        Storage backend (default: memory)
  --data, -d <path>           Data directory (for sqlite)
  --connection-string <url>   Database URL (for postgres)
  --debug                     Enable debug logging
  --quiet                     Only show warnings and errors
  --help                      Show help

Examples

# In-memory (great for testing)
easydb-server

# SQLite with persistent storage
easydb-server --adapter sqlite --data ./data

# SQLite on a custom port
easydb-server -a sqlite -d ./data -p 27018

# PostgreSQL
easydb-server --adapter postgres --connection-string "postgresql://user:pass@localhost:5432/mydb"

# Debug mode (see every command)
easydb-server --adapter sqlite --data ./data --debug

Storage Backends

Backend Flag Persistence Best For
Memory --adapter memory No Testing, development, CI
SQLite --adapter sqlite --data ./path Yes Single-server, embedded, edge
PostgreSQL --adapter postgres --connection-string "..." Yes Production, multi-tenant

All backends are powered by EasyDB adapters and can be swapped with a single CLI flag — your application code doesn't change.

SQLite Persistence

Data is stored in per-collection .sqlite files:

./data/
├── _easydb_meta___global.sqlite   # Collection registry
├── test.users.sqlite               # db.users collection
├── test.products.sqlite            # db.products collection
└── myapp.orders.sqlite             # myapp.orders collection

Collections are automatically restored on server restart.

Compatibility

Supported Operations

Operation Status Examples
insertOne / insertMany Full db.users.insertOne({name: "Alice"})
find / findOne Full db.users.find({age: {$gt: 25}})
updateOne / updateMany Full db.users.updateOne({name: "Alice"}, {$set: {age: 31}})
deleteOne / deleteMany Full db.users.deleteOne({name: "Alice"})
countDocuments Full db.users.countDocuments({role: "admin"})
distinct Full db.users.distinct("role")
findOneAndUpdate Full db.users.findOneAndUpdate(filter, update, {returnDocument: "after"})
findOneAndDelete Full db.users.findOneAndDelete({name: "Alice"})
sort / skip / limit Full db.users.find().sort({age: -1}).skip(10).limit(5)
projection Full db.users.find({}, {name: 1, email: 1})
aggregate Basic $match, $sort, $limit, $skip, $project, $group, $count, $unwind, $set
createIndex Stub Acknowledged but not enforced
show dbs / collections Full show dbs, show collections
drop / dropDatabase Full db.users.drop(), db.dropDatabase()

Query Operators

Category Operators
Comparison $eq $ne $gt $gte $lt $lte $in $nin
Logical $and $or $not $nor
Element $exists $type
Array $size $all $elemMatch
Evaluation $regex $mod
Implicit {field: value} (exact match, works with arrays)

Update Operators

Operator Description
$set Set field value
$unset Remove field
$inc Increment number
$mul Multiply number
$min / $max Set if less/greater than current
$push Append to array (supports $each)
$pull Remove from array
$addToSet Append unique to array
$pop Remove first/last from array
$rename Rename field
$currentDate Set to current date

Aggregation Pipeline

Stage Status
$match Full
$sort Full
$skip / $limit Full
$project Full
$count Full
$group $sum, $avg, $min, $max, $push, $addToSet, $first, $last
$unwind Full
$set / $addFields Basic (field references only)
$lookup Not supported
$facet Not supported

Not Supported

These MongoDB features are intentionally out of scope:

  • Transactions (multi-document)
  • Change streams
  • Aggregation: $lookup, $facet, $bucket, $graphLookup
  • Full-text search ($text)
  • Geospatial queries
  • Authentication (SCRAM-SHA-256)
  • Replication / Sharding
  • GridFS
  • Wire compression

Architecture

┌─────────────────────────────────────────┐
│            MongoDB Client               │
└──────────────┬──────────────────────────┘
               │ TCP (MongoDB Wire Protocol)
               │ OP_MSG + OP_QUERY (BSON)
               ▼
┌─────────────────────────────────────────┐
│          EasyDB Server                  │
│                                         │
│  Wire Protocol ─→ Command Router        │
│                      │                  │
│              ┌───────┼────────┐         │
│              ▼       ▼        ▼         │
│          Handshake  CRUD    Admin       │
│                      │                  │
│              Query Engine               │
│          (matcher + updater)            │
│                      │                  │
│            DatabaseManager              │
│                      │                  │
│              EasyDB Core                │
│         .put() .get() .where()          │
└──────────────┬──────────────────────────┘
               │
       ┌───────┼───────┐
       ▼       ▼       ▼
    SQLite  Postgres  Memory  ...

Use Cases

  • Development: Drop-in MongoDB replacement that requires zero setup
  • Testing: Ephemeral in-memory database for CI/CD pipelines
  • Edge/Embedded: Run a MongoDB-compatible database on devices with SQLite
  • Prototyping: Start with SQLite, switch to PostgreSQL for production
  • Learning: Understand how MongoDB wire protocol works under the hood

Docker

# Build
docker build -t easydb-server .

# Run with in-memory
docker run -p 27017:27017 easydb-server

# Run with SQLite persistence
docker run -p 27017:27017 -v ./data:/data easydb-server \
  --adapter sqlite --data /data

Or with docker-compose:

services:
  easydb:
    build: .
    ports:
      - "27017:27017"
    volumes:
      - ./data:/data
    command: ["--adapter", "sqlite", "--data", "/data"]

Comparison with Alternatives

Feature EasyDB Server FerretDB MongoDB
Storage backends 10+ 2 1
SQLite backend Yes Yes No
PostgreSQL backend Yes Yes No
MySQL/Redis/KV backend Yes No No
In-memory mode Yes No No
Zero config startup Yes No Yes
npm installable Yes No No
Docker image size ~50MB ~100MB ~700MB
CRUD operations Full Full Full
Aggregation Basic Most Full
Transactions No Partial Full
Auth/TLS No Yes Full
License MIT Apache 2.0 SSPL

Contributing

PRs welcome! See SPEC.md for the full technical specification.

License

MIT

About

MongoDB-compatible server powered by EasyDB — use any backend (SQLite, PostgreSQL, Redis, Memory, etc.) with standard MongoDB clients and drivers.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors