# SQLiteWorkspaceProvider vs Database in Computer SDK: When to Use Each API Level

> Learn the difference between SQLiteWorkspaceProvider and the raw Database wrapper in the computer SDK. Use SQLiteWorkspaceProvider for Node.js file operations, and Database for direct SQL access.

- Repository: [Cloudflare/computer](https://github.com/cloudflare/computer)
- Tags: deep-dive
- Published: 2026-08-07

---

**Use `SQLiteWorkspaceProvider` for Node.js-compatible file system operations, and use the raw `Database` wrapper only when you need direct SQL access to the underlying SQLite tables.**

The Computer SDK from Cloudflare provides two distinct ways to interact with its SQLite-backed storage: a high-level virtual file system (VFS) provider and a low-level database handle. Understanding when to use each abstraction saves you from architectural mismatches and potential data corruption.

---

## What SQLiteWorkspaceProvider Provides

`SQLiteWorkspaceProvider` is a **node-fs-compatible** virtual file system implementation. It exposes the full `VirtualFileSystem` surface: `readFile`, `writeFile`, `mkdir`, `readdir`, symlink support, file watching, and more.

In [`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts), the provider is lazily instantiated:

```typescript
// workspace.ts – provider() method (lines 66-71)
provider(): SQLiteWorkspaceProvider {
  if (!this.#provider) {
    this.#provider = new SQLiteWorkspaceProvider(this.#db, { now: this.#now });
  }
  return this.#provider;
}

```

The provider satisfies the `@platformatic/vfs` interface, meaning you can wrap it with `create()` to obtain a fully-featured `VirtualFileSystem` that works with tools expecting standard Node.js `fs` APIs.

---

## What the Database Wrapper Exposes

The raw `Database` class from `@cloudflare/dofs` gives you **direct SQLite access**. You can execute arbitrary SQL, prepare statements, run transactions, and inspect the underlying schema—bypassing the VFS abstraction entirely.

The `Database` instance is created immediately when constructing a `Workspace`:

```typescript
// workspace.ts – constructor excerpt (lines 98-100)
this.#db = new Database(options.storage);
initializeSchema(this.#db, this.#now);

```

Access it via the `db` property:

```typescript
const db = ws.db;  // Database instance
const rows = await db.all(`SELECT * FROM dofs_entries WHERE type = 'file'`);

```

---

## Key Differences: SQLiteWorkspaceProvider vs Database

| Factor | SQLiteWorkspaceProvider | Raw Database |
|--------|------------------------|--------------|
| **Abstraction level** | High (VFS/file-system) | Low (SQL/native) |
| **API style** | `fs.promises`-compatible | `exec`, `run`, `all`, `prepare` |
| **Safety guarantees** | Enforces mount-read-only, reconciliation | Manual constraint enforcement |
| **Performance** | Optimized for file operations | Faster for bulk SQL operations |
| **Use case** | Git operations, build tools, file manipulation | Custom migrations, debugging, advanced queries |

---

## Practical Examples

### File System Operations via Provider

This is the typical pattern for most Computer SDK applications:

```typescript
import { Workspace } from "@cloudflare/computer";
import { create } from "@platformatic/vfs";

const ws = new Workspace({ storage: ctx.storage });
const provider = ws.provider();
const vfs = create(provider);

await vfs.writeFile("/config.json", JSON.stringify({ port: 8787 }));
const config = JSON.parse(await vfs.readFile("/config.json", "utf8"));

```

### Direct SQL for Inspection or Migration

Use the raw `Database` when the VFS abstraction hides information you need:

```typescript
import { Workspace } from "@cloudflare/computer";

const ws = new Workspace({ storage: ctx.storage });
const db = ws.db;

// Debug: find files modified since a specific watermark
const recent = await db.all<{ path: string; mtime: number }>(
  `SELECT path, mtime FROM dofs_entries 
   WHERE mtime > ? AND type = 'file'`,
  [watermark]
);

```

### Integration with isomorphic-git

The provider shines when interoperating with existing file-system-based tools:

```typescript
import { Workspace } from "@cloudflare/computer";
import { create } from "@platformatic/vfs";
import { clone } from "isomorphic-git";

const ws = new Workspace({ storage: ctx.storage });
const vfs = create(ws.provider());

await clone({
  fs: vfs,
  dir: "/repo",
  url: "https://github.com/cloudflare/workers-sdk.git",
});

```

---

## Safety and Consistency Considerations

**SQLiteWorkspaceProvider** enforces critical safety rules at the data layer:

- Mount read-only restrictions are automatically applied
- Illegal writes are filtered before reaching storage
- Participation in `reconcileWatermarks` during sync cycles
- Batched writes through `Workspace.push()`/`pull()` reconciliation

**Raw Database access** provides no such protections. You must manually respect mount constraints and synchronization semantics. Incorrect writes can corrupt the VFS state or cause reconciliation failures.

---

## Summary

- **Choose `SQLiteWorkspaceProvider`** when you need standard file system semantics, interoperability with `fs`-based tooling, or safety guarantees around mounts and sync.
- **Choose the raw `Database`** exclusively for scenarios requiring direct SQL: custom schema migrations, performance-critical bulk operations, or diagnostic queries outside the VFS model.
- Access the provider through `workspace.provider()` and the database through `workspace.db`, according to the patterns in [`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts).

---

## Frequently Asked Questions

### Can I use both APIs in the same application?

Yes. A `Workspace` instance exposes both `provider()` and `db`. You can use the VFS for standard operations and drop to raw SQL for specific needs. Just ensure you don't bypass the provider's safety checks when consistency with the VFS view matters.

### Does using Database directly improve performance?

For bulk operations—large migrations or mass updates—direct SQL can be faster by avoiding VFS overhead. For typical file workloads, the provider's optimization (batching, prepared statements) usually matches or exceeds hand-written SQL.

### What happens if I write to the database in a way that conflicts with the VFS state?

You risk corruption. The VFS maintains invariants about path encoding, entry types, and watermark tracking that raw SQL does not enforce. Always test raw database modifications against `Workspace.pull()` and `push()` cycles to verify consistency.

### Is SQLiteWorkspaceProvider available outside the Computer SDK?

It originates from `@cloudflare/dofs`, but the Computer SDK wraps and configures it specifically for workspace usage. For standalone VFS needs, use `dofs` directly rather than extracting from `computer`.