See the ciphertext
The Install page claims the store never sees your plaintext. Don't take the claim — look at the bytes. Swap the in-memory default for to-file, which persists each record as a JSON file you can open:
pnpm add @noy-db/to-file
import { createNoydb } from '@noy-db/hub'
import { toFile } from '@noy-db/to-file'
const db = await createNoydb({
store: toFile({ dir: './data' }),
user: 'me',
secret: 'correct horse battery staple',
})
const vault = await db.openVault('acme')
const invoices = vault.collection('invoices')
await invoices.put('inv-1', { id: 'inv-1', amount: 8500, customer: 'ABC Trading' })
Now open what the store wrote — cat ./data/acme/invoices/inv-1.json:
{
"_noydb": 1,
"_v": 1,
"_ts": "2026-07-15T15:31:54.149Z",
"_iv": "OIGbecaDduQOQqO+",
"_data": "ruPaj9T50xSQoRfFM3y8NfmlXApnBRzz/Ym3XaqGlqZzao93e/LR4Pox+d0N1nJoWmhypqXAIaEaJZRBcITEmsY9jiFD",
"_by": "me"
}
That file is an envelope — the only shape any to-* store ever handles. The record's fields (amount, customer, even the field names) are inside _data, encrypted; _iv is the per-write initialization vector; the cleartext parts (_v, _ts, _by) are versioning metadata the store needs to do its job. grep 8500 -r ./data finds nothing.
The same directory also holds acme/_keyring/me.json — your keyring, whose per-collection data keys are themselves wrapped under a key derived from your secret — and acme/_meta/policy.json, the deliberately-plaintext unlock policy. Nothing readable requires anything readable to be stored: whoever holds this directory (a disk, a cloud bucket, a backup) holds ciphertext and can neither run your queries nor read your records.
The negative control
Encryption is on by default and can only be disabled explicitly. Run the same code with encrypt: false (testing only — no privacy guarantee) and read the file again:
{
"_noydb": 1,
"_v": 1,
"_ts": "2026-07-15T15:32:09.970Z",
"_iv": "",
"_data": "{\"id\":\"inv-1\",\"amount\":8500,\"customer\":\"ABC Trading\"}",
"_by": "me"
}
Same envelope shape, plaintext _data, empty _iv — that's the entire difference the secret makes, and it's the difference between a store you must trust and a store you don't have to.
In the browser
@noy-db/to-browser-idb gives you the same experiment in a web app: write a record, open DevTools → Application → IndexedDB, and inspect the stored envelopes — _data is the same opaque ciphertext there. See Core 05 — Stores for the store catalog.
Next
- Orientation — pick the capabilities your app needs and compose your
createNoydb()build. - Core 02 — Client (Enclave) — the full key hierarchy and envelope format behind what you just saw.