File storage with real branching

Your SaaS customers struggle to work in parallel without branching and version control

FileBackbone lets you add branching and history to content, design, and configuration files stored in FileBackbone using a simple API, so your users can iterate safely without conflicts.

Simple API flow
Save and update files with versioned commits
Live
const client = new FileBackboneClient({ baseUrl, token });

await client.putFile(repo_id, {
  branch: 'main',
  file_path: 'content/homepage.md',
  content: '# Homepage\nFirst draft\n',
  message: 'save homepage draft',
});

await client.putFile(repo_id, {
  branch: 'main',
  file_path: 'content/homepage.md',
  content: '# Homepage\nUpdated headline\n',
  message: 'update homepage headline',
});
Two commits on the same path: first save, then change.

A file system—and more

FileBackbone gives you instant operations that feel like a real file system: move a file, move a whole tree of paths, create directories—same mental model as working on disk.

import { FileBackboneClient } from 'reposys/client/filebackbone_client.js';

const repo_id = Number(process.env.FBB_REPO_ID || 1);
const baseUrl = process.env.FBB_API_BASE_URL || 'http://127.0.0.1:3000';
const token = process.env.FBB_API_TOKEN; // public_id.secret

if (!token) throw new Error('FBB_API_TOKEN is required');

const client = new FileBackboneClient({ baseUrl, token });
const branch = 'main';

async function readHeadOid() {
  const { repo_commit_object_id } = await client.get_branch_head_oid(repo_id, branch);
  return repo_commit_object_id || '';
}

// mkdir somewhere/
await client.create_directory(repo_id, {
  branch,
  path: 'somewhere',
  expected_head: await readHeadOid(),
});

// mv your-file.txt somewhere/your-file.txt
await client.fs_move(repo_id, {
  branch,
  from_path: 'your-file.txt',
  to_path: 'somewhere/your-file.txt',
  expected_head: await readHeadOid(),
});

// mkdir archive/
await client.create_directory(repo_id, {
  branch,
  path: 'archive',
  expected_head: await readHeadOid(),
});

// mv huge-dir/ archive/huge-dir-2025-02/
await client.fs_move(repo_id, {
  branch,
  from_path: 'huge-dir',
  to_path: 'archive/huge-dir-2025-02',
  expected_head: await readHeadOid(),
});

On top of that, you can instantly retrieve old versions of the whole file system, create branches, and merge changes from one branch into another—so you get familiar filesystem ergonomics plus version control when you need it.

If you only need simple blob storage, object stores like S3, R2, and similar are extremely fast and a great fit. When you need filesystem semantics, history, branches, and merges, FileBackbone is built for that.

What you get

Give your customers the same semantics they already use in code

Their teams already use Git to work in parallel. Their content, design, and configuration need the same model so they can easily use your system.

Keep a real history of changes

Track, compare, and restore content, design, and configuration across versions.

Integrate directly into your product

Use a simple API to power versioned workflows in your app, backend, or CI.

Control access as your system grows

Manage who can view, edit, and ship changes across teams and environments.

Because your customers don't work in a straight line

Your customers have many ideas. Their teams need to collaborate, but they also need to work in parallel.

Without branching, they fall back to manual workarounds. Files get duplicated, changes drift apart, and your SaaS fills up with disconnected versions, no clear history, and no way to understand what changed.

FileBackbone gives you a clean system for managing file changes so your product can support real parallel workflows.

Your customers already work in parallel.

Your product should support it.