What Is the `dofs` Package in Cloudflare Computer?
The @cloudflare/dofs package provides a SQLite-backed virtual filesystem (VFS) that runs inside Durable Objects, enabling persistent file storage for Cloudflare Computer.
The @cloudflare/dofs package—short for Durable-Object File System—serves as the foundational storage layer of the cloudflare/computer project. It transforms Durable Objects into persistent, content-addressed filesystems that can be mounted via FUSE, synchronized with container runtimes, or used directly for lightweight SQL-backed storage.
Core Architecture of the dofs Package
The package is organized into five distinct layers, each handling a specific aspect of virtual filesystem operations.
Database Wrapper Layer
At the heart of dofs lies the Database class in src/storage.ts. This thin wrapper around the Durable Object's DurableObjectStorage SQL API exposes convenience methods for query execution:
run(sql, ...params)– Execute a statement without returning rowsall(sql, ...params)– Return all matching rowsone(sql, ...params)– Return exactly one row or throwscalar(sql, ...params)– Return a single scalar value
The wrapper also implements a re-entrant transaction system critical for maintaining ACID guarantees during concurrent filesystem operations.
Filesystem Primitives Layer
The src/fs/ directory contains POSIX-like operations implemented directly against the SQLite schema:
| Operation | Description |
|---|---|
mkdir |
Create directories with parent auto-creation |
writeFile |
Content-addressed blob storage with chunked writes |
readFile |
Streaming reads from vfs_chunks table |
rm |
Recursive or single-node deletion |
readdir |
Directory entry enumeration via vfs_dirents |
stat |
Metadata retrieval (size, mtime, mode) |
symlink / readlink |
POSIX symbolic link support |
grep / find |
Content search utilities |
These primitives bypass traditional filesystem APIs entirely, operating on the relational schema instead.
Virtual Provider Adapter
src/provider.ts exports SQLiteWorkspaceProvider, which adapts the primitive layer to the @platformatic/vfs VirtualProvider interface. This adapter enables:
- FUSE mounting via the
computerddaemon - Sandbox container integration where the VFS appears as a standard Node.js
fsmodule - Path resolution and handle management for virtual inodes
Sync Protocol Layer
The src/sync/ directory implements the wire protocol between Durable Objects and container runtimes. Key functions include:
applyChanges(db, changeSet)– Apply remote mutations locallyfetchChanges(db, since)– Retrieve local changes for replicationpushObjects(db, objects)– Stream pending blobs to remote storagebuildManifest(db)– Generate content-addressed snapshots
These building blocks enable bidirectional synchronization of filesystem state across DO restarts and container migrations.
Schema and Migrations
src/schema/ defines the SQLite DDL that underlies the entire system:
-- vfs_nodes: inode table with content hashes
CREATE TABLE vfs_nodes (
id INTEGER PRIMARY KEY,
hash BLOB UNIQUE NOT NULL,
size INTEGER NOT NULL,
mode INTEGER,
mtime INTEGER
);
-- vfs_dirents: directory entry mappings (name → inode)
CREATE TABLE vfs_dirents (
parent_id INTEGER REFERENCES vfs_nodes(id),
name TEXT NOT NULL,
node_id INTEGER REFERENCES vfs_nodes(id),
PRIMARY KEY (parent_id, name)
);
-- vfs_chunks: content-addressed blob storage
CREATE TABLE vfs_chunks (
hash BLOB NOT NULL,
idx INTEGER NOT NULL,
data BLOB NOT NULL,
PRIMARY KEY (hash, idx)
);
The initializeSchema() function handles idempotent table creation and future migrations.
Using dofs in a Durable Object
The following example demonstrates typical dofs patterns inside a Durable Object class:
import { Database, initializeSchema, SQLiteWorkspaceProvider } from '@cloudflare/dofs';
export class WorkspaceDO extends DurableObject {
private readonly db: Database;
private readonly provider: SQLiteWorkspaceProvider;
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
// Initialize database wrapper with DO storage
this.db = new Database(ctx.storage);
// Create or migrate VFS schema
initializeSchema(this.db, Date.now);
// Create provider for FUSE/VFS compatibility
this.provider = new SQLiteWorkspaceProvider(this.db);
}
async createProject(name: string) {
const projectPath = `/projects/${name}`;
// POSIX-style API via provider
this.provider.mkdirSync(projectPath, { recursive: true });
this.provider.writeFileSync(
`${projectPath}/README.md`,
new TextEncoder().encode(`# ${name}\n`)
);
return { created: true, path: projectPath };
}
async getProjectFiles(name: string) {
const projectPath = `/projects/${name}`;
const entries = this.provider.readdirSync(projectPath, {
withFileTypes: true
});
return entries.map(e => ({
name: e.name,
type: e.isDirectory() ? 'directory'
: e.isFile() ? 'file'
: 'symlink',
size: e.isFile() ? this.provider.statSync(`${projectPath}/${e.name}`).size : null
}));
}
async syncToRemote() {
// Direct sync protocol usage (normally wrapped by @cloudflare/computer)
const { applyChanges } = await import('@cloudflare/dofs');
return applyChanges(this.db, {});
}
}
Key Source Files
Understanding dofs requires familiarity with these specific paths in the repository:
| File Path | Purpose |
|---|---|
packages/dofs/src/storage.ts |
Database class and transaction management |
packages/dofs/src/provider.ts |
SQLiteWorkspaceProvider @platformatic/vfs adapter |
packages/dofs/src/fs/ |
POSIX filesystem primitive implementations |
packages/dofs/src/sync/ |
Sync protocol and replication helpers |
packages/dofs/src/schema/ |
SQLite DDL and migration utilities |
packages/dofs/src/index.ts |
Public API surface exports |
When to Use @cloudflare/dofs
The package supports three primary use cases:
- Full Computer stack – Let
@cloudflare/computerhandledofsinitialization while you work with higher-level APIs - Custom FUSE mounting – Use
SQLiteWorkspaceProviderdirectly withcomputerdfor specialized container setups - Standalone SQL storage – Import
Databaseand schema utilities for lightweight, durable persistence without the full VFS overlay
Summary
@cloudflare/dofsimplements a SQLite-backed virtual filesystem inside Durable Objects- The five-layer architecture spans database wrapping, POSIX primitives, VFS adaptation, sync protocols, and schema management
- Key classes:
Database(storage.ts),SQLiteWorkspaceProvider(provider.ts) - Files are content-addressed and stored across
vfs_nodes,vfs_dirents, andvfs_chunkstables - The package is preview-only with an evolving API surface intended for experiments and internal tooling
Frequently Asked Questions
What does "dofs" stand for?
Dofs abbreviates Durable-Object File System. The name reflects its core purpose: providing filesystem semantics backed by Durable Object storage rather than traditional block or object storage.
How does dofs differ from Cloudflare R2 or Workers KV?
Unlike R2 (object storage) or Workers KV (key-value), dofs offers POSIX-compatible filesystem semantics including directories, symlinks, atomic renames, and partial file updates. It runs inside the Durable Object itself, eliminating external storage latency for metadata operations.
Can I use dofs without the full Cloudflare Computer stack?
Yes. While designed for Computer's FUSE-mounted containers, the standalone APIs (Database, initializeSchema, and filesystem primitives) can be imported directly for custom Durable Object storage needs.
Is dofs production-ready?
No. According to the source repository, the package is explicitly marked preview only. The API surface remains unstable, and Cloudflare intends it for prototypes, experiments, and internal tooling rather than production workloads.
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 →