What Are the Use Cases for the `dofs` Package in Cloudflare Computer?
The @cloudflare/dofs package provides a SQLite-backed virtual filesystem that powers Cloudflare Computer, used directly for workspace database operations, test storage, low-level file I/O, and state synchronization between Durable Objects and sandboxes.
The dofs package forms the storage foundation of the Cloudflare Computer (cloudflare/computer) repository. While most developers interact with it indirectly through higher-level @cloudflare/computer APIs, understanding its direct use cases unlocks advanced patterns for testing, prototyping, and custom integrations. Here are the four core use cases drawn from the actual source code.
Workspace Database Creation
The primary use case for dofs is initializing a workspace database — the root SQLite store that manages files, directories, and inodes for a Computer environment.
In packages/rpc/tests/shell-and-composite.test.ts, the pattern looks like this:
import { Database, initializeSchema } from '@cloudflare/dofs';
import { SQLiteTestStorage } from '@cloudflare/dofs/testing';
const storage = new SQLiteTestStorage();
const db = await Database.open(storage);
await initializeSchema(db);
The Database class in packages/dofs/src/index.ts exposes the low-level API, while initializeSchema prepares the root inode and required tables. This pattern appears whenever a fresh filesystem context is needed.
Test Storage Implementation
For unit tests and isolated prototypes, dofs provides SQLiteTestStorage via the testing submodule. This in-memory SQLite backend avoids filesystem dependencies and runs anywhere Node.js or Worker-compatible runtimes execute.
From packages/rpc/tests/wire.test.ts:
import { SQLiteTestStorage } from '@cloudflare/dofs/testing';
const storage = new SQLiteTestStorage();
The SQLiteTestStorage class (defined in packages/dofs/src/testing.ts) implements the same storage interface used by production Durable Object bindings, making tests behaviorally faithful without I/O overhead.
Direct File Operations
The dofs package supports low-level file system operations when you need to bypass higher-level abstractions. The Database instance methods include stat, writeFile, mkdir, readFile, and more.
In packages/computerd/src/exec/runner.test.ts, direct dofs usage validates execution behavior:
// File operations against the database directly
await db.writeFile(ROOT_INODE, '/test.txt', Buffer.from('content'));
const info = await db.stat(ROOT_INODE, '/test.txt');
These operations mirror POSIX semantics but operate on the SQLite virtual filesystem, enabling atomic transactions and deterministic behavior across distributed environments.
State Synchronization
The final use case involves synchronizing state between the Durable Object store and sandboxed execution environments. The dofs sync driver uses applyResult and readWatermark utilities to push and pull incremental changes.
In packages/rpc/src/sync-driver.ts, this pattern drives the replication layer:
import { applyResult, readWatermark } from '@cloudflare/dofs';
// Apply mutations from sandbox back to Durable Object
await applyResult(db, result);
// Read current synchronization watermark
const watermark = readWatermark(db);
This enables eventual consistency between the authoritative database (in Durable Objects) and ephemeral compute sandboxes.
Complete Working Example
Combine these use cases into a standalone demonstration:
import { Database, initializeSchema, ROOT_INODE } from '@cloudflare/dofs';
import { SQLiteTestStorage } from '@cloudflare/dofs/testing';
async function demonstrateDofs() {
// 1. Create in-memory test storage
const storage = new SQLiteTestStorage();
// 2. Open database and initialize schema
const db = await Database.open(storage);
await initializeSchema(db);
// 3. Write a file to root inode
const path = '/hello.txt';
const content = Buffer.from('Hello from dofs!');
await db.writeFile(ROOT_INODE, path, content);
// 4. Read it back and verify
const read = await db.readFile(ROOT_INODE, path);
console.log(read.toString()); // "Hello from dofs!"
// 5. Check file metadata
const stats = await db.stat(ROOT_INODE, path);
console.log(`Size: ${stats.size}, Modified: ${stats.mtime}`);
}
demonstrateDofs().catch(console.error);
This pattern works in Node.js, Vitest, or any environment with SQLite bindings.
Key Source Files
| File | Purpose |
|---|---|
packages/dofs/src/index.ts |
Core public API: Database, initializeSchema, ROOT_INODE |
packages/dofs/src/testing.ts |
Test utilities: SQLiteTestStorage |
packages/rpc/tests/shell-and-composite.test.ts |
Workspace database setup patterns |
packages/computerd/src/exec/runner.test.ts |
Direct file operation examples |
packages/rpc/src/sync-driver.ts |
Synchronization driver implementation |
Summary
- Workspace initialization — Create and prepare SQLite-backed filesystem databases using
Database.open()andinitializeSchema(). - Test isolation — Use
SQLiteTestStoragefor fast, deterministic unit tests without external dependencies. - Low-level I/O — Execute
readFile,writeFile,stat, and directory operations directly onDatabaseinstances. - Distributed sync — Leverage
applyResultandreadWatermarkfor state synchronization between Durable Objects and sandboxes.
Frequently Asked Questions
Is dofs intended for direct use, or only through the Computer API?
Most production code should use the higher-level @cloudflare/computer APIs, which wrap dofs with safety guarantees and ergonomic interfaces. Direct dofs usage is appropriate for custom tooling, testing infrastructure, and advanced scenarios requiring precise control over storage semantics.
Can I use dofs outside of Cloudflare's infrastructure?
Yes. The SQLiteTestStorage backend runs in any Node.js or Worker-compatible environment with SQLite bindings. Production dofs usage requires Durable Object bindings for persistence, but the core library is portable for development and testing.
What is the performance characteristic of dofs compared to native filesystems?
dofs trades raw throughput for consistency and portability. SQLite transactions provide ACID guarantees, and the virtual filesystem layer enables snapshotting and replication that native filesystems cannot offer in edge environments. Benchmarks in the test suite suggest overhead is acceptable for typical Computer workloads.
How does dofs handle concurrent access?
Concurrency control is implemented at the Durable Object level for production deployments. Within a single Database instance, SQLite's WAL mode provides read concurrency with serialized writes. The sync-driver.ts implementation serializes mutations through watermarks to maintain causal consistency across distributed instances.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →