Getting Started with FLASH DB โ
FLASH is a zero-knowledge encrypted intelligence database โ the first line of privacy protection while AI is built: server-blind by architecture, local-first by default.
It is not a generic document store with encryption added later. Every layer โ storage (.farc, FlashBinary), indexing (blind trapdoors, ORE), and query โ is designed so the engine holds sealed data rather than plaintext.
1.3.1is docs only โ no extra code. What's new. This week: Do this first. Later engine (announced now): Security ahead. Mission ยท Trust Model.
Master key (1.3.0 โ recommended) โ
Do not paste master secrets in source when you can seal them once:
flashsh wrap-key # .flash-wrap (your .gitignore) + .flash-take (commit OK)
echo ".flash-wrap" >> .gitignoreimport { FlashClient } from "flash-zk";
const client = new FlashClient({
storagePath: "./flash_data",
// wrapKeyDir: "./config", // optional; default is process.cwd()
});Alternative โ explicit secret (env, secret manager), never hardcoded:
const client = new FlashClient({
storagePath: "./flash_data",
});Details: flashsh CLI ยท Trust Model.
Intelligence in 5 Minutes โ
The fastest path to FLASH's identity โ Private RAG โ Agent Memory โ Sealed Vault:
flashsh wrap-key # once, in your project root
flashsh initimport { FlashClient } from "flash-zk";
const client = new FlashClient({ storagePath: "./flash_data" });
// 1. Private RAG โ ingest & ask (server-blind)
const rag = client.privateRAG("knowledge");
await rag.ingest({
title: "Security Policy",
text: "All data is encrypted client-side...",
});
const ctx = await rag.ask("How is data protected?");
console.log(ctx.sources[0]?.text);
// 2. Agent Memory โ encrypted episodic recall
const memory = client.agentMemory("assistant");
await memory.remember("User prefers dark mode", { importance: 2 });
const facts = await memory.recall("UI preferences");
// 3. Sealed Vault โ passphrase-isolated secrets
const vault = client.sealedVault("secrets");
vault.unlock("my-passphrase");
await vault.put("api_key", { service: "openai", value: "sk-..." });
await client.close();CLI equivalent:
flashsh wrap-key # seal keys (once)
flashsh init # bootstrap local intelligence workspace
flashsh ingest ./notes.txt # add to private RAG
flashsh ask "what did I ingest?" # semantic retrievalWeb UI: run flashsh wrap-key first, then npx flash-console โ Intelligence Console (dashboard token printed as x-flash-token).
Engine Options (v1.2.5+) โ
const client = new FlashClient({
storagePath: "./flash_data",
engineOptions: {
durability: "balanced", // strict | balanced | throughput
memtableThreshold: 4 * 1024 * 1024,
},
});See Engine Options & Durability.
๐ฆ Installation โ
Install the library directly into your project:
npm install flash-zkEnsure your package.json specifies "type": "module".
๐ Quick Setup โ
1. Initialize the Client โ
import { FlashClient } from "flash-zk";
const client = new FlashClient({
dbName: "production_db",
storagePath: "./flash_data",
});2. Access Collections (Synchronous Interface) โ
Collections are instantiated synchronously and initialized on-demand:
const users = client.collection("users");
const orders = client.collection("orders");๐ Complete CRUD Guide โ
โ 1. Inserting Documents โ
A. Insert a Single Document (insertOne) โ
const insertResult = await users.insertOne({
name: "Alan Turing",
email: "alan@bletchley.gov.uk",
age: 41,
balance: 12000,
department: "Cryptography",
status: "active",
});
console.log("Inserted ID:", insertResult.insertedId);
console.log("Merkle State Root:", insertResult.merkleRoot);B. Insert Multiple Documents in Batch (insertMany) โ
const batchResult = await users.insertMany([
{
name: "Grace Hopper",
email: "grace@navy.mil",
age: 85,
balance: 35000,
department: "Compilers",
},
{
name: "Claude Shannon",
email: "claude@bell-labs.com",
age: 84,
balance: 28000,
department: "Information Theory",
},
{
name: "Ada Lovelace",
email: "ada@analytical.org",
age: 36,
balance: 42000,
department: "Mathematics",
},
]);
console.log("Inserted Count:", batchResult.insertedCount);
console.log("Inserted IDs:", batchResult.insertedIds);๐ 2. Querying & Finding Documents โ
A. Find All Documents (find()) โ
To fetch all documents in the collection:
const allUsers = await users.find();
// Or explicitly:
const allUsers = await users.find({});
console.log(allUsers);B. Find Single Document (findOne) โ
const user = await users.findOne({ email: "alan@bletchley.gov.uk" });
console.log(user.name); // 'Alan Turing'C. Exact Matching over Encrypted Blind Indexes ($eq / Direct) โ
// Matches are found via HMAC trapdoors without server decryption
const admins = await users.find({ department: "Cryptography" });D. Substring & Regex Queries ($regex) โ
// Searches using 3-Gram trapdoors with Honey Padding protection
const results = await users.find({ name: { $regex: "Grace" } });E. Range Comparisons ($gt, $gte, $lt, $lte) โ
// Searches using discrete bucketed range tokens
const seniors = await users.find({ age: { $gte: 40, $lte: 90 } });F. Pagination (limit and skip) โ
const page1 = await users.find({}, { limit: 10, skip: 0 });
const page2 = await users.find({}, { limit: 10, skip: 10 });๐๏ธ 3. Deleting Documents (deleteOne) โ
Removes the document from the active LSM store and archives a copy to .flash-trash for undo:
const deleteResult = await users.deleteOne({ email: "alan@bletchley.gov.uk" });
console.log("Deleted Count:", deleteResult.deletedCount); // 1
// Undo (while still in trash โ see Trash & Restore guide)
const undo = await users.restoreOne("doc-id-here");
console.log(undo.restored); // trueSee Trash & Restore for limits and configuration.
๐ 4. Document Count (count) โ
Returns the exact count of active, non-tombstone records:
const totalCount = await users.count();
console.log("Active Documents:", totalCount);๐งฎ 5. Stream Aggregation Pipelines (aggregate) โ
Execute multi-stage analytics pipelines with client-side streaming:
const report = await users.aggregate([
// Stage 1: Filter by condition
{ $match: { age: { $gte: 30 } } },
// Stage 2: Group and compute metrics
{
$group: {
_id: "$department",
totalPayroll: { $sum: "$balance" },
avgAge: { $avg: "$age" },
headCount: { $count: 1 },
},
},
// Stage 3: Sort results
{ $sort: { totalPayroll: -1 } },
// Stage 4: Limit results
{ $limit: 5 },
]);
console.log(report);๐ 6. Relationships & Foreign Key Joins ($lookup & populate) โ
FLASH DB supports full relationship resolution between collections via either Aggregation $lookup or Direct populate in find():
A. Direct populate in find() (Easiest) โ
// Fetch user and automatically populate all matching posts from 'posts' collection
const usersWithPosts = await users.find(
{ email: "alan@bletchley.gov.uk" },
{
populate: [
{
from: "posts", // Target foreign collection
localField: "_id", // Field in users
foreignField: "authorId", // FK field in posts
as: "articles", // Attached field name
},
],
},
);
console.log(usersWithPosts[0].articles); // Array of decrypted posts!B. Pipeline $lookup in aggregate() โ
const joinedReport = await users.aggregate([
{ $match: { department: "Cryptography" } },
{
$lookup: {
from: "posts",
localField: "_id",
foreignField: "authorId",
as: "posts",
},
},
]);๐ฒ 7. Cryptographic Merkle Proof Verification โ
Verify that a specific record has not been tampered with or corrupted on disk:
const check = await users.verifyRecordIntegrity(insertResult.insertedId);
console.log("Integrity Valid:", check.isValid); // true
console.log("Merkle Root:", check.root); // SHA-256 hash
console.log("Proof Tree Depth:", check.proofLength); // Tree path length๐พ 7. Manual SSTable Flush & Checkpointing โ
Force-flush all active MemTable entries to an immutable on-disk .sst segment:
await users.raw.flush();๐๏ธ 8. Database Management & Cleanup โ
// List all collection names in the database
const collections = client.db.listCollections();
console.log(collections); // ['users', 'orders']
// Drop a collection and permanently erase its files
await client.db.dropCollection("temporary_data");
// Graceful database shutdown
await client.close();