Voxta.Packaging
1.10.0
Prefix Reserved
See the version list below for details.
dotnet add package Voxta.Packaging --version 1.10.0
NuGet\Install-Package Voxta.Packaging -Version 1.10.0
<PackageReference Include="Voxta.Packaging" Version="1.10.0" />
<PackageVersion Include="Voxta.Packaging" Version="1.10.0" />
<PackageReference Include="Voxta.Packaging" />
paket add Voxta.Packaging --version 1.10.0
#r "nuget: Voxta.Packaging, 1.10.0"
#:package Voxta.Packaging@1.10.0
#addin nuget:?package=Voxta.Packaging&version=1.10.0
#tool nuget:?package=Voxta.Packaging&version=1.10.0
Voxta Packaging
Reader and writer for .voxpak, the single-file container Voxta ships characters, scenarios and
content packages in.
No dependencies, and none on Voxta: this is the format on its own, for anyone hosting or serving
Voxta content. The full on-disk format is documented in docs/VOXPAK_SPECIFICATION.md inside the
package — complete enough to write an independent reader or writer in another language.
Why not a zip
- Content addressing. Blobs are keyed by the hash of their contents, so the same asset stored under two paths is written once.
- Random access. Each blob is split into independently compressed blocks, so seeking into the middle of a 20GB model costs one block decompress rather than a scan from the start.
- Encryption that keeps it. Blocks are sealed individually with AES-256-GCM, so an encrypted pack is still seekable.
Writing
await using var builder = new VoxPakBuilder(new VoxPakTempFileProvider());
await builder.AddFileAsync("character.json", "/path/to/character.json", ct);
await builder.AddFileAsync("assets/model.vrm", "/path/to/model.vrm", ct);
// Hands back the finished container, rewound. Ownership transfers to you.
await using var pak = await builder.CompleteAsync(ct);
await using var file = File.Create("character.voxpak");
await pak.CopyToAsync(file, ct);
Pass a VoxPakKey to encrypt:
var key = VoxPakKey.Create(new VoxPakSecret.Passphrase("correct horse battery staple"));
await using var builder = new VoxPakBuilder(new VoxPakTempFileProvider(), key);
VoxPakTempFileProvider writes scratch files to the OS temp directory. Packages run to tens of
gigabytes and that is often the wrong volume — implement IVoxPakTempFileProvider to put them
somewhere with room.
Reading
await using var reader = await VoxPakReader.OpenFileAsync("character.voxpak", secret: null, ct);
foreach (var entry in reader.Entries)
Console.WriteLine($"{entry.Path} ({reader.GetLength(entry.Path)} bytes)");
// Seekable, decompressed on demand a block at a time. Several may be open at once.
await using var model = reader.OpenRead("assets/model.vrm");
Ask before committing, when you may be handed either kind:
var header = await VoxPakReader.ReadHeaderAsync(stream, ct);
var secret = header.IsEncrypted ? new VoxPakSecret.Passphrase(await PromptAsync()) : null;
await using var reader = await VoxPakReader.OpenAsync(stream, leaveOpen: true, secret, ct);
Reading files from strangers
Opening a container validates it against itself before any entry is read: declared counts are
checked against the bytes that could hold them, block tables must cover the length they claim, blobs
must lie inside the container and not overlap, and entry paths must be relative and free of
traversal. A file that fails any of it is refused at open with an InvalidDataException rather than
part-way through serving an asset. The bounds are in VoxPakLimits; §11.1 of the specification
states them as requirements, so an independent reader can match.
Entry paths are validated, not sanitised. A consumer writing entries out to disk still owes its own platform-specific checks — reserved device names, trailing dots, case-insensitive collisions.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Voxta.Packaging:
| Package | Downloads |
|---|---|
|
Voxta.Storage.VoxPak
Storage-side integration for Voxta packages — serves a resource's assets straight out of the .voxpak it was imported from, with the pack cache, scratch-file provider and DI registration that goes with it. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.11.0-beta.1 | 59 | 9/23/2026 |
| 1.10.0 | 132 | 9/4/2026 |
| 1.10.0-beta.1 | 70 | 9/4/2026 |
| 1.10.0-alpha.3 | 78 | 8/26/2026 |
| 1.10.0-alpha.2 | 70 | 8/26/2026 |
| 1.10.0-alpha.1 | 91 | 8/25/2026 |