How to Use the Isomorphic-Git Client Directly on the SQLite-Backed VFS in Cloudflare Computer

To use isomorphic-git directly on the SQLite-backed VFS, create a VirtualFileSystem with createNodeVirtualFileSystem() and pass it to createGitClient(), which returns a Git client that persists all operations to a Durable Object-backed SQLite database.

The @cloudflare/computer package exposes a lower-level Git API that bypasses the high-level Workspace abstraction, giving you direct control over repository operations while retaining the benefits of Cloudflare's distributed, SQLite-backed virtual file system. This guide shows you how to wire the three core components together: the VFS factory, the Git client factory, and the SQLite storage provider.


Core Architecture

Three pieces work together to enable Git operations on the SQLite-backed VFS:

Component Purpose Source Location
createGitClient() Builds a Git client exposing isomorphic-git methods packages/computer/src/git/index.ts
SQLiteWorkspaceProvider Supplies SQLite-backed storage and VFS packages/rpc/src/interface.ts
VirtualFileSystem Concrete VFS implementation compatible with isomorphic-git packages/computerd/src/fuse/vfs.ts

The Git client internally uses vfs.promises as its fs implementation, mapping every file operation to SQLite-backed storage that automatically syncs across Durable Object peers.


Setting Up the SQLite-Backed VFS

Before creating the Git client, initialize the virtual file system. In packages/computerd/src/fuse/vfs.ts, the createNodeVirtualFileSystem() function returns a fully configured VFS with sync capabilities.

import { createNodeVirtualFileSystem } from "@cloudflare/computerd/fuse";
import { createGitClient } from "@cloudflare/computer/git";

// Create the SQLite-backed VFS and database connection
const { vfs, db, stopSync } = await createNodeVirtualFileSystem();

// Build Git client bound to this VFS
const git = createGitClient()({ ws: { provider: () => db } });

The vfs object implements the VirtualFileSystem contract with methods like readFile, writeFile, mkdir, and readdir that isomorphic-git expects. The db handle connects to the Durable Object's SQLite instance, and stopSync terminates the background replication loop.


Initializing and Opening Repositories

Create a New Repository

Use git.init() to write a fresh .git directory into the VFS root:

await git.init({ fs: vfs.promises, dir: "/" });

This creates the standard Git directory structure—all persisted to SQLite via the VFS layer.

Open an Existing Repository

For repositories already stored in the SQLite backing:

await git.checkout({
  fs: vfs.promises,
  dir: "/",
  ref: "main",
});

The checkout operation reads refs and objects from SQLite, reconstructing the working tree in the VFS.


Basic Git Workflow on the SQLite VFS

The following pattern demonstrates a complete add-commit-status cycle with full persistence:

// Write file to VFS (stored in SQLite)
await vfs.promises.writeFile("/README.md", "# Hello, Cloudflare!\n");

// Stage the file
await git.add({ fs: vfs.promises, dir: "/", filepath: "README.md" });

// Commit with author metadata
await git.commit({
  fs: vfs.promises,
  dir: "/",
  message: "Initial commit",
  author: { name: "Alice", email: "alice@example.com" },
});

// Get status matrix showing staged/committed state
const status = await git.statusMatrix({
  fs: vfs.promises,
  dir: "/",
});
console.table(status);

Every operation writes through to the SQLite database. The Durable Object replication layer propagates these changes to connected peers automatically.


Pulling from Remote Repositories

The client supports HTTP remotes using isomorphic-git's web transport, compatible with the Workers runtime:

await git.pull({
  fs: vfs.promises,
  dir: "/",
  url: "https://github.com/cloudflare/computer",
  ref: "main",
  singleBranch: true,
  // Optional authentication:
  // username: "token",
  // password: process.env.GITHUB_TOKEN,
});

Downloaded pack files and objects are stored in the same SQLite VFS, enabling subsequent offline operations.


Key Implementation Details

Dynamic Module Loading

In packages/computer/src/git/index.ts (lines 361-714), createGitClient() uses dynamic import to defer loading the isomorphic-git bundle:

const git = await import("isomorphic-git");

This keeps cold-start overhead minimal—the full Git implementation loads only on first Git method invocation.

Pack/Index Caching

Each client instance creates a dedicated gitCache object passed to underlying isomorphic-git functions. This cache avoids re-reading pack files from SQLite during diff and clone operations, significantly improving performance on large repositories.

Error Normalization

All errors from isomorphic-git are wrapped in a GitError class that normalizes error shapes across different failure modes. This makes error handling predictable in production Workers code.


Cleanup and Resource Management

Always stop the sync loop before process termination to close Durable Object connections gracefully:

await stopSync();

The VFS remains functional until the process exits, but replication pauses to prevent partial sync states.


Summary

  • Instantiate the VFS with createNodeVirtualFileSystem() to get a SQLite-backed file system with automatic Durable Object sync
  • Create the Git client via createGitClient() and bind it to the VFS through the database provider
  • Pass vfs.promises as the fs argument to all Git operations—isomorphic-git uses this for every file access
  • Enjoy automatic persistence: all Git operations write to SQLite and replicate to peers without additional code

Frequently Asked Questions

What is the difference between using createGitClient() and the full Workspace API?

The Workspace API in packages/computer/src/workspace.ts provides higher-level abstractions like automatic branch management and conflict resolution. createGitClient() exposes the raw isomorphic-git interface directly, giving you complete control over Git operations while still using the same SQLite-backed infrastructure. Use the client directly when you need custom Git workflows or want to minimize bundle size.

Does the SQLite-backed VFS support concurrent Git operations?

Yes, but with important caveats. The Durable Object provides single-threaded execution guarantees, so concurrent operations within the same Durable Object serialize naturally. However, the gitCache is per-client-instance, so creating multiple createGitClient() instances for the same repository may cause cache inconsistency. Share a single client instance per repository for optimal correctness.

Can I use this with Git over SSH or only HTTP?

The current implementation in @cloudflare/computer uses isomorphic-git/http/web, which supports HTTP and HTTPS remotes only. SSH transport requires Node.js-specific networking primitives unavailable in the Workers runtime. For private repositories, use HTTPS with token-based authentication as shown in the pull example.

How does performance compare to native file system Git operations?

The SQLite-backed VFS adds modest overhead for small operations due to serialization and Durable Object round-trips. However, the gitCache mitigates this for read-heavy workloads like status checks and diff operations. For large clones, initial download performance is network-bound rather than storage-bound. The key advantage is automatic durability and cross-edge replication that native file systems cannot provide.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →