WebAssembly

Run OxiDB entirely in the browser. No server needed — data lives in memory within the WASM module and can be persisted to OPFS (the browser's Origin Private File System) so it survives page reloads. Supports MongoDB-style JSON queries, aggregation, and indexes.

Installation

Download the pre-built WASM package from GitHub releases and extract into your project:

curl -L -o oxidb-wasm.tar.gz \
  https://github.com/parisxmas/OxiDB/releases/download/v0.34.0/oxidb-wasm-v0.34.0.tar.gz

mkdir wasm && tar xzf oxidb-wasm.tar.gz -C wasm/

Your project structure:

your-project/
  wasm/
    oxidb_wasm.js          # ES module entry point
    oxidb_wasm.d.ts        # TypeScript types
    oxidb_wasm_bg.wasm     # WASM binary (~1.5 MB gzipped)
    oxidb_wasm_bg.wasm.d.ts
  index.html

Note: WASM files must be served from your own web server (same origin). Direct import from GitHub URLs will not work due to CORS restrictions.

Initialize

Load the WASM module and create an in-memory database:

<script type="module">
  import init, * as oxidb from './wasm/oxidb_wasm.js';

  await init();     // load WASM binary
  oxidb.init();     // create in-memory database
  // ready to use
</script>

Insert Documents

// Single document — returns document ID
const id = oxidb.insert('users', JSON.stringify({
  name: 'Alice', age: 30, city: 'Berlin'
}));

// Multiple documents — returns JSON array of IDs
const ids = JSON.parse(oxidb.insert_many('users', JSON.stringify([
  { name: 'Bob', age: 25, city: 'Tokyo' },
  { name: 'Charlie', age: 35, city: 'Berlin' }
])));

Query Documents

// All documents
const all = JSON.parse(oxidb.find('users', '{}'));

// Filter
const berliners = JSON.parse(oxidb.find('users',
  JSON.stringify({ city: 'Berlin' })
));

// Operators: $gt, $gte, $lt, $lte, $ne, $in, $nin, $exists, $regex
const older = JSON.parse(oxidb.find('users',
  JSON.stringify({ age: { $gt: 25 } })
));

// Single document
const alice = JSON.parse(oxidb.find_one('users',
  JSON.stringify({ name: 'Alice' })
));

Update Documents

// Returns number of modified documents
const n = oxidb.update('users',
  JSON.stringify({ name: 'Alice' }),          // filter
  JSON.stringify({ $set: { age: 31 } })       // update
);

// Operators: $set, $unset, $inc, $mul, $min, $max, $push, $pull, $addToSet
oxidb.update('users',
  JSON.stringify({ city: 'Berlin' }),
  JSON.stringify({ $inc: { age: 1 } })
);

Delete Documents

// Returns number of deleted documents
const n = oxidb.delete('users',
  JSON.stringify({ age: { $lt: 20 } })
);

Count

const total = oxidb.count('users', '{}');
const berliners = oxidb.count('users',
  JSON.stringify({ city: 'Berlin' })
);

Indexes

oxidb.create_index('users', 'age');
oxidb.create_index('users', 'city');

Aggregation Pipeline

const pipeline = JSON.stringify([
  { $match: { age: { $gte: 20 } } },
  { $group: {
      _id: '$city',
      count: { $sum: 1 },
      avg_age: { $avg: '$age' }
  }},
  { $sort: { count: -1 } }
]);
const stats = JSON.parse(oxidb.aggregate('users', pipeline));

Collections

const names = JSON.parse(oxidb.list_collections());
oxidb.drop_collection('old_data');

Persist to the browser (OPFS)

The engine core is in-memory, but the browser gives every origin a private, persistent file store — OPFS (Origin Private File System). persist_opfs() snapshots the whole database to a real origin-private file (oxidb.json); load_opfs() restores it on the next visit. Both are async (they return Promises).

await init();               // load the WASM binary
oxidb.init();               // create the in-memory database
await oxidb.load_opfs();    // rehydrate from OPFS if a snapshot exists (first run: false)

// ... insert / update / delete as usual ...
oxidb.insert('tasks', JSON.stringify({ title: 'Buy milk', done: false }));

await oxidb.persist_opfs();  // write a fresh snapshot to OPFS

A common pattern is to reload on start and snapshot on unload:

window.addEventListener('beforeunload', () => { oxidb.persist_opfs(); });

Note: OPFS is available in all modern browsers (Chrome, Edge, Firefox, Safari 16.4+). The snapshot is a full image, so it is best suited to small/medium datasets; clear_opfs() deletes it for a fresh start.

Complete Example

<!DOCTYPE html>
<html>
<head><title>OxiDB WASM</title></head>
<body>
  <pre id="out"></pre>
  <script type="module">
    import init, * as oxidb from './wasm/oxidb_wasm.js';

    await init();
    oxidb.init();

    // Insert
    oxidb.insert('tasks', JSON.stringify(
      { title: 'Buy groceries', done: false, priority: 'high' }
    ));
    oxidb.insert('tasks', JSON.stringify(
      { title: 'Write docs', done: true, priority: 'medium' }
    ));

    // Index
    oxidb.create_index('tasks', 'priority');

    // JSON query
    const urgent = JSON.parse(oxidb.find('tasks',
      JSON.stringify({ priority: 'high', done: false })
    ));

    // Aggregation
    const stats = JSON.parse(oxidb.aggregate('tasks', JSON.stringify([
      { $group: { _id: '$done', count: { $sum: 1 } } }
    ])));

    document.getElementById('out').textContent =
      JSON.stringify({ urgent, stats }, null, 2);
  </script>
</body>
</html>

API Reference

FunctionArgumentsReturns
init()Creates in-memory database
insert(collection, jsonStr)collection name, JSON document stringDocument ID (string)
insert_many(collection, jsonStr)collection name, JSON array stringJSON array of IDs
find(collection, queryStr)collection name, JSON query stringJSON array string
find_one(collection, queryStr)collection name, JSON query stringJSON string or "null"
update(collection, queryStr, updateStr)filter, update operationsModified count (number)
delete(collection, queryStr)collection name, JSON query stringDeleted count (number)
count(collection, queryStr)collection name, JSON query stringCount (number)
aggregate(collection, pipelineStr)collection name, JSON pipeline stringJSON array string
create_index(collection, field)collection name, field name
list_collections()JSON array of names
drop_collection(name)collection name
dump()JSON image string of the whole database
restore(imageStr)image from dump()
persist_opfs()Promise<void> — snapshot to OPFS
load_opfs()Promise<boolean> — restore from OPFS (false if none)
clear_opfs()Promise<void> — delete the OPFS snapshot

Build from Source

# Prerequisites: Rust, wasm-pack
cargo install wasm-pack

# Clone and build
git clone https://github.com/parisxmas/OxiDB.git
cd OxiDB/oxidb-wasm
./build.sh

# Output in pkg/

Notes

  • Queries run against an in-memory engine; call persist_opfs() to snapshot to OPFS and load_opfs() to restore, so data survives page reloads
  • WASM binary is ~1.5 MB gzipped (~4.7 MB uncompressed)
  • All queries run synchronously on the main thread
  • Supports the same query operators and aggregation pipeline as native OxiDB
  • TypeScript types included (oxidb_wasm.d.ts)
Report Issue