Architecture Deep-Dive
Internal details of Zoi's store structure and transaction log format for contributors.
This document provides a technical deep-dive into Zoi's internal architecture, focusing on how packages are stored on disk and how Zoi ensures atomic operations through its transaction system. This is intended for library contributors and developers looking to integrate Zoi deeply into their own applications.
Public Library Surface
For application integrations, prefer the stable wrappers in src/lib.rs over calling internal modules directly. The recommended public entry points are:
build_with_optionsinstall_package_with_optionsinstall_sourcesresolve_packageresolve_dependency_graph
The lower-level modules under pkg::, cmd::, and project:: remain useful for contributors, but they should be treated as internal implementation details unless they are explicitly re-exported or documented in the library API reference.
Zoi Store Structure
Zoi follows a structured, collision-resistant layout for managing package installations. By default, the Zoi home directory is located at ~/.zoi.
Store Root
All installed packages are stored in the pkgs/store directory within the Zoi home:
- User Scope:
~/.zoi/pkgs/store/ - System Scope:
- Linux/macOS:
/var/lib/zoi/pkgs/store/ - Windows:
C:\ProgramData\zoi\pkgs\store
- Linux/macOS:
- Project Scope:
./.zoi/pkgs/store/(relative to project root)
Package Identification and Hashing
To prevent naming collisions across different registries and repositories, Zoi identifies every package by a unique ID generated from its origin.
- Package ID String:
#{registry-handle}@{repo-path}/{package-name}- Example:
#zoidberg@core/linux
- Example:
- Hashing: The ID string is hashed using SHA-512.
- Directory Name: Zoi uses the first 32 characters of the hex-encoded hash, followed by the package name.
- Format:
{hash32}-{package-name} - Example:
8f1a...-linux
- Format:
Directory Layout
Inside the store, each package has its own directory containing versioned installations and metadata.
{hash}-{name}/
├── {version}/ # Actual package files
│ ├── bin/ # Binaries (linked to PATH)
│ ├── manifest.yaml # Installation manifest for this version
│ └── ... # Staged package contents (libs, share, etc.)
├── latest # Symlink to the current active version directory
└── dependents/ # Directory containing files named by hex-encoded IDs
# of packages that depend on this one.The latest Symlink
The latest symlink always points to the directory of the currently active version. This allows Zoi to perform atomic version swaps by updating a single symlink.
Dependents Tracking
Zoi implements simple reference counting using the dependents/ directory. When package A installs package B as a dependency, Zoi creates an empty file in B/dependents/ named with the hex-encoded ID of A. This prevents B from being uninstalled as long as the directory is not empty.
Binary Linking
Binaries are not added to the system PATH individually. Instead, Zoi maintains a global bin directory (~/.zoi/pkgs/bin) and creates symlinks to the binaries located inside the specific {version}/bin/ directories in the store.
Dependency Resolution (SAT Solver)
Zoi uses a Boolean Satisfiability (SAT) solver to resolve dependencies. This ensures that even the most complex dependency graphs with version constraints and conflicts are solved mathematically.
The Engine: PubGrub
Zoi integrates the PubGrub algorithm (via the pubgrub crate), which is a next-generation version solver also used by cargo and uv. PubGrub provides:
- Conflict-Driven Clause Learning (CDCL): Quickly narrows down the search space for valid solutions.
- Human-Readable Errors: If a set of dependencies is impossible to satisfy, Zoi prints a clear explanation of exactly which constraints are clashing.
- Backtracking: If an initial choice leads to a dead-end, the solver can backtrack and try alternative versions.
SQLite-Powered Metadata
The solver is fed by a high-performance SQLite database. During a zoi sync, Zoi builds an index of every available package version and its requirements. This allows the solver to query thousands of versions in milliseconds without parsing thousands of Lua files on the fly.
Global File Indexing
Zoi supports searching for files across all active registries, even for packages that are not installed. This is achieved via:
- Remote File Metadata: Registries can host
.filesmetadata files for each package. - SQLite Indexing: When
zoi sync --filesis run, Zoi downloads these file lists and populates a dedicatedpackage_filestable in the SQLite database. - FTS5 Integration: The file table uses a Virtual Table with FTS5 indexing, allowing for near-instant searching of millions of file paths using the
zoi search --filescommand.
PGP Key Management
Zoi uses a dedicated keyring for package and registry verification, separate from the system's GPG keyring.
- Key Storage:
~/.zoi/pgps/ - Format: Public keys are stored as standard ASCII-armored
.ascfiles.
Built-in Keyring
Zoi features a built-in mechanism for embedding "Root of Trust" keys. During the build process, build.rs scans src/pkg/pgp/builtin/ for .asc files and generates a static byte array containing their contents. On startup, Zoi's ensure_builtin_keys() function compares these embedded keys against the local store and automatically imports any that are missing or have been updated.
Transaction System
Zoi ensures system integrity by wrapping all state-changing operations (install, uninstall, upgrade) in transactions.
Transaction Logs
Transaction logs are stored as JSON files in ~/.zoi/transactions/. They are named using UUID v7, which provides both uniqueness and chronological ordering.
Log Format
A transaction log records the starting time and a sequential list of operations.
{
"id": "018e...-...",
"start_time": "2026-02-26T10:00:00Z",
"operations": [
{
"install": {
"manifest": {
"name": "hello",
"version": "1.0.0",
"repo": "community",
"registry_handle": "zoidberg",
"scope": "user",
"installed_files": [
"/home/user/.zoi/pkgs/store/.../1.0.0/bin/hello"
],
...
}
}
}
]
}Operation Types
The operations array contains one of three objects:
install: Contains theInstallManifestof the newly installed package.uninstall: Contains theInstallManifestof the package that was removed.upgrade: Contains bothold_manifestandnew_manifest.
Atomicity and Rollback
- Atomic Commits: When an operation completes successfully, Zoi deletes the transaction log. A missing log indicates a successful "commit."
- Automatic Rollback: If Zoi crashes or encounters an unhandled error, the transaction log remains on disk. On the next invocation (or via
zoi rollback), Zoi reads the log and reverts operations in reverse order. - Manual Rollback: Users can trigger a rollback of the last successful transaction using
zoi rollback --last-transaction, which uses the same mechanism but targets the most recently created log.
2026 © All Rights Reserved.
- All the content is available under CC BY-SA 4.0, expect where otherwise stated.
- Source code is available on GitLab, licensed under Apache 2.0.
Last updated on
