Skip to content

File Format

A packed onelf file is four concatenated sections:

┌────────────────────────────────────┐  offset 0
│ Runtime (static musl ELF)          │
│  670 KB (slim) or ~2 MB (update)   │
├────────────────────────────────────┤
│ Payload                            │
│  zstd-compressed 256 KB blocks     │
│  multiple entries share blocks     │
├────────────────────────────────────┤
│ Manifest (zstd-compressed)         │
│  - header (50 bytes)               │
│  - entrypoints                     │
│  - file/dir/symlink entries        │
│  - lib_dir_offsets                 │
│  - string_table                    │
├────────────────────────────────────┤
│ Dictionary (optional, raw)         │
├────────────────────────────────────┤
│ Footer (76 bytes, fixed)           │  last 76 bytes of file
│  - magic, offsets, checksums       │
└────────────────────────────────────┘

When executed, the runtime reads its own tail to discover where the manifest, payload, and dictionary begin.

76 bytes at the end of the file. All integers little-endian.

OffsetSizeFieldDescription
08magic"ONELF\0\x01\x00"
82format_version1
102flagsMEMFD_HINT (1), reserved bits
128manifest_offsetAbsolute file offset of the compressed manifest
208manifest_compressedCompressed manifest size in bytes
288manifest_originalUncompressed manifest size
368payload_offsetAbsolute offset of payload start
448payload_sizePayload total size
528dict_offsetDictionary offset (0 if absent)
604dict_sizeDictionary size (0 if absent)
644manifest_checksumXXH32 of uncompressed manifest
688end_magic"FLENONE\0"

Manifest

Compressed with zstd. After decompression:

┌────────────────┐
│ Header (50 B)  │
├────────────────┤
│ Entrypoints    │  14 bytes each * entrypoint_count
├────────────────┤
│ Entries        │  variable-size records * entry_count
├────────────────┤
│ lib_dir_offsets│  4 bytes each * lib_dir_count
├────────────────┤
│ string_table   │  null-terminated strings
└────────────────┘

Header (50 bytes)

OffsetSizeField
02manifest_version (currently 1)
24entry_count
64string_table_size
102entrypoint_count
122default_entrypoint (index into entrypoints)
142lib_dir_count
162name_offset (into string_table)
1832package_id (BLAKE3 of the serialized manifest bytes minus this field)

Entrypoint (14 bytes each)

OffsetSizeField
04name (string_table offset)
44target_entry (index into entries)
84args (string_table offset, 0x1F-separated)
121working_dir (enum)
131flags (bit 0: MEMFD_ELIGIBLE)

Entry (variable)

Represents a file, directory, or symlink. Fields:

parent:       u32 (index into entries, 0xFFFFFFFF for top-level)
mode:         u32 (unix mode bits)
mtime_secs:   u64
mtime_nsec:   u32
name:         u32 (string_table offset)
kind:         u8 (0=dir, 1=file, 2=symlink)
content_hash: [u8; 32] (BLAKE3 of concatenated block contents; zero for non-files)
symlink_target: u32 (string_table offset; 0 unless kind == symlink)
blocks: Vec<Block>  (file content block refs; empty for non-files)

Each Block is (payload_offset: u64, compressed_size: u64, original_size: u64).

Payload

Contiguous sequence of zstd-compressed blocks. Block boundaries are defined entirely by the blocks arrays in the manifest. Two files can share a block if their contents overlap, though pack.rs currently emits per-entry block lists (no content-level deduplication).

Block size defaults to 256 KB uncompressed. Each block is compressed independently, which lets the runtime decompress them lazily as the entrypoint reads files.

If a dictionary is present (dict_size > 0), each block is decompressed against that dictionary.

Reading a packed file

In pseudocode:

file = open(path)
file.seek(SeekFrom::End(-76))
footer = read 76 bytes, validate magic
file.seek(footer.manifest_offset)
compressed = read footer.manifest_compressed bytes
manifest_bytes = zstd::decompress(compressed)
assert XXH32(manifest_bytes) == footer.manifest_checksum
manifest = parse(manifest_bytes)

Then the manifest tells you how to read entrypoints, files, etc.

Integrity

  • XXH32 over the uncompressed manifest bytes catches accidental corruption of the manifest itself.
  • BLAKE3 over each file's concatenated content bytes is stored in the entry. onelf verify recomputes and compares.
  • The package_id (BLAKE3 of the manifest) uniquely identifies the package and drives cache-mode directory names.

Format compatibility

The footer's format_version field currently must be 1. Older runtimes will refuse to read newer formats with a clear error. When a future version bumps the manifest, older tools will need an update.

Released under the MIT License.