
Security News
CVE Volume Surges Past 48,000 in 2025 as WordPress Plugin Ecosystem Drives Growth
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.
@wnfs-wg/nest
Advanced tools
A layer around the wnfs package that provides a FileSystem class, a root tree, mounts, transactions and some other essentials.
pnpm install @wnfs-wg/nest
Scenario 1:
🚀 Create a new file system, create a new file and read it back.
import { FileSystem, Path } from '@wnfs-wg/nest'
// Provide some block store of the `Blockstore` type from the `interface-blockstore` package
import { IDBBlockstore } from 'blockstore-idb'
const blockstore = new IDBBlockstore('path/to/store')
await blockstore.open()
const fs = await FileSystem.create({
blockstore,
})
// Create the private node of which we'll keep the encryption key around.
const { capsuleKey } = await fs.createPrivateNode({
path: Path.root(), // ie. root private directory
})
// Write & Read
await fs.write(['private', 'file'], 'utf8', '🪺')
const contents = await fs.read(['private', 'file'], 'utf8')
Scenario 2:
🛰️ Listen to commit and/or publish events.
A commit is a (optionally verified) modification to the file system,
and publishes are the debounced events resulting from the commits.
This will allow us the store the latest state of our file system,
for this we need what we call the data root. This is the top-level CID
of our root tree, the pointer to our file system.
let fsPointer: CID = await fs.calculateDataRoot()
// When we make a modification to the file system a verification is performed.
await fs.write(['private', 'file'], 'utf8', '🪺')
// If the commit is approved, the changes are reflected in the file system and
// the `commit` and `publish` events are emitted.
fs.on('commit', ({ dataRoot, modifications }) => {
// Commit approved and performed ✅
})
fs.on('publish', ({ dataRoot }) => {
// Commit approved and performed ✅
// Debounced and delayed ✅
fsPointer = dataRoot
})
Scenario 3:
🧳 Load a file system from a previous pointer.
// `blockstore` from scenario 1
// `fsPointer` from scenario 2
const fs = await FileSystem.fromCID(fsPointer, { blockstore })
// `capsuleKey` from scenario 1
await fs.mountPrivateNode({
path: Path.root(),
capsuleKey,
})
fs.exists
fs.listDirectory // alias: fs.ls
fs.read
fs.size
fs.copy // alias: fs.cp
fs.move // alias: fs.mv
fs.createDirectory
fs.createFile
fs.ensureDirectory // alias: fs.mkdir
fs.remove // alias: fs.rm
fs.rename
fs.write
fs.identifier()
fs.assignIdentifier('did')
Flow:
TXT file-system.tokono.ma could resolve to the data root, a CID). That said, this could also be done without a naming system, maybe by presenting a QR code.// Step 1 & 2 (Receiver)
const { dataRoot } = await fs.registerExchangeKey('key-id', publicKey)
const receiverDataRoot = dataRoot
// Step 3, 4 & 5 (Sharer)
await fs.assignIdentifier('did')
const { dataRoot } = await fs.share(pathToPrivateItem, receiverDataRoot)
const sharerDataRoot = dataRoot
// Step 6 (Receiver)
const share = await fs.receive(sharerDataRoot, { publicKey, privateKey })
await share.read('utf8')
Instead of keeping the (symmetric) capsule key around we can use an (asymmetric) exchange key pair to mount a private node. This basically creates a share for ourselves.
// 🚀 Create & mount
await fs.createPrivateNode({
path: Path.root(),
exchangeKeyPair: { publicKey, privateKey }, // 🔑 Pass in key pair here
})
// 🧳 Load
await fs.mountPrivateNode({
path: Path.root(),
exchangeKeyPair: { publicKey, privateKey },
})
const result: Promise<
| { modifications: Modification[]; dataRoot: CID }
| 'no-op'
> = fs.transaction(t => {
t.write(…)
t.read(…)
t.write(…)
// You can use all the same methods as with the `fs` interface
})
This exists so you can approve modifications to the file system.
import { Modification } from '@wnfs-wg/nest'
const fs = FileSystem.create({
blockstore,
onCommit: async (
modifications: Modification[]
): Promise<{ commit: boolean }> => {
// For example, check if I have access to all paths.
const satisfied = modifications.every((m) =>
ALLOWED_PATHS.includes(Path.toPosix(m.path))
)
if (satisfied) return { commit: true }
else return { commit: false }
},
})
When you make a modification through the transaction method and the commit ends up not being approved, this will result in a "no-op" string. In the case of using a regular mutation method such as write it will produce an error.
Check https://wnfs-wg.github.io/nest
Read contributing guidelines here.
This project is licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
FAQs
A utility layer around the `wnfs` package.
We found that @wnfs-wg/nest demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.

Security News
Socket CEO Feross Aboukhadijeh joins Insecure Agents to discuss CVE remediation and why supply chain attacks require a different security approach.

Security News
Tailwind Labs laid off 75% of its engineering team after revenue dropped 80%, as LLMs redirect traffic away from documentation where developers discover paid products.