UNPKG

milodb

Version:

Fast encrypted JSON database with AI-friendly API

463 lines (343 loc) • 9.91 kB
# MiloDB šŸš€ **Fast, encrypted JSON database for small projects and serverless apps** Zero-config database that works out of the box. No setup, no servers, no complexity. [![npm version](https://img.shields.io/npm/v/milodb.svg)](https://www.npmjs.com/package/milodb) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## Why MiloDB? Perfect for **small projects, prototypes, and serverless apps** where traditional databases are overkill: āœ… **Zero Setup** - No installation, no configuration, no servers āœ… **Serverless Ready** - Works in Next.js, Vercel, Netlify āœ… **Encrypted** - AES-256-GCM encryption built-in āœ… **Fast** - Indexed lookups, batch operations, streaming āœ… **TypeScript** - Full type safety and autocomplete āœ… **AI-Friendly** - Simple API that LLMs understand āœ… **Tiny** - No dependencies on external databases ### When to Use MiloDB āœ… **Perfect for:** - Side projects and MVPs - Serverless functions (Next.js, Vercel, Netlify) - Prototypes and demos - Small apps (<100k records per table) - Local development - Configuration storage - Cache layer āŒ **Not for:** - High-traffic production apps (>1M requests/day) - Complex queries (joins, aggregations) - Multi-server deployments - Real-time collaboration ## Installation ```bash npm install milodb ``` ## Quick Start ```typescript import MiloDB from 'milodb'; // Initialize (no encryption) const db = new MiloDB(); // Or with encryption const db = new MiloDB('./data', 'your-secret-key'); // Create table await db.createTable('users'); // Insert await db.insert('users', { id: 1, name: 'Alice', email: 'alice@example.com' }); // Find const users = await db.find('users', { name: 'Alice' }); // Update await db.update('users', 1, { email: 'newemail@example.com' }); // Delete await db.delete('users', 1); ``` ## Complete API ### Tables ```typescript // Create table await db.createTable('products'); // List all tables const tables = await db.listTables(); // ['users', 'products'] // Drop table await db.dropTable('products'); ``` ### Insert ```typescript // Single insert await db.insert('users', { id: 1, name: 'Bob', role: 'admin' }); // Batch insert (10x faster) await db.insertMany('users', [ { id: 2, name: 'Charlie', role: 'user' }, { id: 3, name: 'Diana', role: 'user' } ]); ``` ### Query ```typescript // Find all const all = await db.find('users'); // Find with filter const admins = await db.find('users', { role: 'admin' }); // Find by ID (indexed, instant) const user = await db.findById('users', 1); // Pagination & sorting const page = await db.find('users', { role: 'user' }, { limit: 10, offset: 20, sort: 'name', order: 'asc' } ); // Count const total = await db.count('users', { role: 'admin' }); ``` ### Update ```typescript // Update single await db.update('users', 1, { role: 'superadmin' }); // Update multiple const updated = await db.updateMany( 'users', { role: 'user' }, { active: true } ); console.log(`Updated ${updated} records`); ``` ### Delete ```typescript // Delete single await db.delete('users', 1); // Delete multiple const deleted = await db.deleteMany('users', { active: false }); console.log(`Deleted ${deleted} records`); ``` ## Real-World Examples ### 1. Next.js Blog (Serverless) ```typescript // app/api/posts/route.ts import { MiloDB } from 'milodb'; const db = new MiloDB('./data'); export async function GET() { const posts = await db.find('posts', {}, { sort: 'createdAt', order: 'desc', limit: 10 }); return Response.json(posts); } export async function POST(req: Request) { const post = await req.json(); await db.insert('posts', { ...post, id: Date.now(), createdAt: new Date().toISOString() }); return Response.json({ success: true }); } ``` ### 2. E-commerce Store ```typescript import MiloDB from 'milodb'; const db = new MiloDB('./store', process.env.DB_KEY); // Setup await db.createTable('products'); await db.createTable('orders'); // Add products await db.insertMany('products', [ { id: 1, name: 'Laptop', price: 999, stock: 50 }, { id: 2, name: 'Mouse', price: 29, stock: 200 }, { id: 3, name: 'Keyboard', price: 79, stock: 150 } ]); // Search products const affordable = await db.find('products', {}, { sort: 'price', order: 'asc', limit: 5 }); // Create order await db.insert('orders', { id: Date.now(), userId: 123, items: [1, 2], total: 1028, status: 'pending' }); // Update stock await db.update('products', 1, { stock: 49 }); // Get pending orders const pending = await db.count('orders', { status: 'pending' }); ``` ### 3. User Authentication ```typescript import MiloDB from 'milodb'; import bcrypt from 'bcrypt'; const db = new MiloDB('./auth', process.env.SECRET); await db.createTable('users'); // Register async function register(email: string, password: string) { const hash = await bcrypt.hash(password, 10); await db.insert('users', { id: Date.now(), email, password: hash, createdAt: new Date().toISOString() }); } // Login async function login(email: string, password: string) { const users = await db.find('users', { email }); if (!users.length) return null; const valid = await bcrypt.compare(password, users[0].password); return valid ? users[0] : null; } ``` ### 4. API Rate Limiting ```typescript import MiloDB from 'milodb'; const db = new MiloDB('./cache'); await db.createTable('ratelimit'); async function checkRateLimit(ip: string): Promise<boolean> { const now = Date.now(); const hour = 60 * 60 * 1000; const requests = await db.find('ratelimit', { ip, timestamp: { $gt: now - hour } }); if (requests.length >= 100) return false; await db.insert('ratelimit', { id: Date.now(), ip, timestamp: now }); return true; } ``` ### 5. Configuration Management ```typescript import MiloDB from 'milodb'; const db = new MiloDB('./config', 'config-key'); await db.createTable('settings'); // Save settings await db.insert('settings', { id: 'app', theme: 'dark', language: 'en', notifications: true }); // Load settings const config = await db.findById('settings', 'app'); // Update setting await db.update('settings', 'app', { theme: 'light' }); ``` ## TypeScript Support Full type safety with generics: ```typescript interface User { id: number; name: string; email: string; role: 'admin' | 'user'; } const users = await db.find<User>('users', { role: 'admin' }); // users is typed as User[] const user = await db.findById<User>('users', 1); // user is typed as User | null ``` ## Encryption MiloDB uses **AES-256-GCM** with proper key derivation (PBKDF2): ```typescript // Enable encryption const db = new MiloDB('./secure-data', 'your-strong-password'); // All operations are encrypted automatically await db.insert('secrets', { apiKey: 'sk-...' }); // Data is encrypted at rest // Only decrypted in memory during operations ``` **Security Notes:** - Store encryption key in environment variables - Use strong passwords (16+ characters) - Encryption adds ~20% overhead - Keys are derived using PBKDF2 (100k iterations) ## Performance **Benchmarks** (M1 Mac, 10k records): | Operation | Time | Records/sec | |-----------|------|-------------| | Insert | 0.5ms | 2,000/sec | | Batch Insert (100) | 15ms | 6,600/sec | | Find by ID | 0.1ms | 10,000/sec | | Find with filter | 5ms | 2,000/sec | | Update | 8ms | 125/sec | | Delete | 8ms | 125/sec | **Tips:** - Use `insertMany()` for bulk inserts (10x faster) - Use `findById()` for single lookups (indexed) - Enable encryption only if needed (~20% slower) - Use pagination for large result sets ## CLI ```bash # Initialize database npx milodb init # Follow prompts: # - Enable encryption? (y/n) # - Encryption key: ******** # - Create users table? (y) # Creates: # - ./db/ folder # - milo.config.json ``` ## Dashboard (Optional) Visual dashboard for managing data: ```bash cd node_modules/milodb/dashboard npm install npm run dev ``` Open http://localhost:3000 for GUI management. ## Comparison | Feature | MiloDB | SQLite | MongoDB | PostgreSQL | |---------|--------|--------|---------|------------| | Setup | āœ… None | āš ļø Binary | āŒ Server | āŒ Server | | Serverless | āœ… Yes | āš ļø Limited | āŒ No | āŒ No | | Encryption | āœ… Built-in | āŒ No | āš ļø Enterprise | āš ļø Extension | | TypeScript | āœ… Native | āš ļø Wrapper | āš ļø Wrapper | āš ļø Wrapper | | File-based | āœ… JSON | āœ… Binary | āŒ No | āŒ No | | Learning Curve | āœ… 5 min | āš ļø 1 hour | āŒ 1 day | āŒ 1 week | ## Migration Path Start with MiloDB, migrate later if needed: ```typescript // Export data const users = await db.find('users'); await fs.writeJson('export.json', users); // Import to PostgreSQL/MongoDB // Your data is just JSON! ``` ## FAQ **Q: Is this production-ready?** A: Yes, for small projects (<100k records, <10k requests/day). Not for high-traffic apps. **Q: Can I use this with Vercel/Netlify?** A: Yes! Perfect for serverless functions. Data persists in your repo. **Q: How do I backup?** A: Just copy the `./db` folder. It's plain JSON files (or encrypted). **Q: Can multiple processes access the same database?** A: No. MiloDB is single-process. Use Redis/PostgreSQL for multi-process. **Q: What about data corruption?** A: MiloDB uses atomic writes. Corruption is rare but possible. Keep backups. **Q: Performance with large datasets?** A: Works well up to 100k records per table. Beyond that, consider PostgreSQL. ## License MIT ## Contributing Issues and PRs welcome! This is a simple project - keep it simple. --- **Made for developers who want to build fast, not configure databases.** Start coding in 30 seconds: ```bash npm install milodb ```