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.promisesas thefsargument 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →