{"slug": "introducing-casita-a-content-addressed-store-for-source-code-and-build-artifact", "title": "Introducing Casita: A content-addressed store for source code and build artifact", "summary": "Cachix introduced Casita, a pre-release content-addressed object store for source code and build artifacts, available as a Rust library and CLI targeting Linux, macOS, and Windows. Casita stores immutable byte blobs addressed by BLAKE3 hashes and immutable object records that link them into a graph, offering shared storage, verification, synchronization, and garbage collection, with an optional Bao outboard so a reader can verify one range without reading the whole blob. The project added an ArtifactStorage interface to Cargo so registry archives, Git dependencies, and workspace build outputs can persist through different backends, though the Casita backend remains experimental because import and restore performance has not yet matched the filesystem backend.", "body_md": "### Cargo\n\n**libuv.rlib**\n\nWaiting\n\n**uv**\n\nWaiting\n\n**uv.d**\n\nWaiting\n\nWriting outputs\n\nWe’re rewriting [Nix](https://nix.dev/) in Rust, and it needs to be\n[split into layers](https://casita.rs/concepts/responsibilities/) and modernized.\n\nIts storage, build machinery, and higher-level tools can each be useful on their own.\n\nYou should be able to use one layer without adopting the whole stack.\n\nThat matters even more in agentic development. Agents produce more source code, more versions of it, and more build artifacts as they explore and test changes.\n\nKeeping every copy quickly becomes expensive, but throwing everything away means rebuilding or regenerating work you might need again.\n\nDevelopers are sharing screenshots of disks filled with `target/` directories in a matter of hours.\n\nIt feels familiar to how Nix users who have had to garbage collect\ntheir `/nix/store`: which artifacts are still useful, which ones can go, and how to reclaim space without losing what another project still needs.\n\nCasita is our first standalone layer, a [content-addressed object store](https://casita.rs/overview/) for source code and build artifacts, with [shared storage](https://casita.rs/concepts/deduplication/), [verification](https://casita.rs/concepts/verification/), [synchronization](https://casita.rs/concepts/sync/), and [garbage collection](https://casita.rs/concepts/garbage-collection/).\n\nIt is still pre-release and available as a Rust library and CLI. We’re targeting Linux, macOS, and Windows.\n\nRust workspaces and throwaway checkouts can accumulate `target/` directories.\nDeleting them discards artifacts a later build might reuse; keeping them\nduplicates bytes across similar projects. [Cargo](https://doc.rust-lang.org/cargo/guide/cargo-home.html)\nand [uv](https://docs.astral.sh/uv/concepts/cache/) cache downloaded\ndependencies, but their caches do not manage source versions and generated\noutputs across projects.\n\nWe added an [`ArtifactStorage` interface](https://github.com/cachix/cargo/commit/a393d0143a6a5ee600e2c6f87d0eb537de8954d2)\nso Cargo can prepare and persist registry archives, Git dependencies, and\nworkspace build outputs through different backends. The filesystem backend\npreserves Cargo’s usual behavior.\n\nThe [Casita backend](https://github.com/cachix/cargo/commit/7953f9427a3dba5eae5f3eb687d7a8ae9b78fa3b)\nimports and restores that content through [local IPC](https://casita.rs/integrations/ipc/),\nwhile Cargo still decides what to download and build. This remains\nexperimental: import and restore performance has not yet matched the\nfilesystem backend. The [development branch](https://github.com/cachix/cargo/tree/artifacts%2Bcasita)\nand [Cargo guide](https://casita.rs/integrations/cargo/) have the details.\n\nThink of Casita’s storage model as a generalized Git object database. Git has blobs, trees, and commits. Casita stores immutable byte blobs and immutable object records: each format defines an object’s identity and its links to other objects. A directory links to its files and subdirectories; a Git commit links to a tree and its parents. Casita follows those links to find a complete saved version.\n\nEvery blob has a\n[BLAKE3](https://github.com/BLAKE3-team/BLAKE3/blob/master/README.md) hash of its\ncomplete bytes. BLAKE3 computes that hash as the root of a Merkle tree. Casita\ncan keep an optional [Bao *outboard*](https://github.com/oconnor663/bao#outboard-mode)\nwith the tree’s intermediate hashes, so a reader can verify one range against\nthe blob’s hash without reading the whole blob. A full sequential read checks\nthe complete hash. The storage backend may chunk and compress the bytes without\nchanging their address.\n\nAn object record gives those bytes meaning and links. For `src/main.rs`, a file\nrecord points to the blob containing its source code. The `src/` directory has\nits own record, which links to that file record and points to a blob encoding\nthe directory entries. These records form a graph above the blobs.\n\nFor this [filesystem tree](https://casita.rs/concepts/directory-storage/), the hashes connect\nroughly like this:\n\nChanging `main.rs` creates a new file ID, which changes the `src/` directory\nID and the IDs of its parent directories. Unchanged files keep their IDs and\nstored bytes. The old blobs and records are never rewritten.\n\nThe blob’s BLAKE3 hash and a source format’s hash serve different purposes. A\n[Git commit](https://casita.rs/guides/git/) keeps its native Git ID while Casita addresses its\nbody bytes by their BLAKE3 hash. A [Nix archive\n(NAR)](https://nix.dev/manual/nix/2.35/command-ref/nix-store/dump) has a SHA-256\nhash of its canonical serialization. Casita measures that NAR hash, then stores\nthe archive’s files as a graph of BLAKE3-addressed blobs. The verified object\nrecords let Casita traverse the graph without decoding every payload.\n\nRead [Blob Storage](https://casita.rs/concepts/blob-storage/) and the\n[repository model](https://casita.rs/concepts/repository/) for the detailed contracts. The\n[NAR IPC guide](https://casita.rs/integrations/ipc/#nar-and-filesystem-nar) shows how to import\nand restore an archive.\n\nAn application gives a saved graph a name, called a\n[*root*](https://casita.rs/concepts/roots-and-retention/). The root points to one exact object and\nkeeps everything reachable from it. The objects and blobs stay immutable; the\napplication can move or remove the root as its needs change.\n\nApplications can save separate versions explicitly. For example, import a\nproject directory after two revisions under `projects/app/v1` and\n`projects/app/v2`. The imports leave the original working directory in place.\nBoth names keep their versions available, and identical files share one blob.\nAn application could also point `projects/app/current` at the same object as\n`v2`, then move that name to a later version without changing either saved\ngraph.\n\nCasita follows links from a root to find its complete graph for synchronization and retention. Removing a name makes objects needed only by that name eligible for garbage collection once active work releases them; files and chunks shared with another root remain.\n\nRoots are permanent by default, which suits saved Git histories and releases.\nRebuildable data, such as a Cargo `target/` directory, can instead use an\nevictable root:\n\nThe CLI can also change retention later with [`root retention`](https://casita.rs/reference/cli/#root-retention).\nThe [Rust API](https://casita.rs/reference/rust-api/) provides `set_root_with_retention` and\n`touch_root` for applications that manage their own cache roots. Marking a root\nevictable does not remove it immediately.\n\n[Importers](https://casita.rs/concepts/imports/) turn inputs into graphs that Casita can verify\nand retain. The [filesystem importer](https://casita.rs/guides/filesystem/) walks a directory;\nthe [tar importer](https://casita.rs/guides/tar/) reads an archive without extracting it first;\nand the [NAR importer](https://casita.rs/integrations/ipc/#nar-and-filesystem-nar) measures a\nNix archive’s canonical SHA-256 while storing its files as a graph. The\n[Git importer](https://casita.rs/guides/git/) keeps native Git object IDs and a view of selected\nbranches and tags.\n\nEach importer uses the same repository publication and retention rules. Once content is saved under a root, Casita can synchronize it and collect it when no name or active work needs it.\n\n[Casitar](https://casita.rs/guides/casitar/) writes a complete saved graph to a portable\n`.casitar` archive. You can pass it through a file, pipe, or release artifact\nwhen the source repository is unavailable to the receiver. On import, Casita\nchecks every payload and object record, verifies that the archive contains the\nwhole graph, and then publishes the destination roots together. The archive\ncarries object identities and bytes, independent of the source repository’s\npacking and database layout.\n\nThe experimental [Gix object database\nadapter](https://github.com/cachix/casita/blob/main/crates/casita/examples/gix_casita_odb.rs)\nreads and writes native Git objects through Casita. Git’s SHA-1 or SHA-256 IDs\nstay intact while Casita verifies and stores the object bodies and their links.\nThe adapter covers object storage; a complete Git repository also needs its\nrefs, index, and working tree integrated. The example writes a blob, tree, and\ncommit, then reopens the store and reads the commit back.\n\nThe companion [CasitaFS](https://github.com/cachix/casita/blob/main/crates/casita-fs/README.md)\ncrate presents a saved filesystem tree as a read-only mount. Existing tools can\nbrowse its files without first checking out the whole tree. It uses FUSE on\nLinux and a native FSKit extension on macOS 26 or later. The macOS extension\nrequires explicit setup for each user.\n\nSuppose a second repository already has `projects/app/v1`. Syncing\n`projects/app/v2` reuses what is there and sends missing content. Compatible\nstores can reuse chunks within changed files too. The destination checks\nincoming objects against their format’s rules and verifies that the whole\nsaved version arrived before it updates the name. An interrupted transfer can\nbe retried without exposing a partial version through that name.\n\nLocal repository sync is implemented in the CLI and Rust library. An optional\nSSH source uses OpenSSH for the connection while the receiving Casita repository\nstill verifies what arrives. Sync adds content; removing destination names and\ncollecting unused data are separate actions. See [Synchronization](https://casita.rs/guides/sync/)\nfor local, SSH, and selective workflows.\n\nIf both `projects/app/v1` and `projects/app/v2` are named, Casita keeps both.\nRemove the first name and run collection: bytes needed only by `v1` can go,\nwhile files and chunks shared with `v2` stay. Active readers and writers also\nhold on to the data they are using during collection.\n\nThe local CLI can preview a pass with `gc --dry-run` before running `gc`.\n\nAutomatic collection helps keep a busy disk from filling up. In the standard\nlocal repository, starting a mutation when the filesystem is at least 80% full\ntriggers a nonblocking collection attempt. Casita first reclaims data no root\nor active operation needs. If disk use remains at or above 75%, it releases\nthe least recently used roots explicitly marked evictable, vacuuming after\neach release until use falls below 75% or no eligible roots remain. Permanent\nroots stay, and manual `gc` preserves every named root, including evictable\nones.\n\nCollection applies to the Casita repository. See\n[Garbage Collection](https://casita.rs/concepts/garbage-collection/) for the retention and\nrecovery rules.\n\nTwo runners can use the same S3 bucket and prefix to publish objects and read\nnamed versions. Their payload bytes are immutable, but names and object\nrecords change as new versions arrive. Casita records those changes in\nChroma’s **wal3**, a write-ahead log stored in S3. Conditional updates to its\nmanifest give competing writers an agreed order for their changes.\n\nReaders and writers register durable holds so collection preserves data still\nin use. The S3 profile is experimental and requires the `s3` feature; an\nabandoned hold needs explicit recovery. The [shared S3 guide](https://casita.rs/guides/s3-multi-owner/)\nshows how independent owners can use one repository, and [S3\nmaintenance](https://casita.rs/guides/s3-maintenance/) covers collection and recovery.\n\nCasita runs from a source checkout today, but we have not tagged `v0.1.0`.\nBefore the first release, we need to improve performance where benchmarks show\nbottlenecks, broaden benchmark coverage, and use Casita in more real projects\nand end-to-end workflows. That practical use should expose problems we can fix\nbefore calling 0.1 ready.\n\nThe integrations have more work ahead. Cargo’s Casita backend needs faster import and restore before it can match the filesystem backend. The Git object store adapter still needs integration with the rest of a Git repository.\n\nFrom a Casita source checkout, install the CLI, then import a directory into the default repository, list its roots, and preview collection:\n\nWhen roots and object records are in one Casita repository and the matching blobs are in another, choose the blob source during sync:\n\nThe [sync guide](https://casita.rs/guides/sync/#read-payloads-from-another-repository) explains\nthe requirements for a separate blob source.\n\nThe [Quick Start](https://casita.rs/getting-started/) walks through checkout and inspection,\nand the [Library guide](https://casita.rs/library/) shows the supported Rust API.\n\nOur [filesystem benchmark](https://casita.rs/benchmarks/)\ncompares imports with Git add and commit. In that run, Casita imported the\nlarge-file corpus faster, while Git was faster for small-file imports and\nunchanged re-imports. The [full benchmark reference](https://casita.rs/reference/benchmarks/)\nincludes methodology and separate native Git measurements.", "url": "https://wpnews.pro/news/introducing-casita-a-content-addressed-store-for-source-code-and-build-artifact", "canonical_source": "https://casita.rs/blog/introducing-casita-a-content-addressed-store-for-source-code-and-build-artifacts/", "published_at": "2026-09-27 02:51:26+00:00", "updated_at": "2026-09-27 03:01:13.734617+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "ai-infrastructure"], "entities": ["Casita", "Cachix", "Nix", "Rust", "Cargo", "uv", "BLAKE3", "Bao"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/introducing-casita-a-content-addressed-store-for-source-code-and-build-artifact", "markdown": "https://wpnews.pro/news/introducing-casita-a-content-addressed-store-for-source-code-and-build-artifact.md", "text": "https://wpnews.pro/news/introducing-casita-a-content-addressed-store-for-source-code-and-build-artifact.txt", "jsonld": "https://wpnews.pro/news/introducing-casita-a-content-addressed-store-for-source-code-and-build-artifact.jsonld"}}