Skip to content

Repository files navigation

LowPack

LowPack — local-first, application-aware lossless packing

CIReleasePython 3.9–3.14License: MITDOI

I built LowPack around one fairly simple thought: compression should understand what it is packing before it reaches for a codec. LowPack prepares data for how it will actually be stored and used, then hands it to proven lossless codecs. It is a terminal tool and Python library that stays completely on your laptop.

A quick, honest alpha note: the .lpk format is still experimental. LowPack 0.2.4 can migrate format 1.0 archives made by the 0.1 releases, but please do not make any alpha archive the only copy of important data.

Oh! One point I care about being clear on: LowPack does not universally outperform Zstandard, gzip, ZIP, Brotli, LZ4, or anything else. Results depend on the data, policy, codec versions, and machine. Version 0.2 uses store, zlib, and Zstandard underneath. The LowPack part is deterministic packaging, safe indexing, deduplication, explainable selection, and reversible preparation.

Install

Python 3.9 through 3.14 is supported. To use LowPack today, install the wheel attached to the GitHub release:

python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install "https://github.com/devkyato/Lowpack/releases/download/v0.2.4/lowpack-0.2.4-py3-none-any.whl"
lowpack --version
lowpack doctor

On macOS or Linux, activation is source .venv/bin/activate; the install command is otherwise the same. If I want the terminal command isolated from a project, I use pipx install with that wheel URL instead. Each release also includes SHA256SUMS, the source archive, and exact verification notes. The getting-started guide covers installation, upgrades, a first round trip, and common command-not-found fixes.

For development, clone the repository and use python -m pip install -e ".[dev]" in a fresh environment. That keeps the published install path separate from contributor tooling.

That is it. LowPack needs no account, website, cloud service, daemon, database, analytics, or background network access.

Five-minute demonstration

Here is the shortest useful tour I use when I want to see the full flow:

lowpack pack project -o project.lpk --profile source
lowpack list project.lpk
lowpack inspect project.lpk
lowpack verify project.lpk --full
lowpack explain project.lpk
lowpack unpack project.lpk -o restored

The exact sizes depend on the input, but a successful run reports the archive, its verification status, and restored file count in this form:

Packed 42 files to project.lpk
OK
Extracted 42 files

Selective extraction is lowpack extract project.lpk project/src -o selected. I made --overwrite explicit on purpose, and lowpack doctor is there when you want a quick check of the local environment.

If an archive came from LowPack 0.1, migrate it without touching the original:

lowpack compatibility old-project.lpk
lowpack migrate old-project.lpk -o project-1.1.lpk
lowpack verify project-1.1.lpk --full

Oh! On this part I thought the safest upgrade was the least surprising one: LowPack authenticates the old archive, rewrites only the framing and manifest, fully reconstructs and verifies the migrated temporary archive, and moves it into place only after all of that succeeds. See the compatibility guide.

Codec selection uses deterministic policy names: balanced, smallest, prefer-store, prefer-zstd-low, and avoid-zlib. They describe stable preferences rather than claiming to measure whole-machine speed or memory.

How I think about profiles

  • general is the honest default. It samples codecs without changing content, detects common compressed formats by magic bytes, chunks files, and deduplicates identical chunks. It never silently excludes ordinary files.
  • source is what I use for project trees. It keeps bytes unchanged, records a language/category manifest, and excludes a documented set of build/cache paths unless --include-all is used. Every exclusion is printed and stored.
  • telemetry is the more structured path for CSV. --telemetry-mode exact (the default) preserves byte-for-byte content. canonical separates columns, records inferred types and reversible encodings, and reconstructs deterministic RFC-style CSV; it is semantically rather than byte equivalent.

See profile details and telemetry details.

Determinism

I thought about the “same input, same archive” point early because reproducible output is much easier to trust and test. LowPack omits creation time and unstable filesystem metadata, sorts paths and manifest keys, uses canonical JSON, and writes in a stable order. Identical bytes still require identical inputs, normalized paths, metadata policy, LowPack and codec versions/settings, profile/transform settings, chunk size, and platform-independent options.

lowpack pack source -o first.lpk
lowpack pack source -o second.lpk
lowpack verify-deterministic first.lpk second.lpk

See determinism guarantees.

Security

Archive extraction is the part I refuse to treat casually. LowPack rejects traversal, absolute/drive/UNC/NUL paths, duplicate and case-colliding destinations, unknown codecs, invalid sizes, unsafe parent symlinks, and archives over conservative limits. Ordinary files are verified and extracted one chunk at a time through sibling temporary files before atomic replacement. Canonical telemetry is explicitly capped because its v1 transform still needs an in-memory reconstruction. Archived permissions are restored only when --restore-permissions is requested, and special mode bits are never applied. Symlinks are neither packed by default nor restored.

Untrusted archives should always be extracted with limits and full verification. Review the security model and report vulnerabilities according to SECURITY.md.

Benchmarking

I wanted the benchmark command to be useful even when LowPack loses. It uses a warm-up, repeated monotonic-clock runs, and environment metadata; it does not tune results to favor LowPack. Generate the fixed-seed local corpus with python benchmarks/generate_corpus.py, then run lowpack benchmark corpus --json results.json --markdown benchmark.md. Nothing is downloaded.

The table below is populated only by a real release-check run:

LowPack benchmark

Python 3.14.4 on Windows-11-10.0.26200-SP0 (AMD64); 1 warm-up, 3 measured runs. Fixed-seed generated corpus.

ScopeMethodOriginalPackedRatioEncode msDecode ms
raw-payloadstore166082216608221.0000.0020.001
raw-payloadgzip-616608228711850.52528.7931.724
raw-payloadzstd-116608228390130.5051.8971.477
raw-payloadzstd-316608228404840.5062.6831.054
raw-payloadzstd-916608228355860.50314.7181.458
tar-containertar+gzip-616608228735700.52634.88917.429
tar-containertar+zstd-116608228425370.5072.94816.010
tar-containertar+zstd-316608228437990.5082.94315.226
tar-containertar+zstd-916608228384020.50516.13318.423
full-archivelowpack-general16608229734890.586306.0511136.959
full-archivelowpack-source16608229821410.591439.0861030.350

See benchmark methodology. Measurements apply only to the identified corpus and environment.

Python API

fromlowpackimport (
inspect_archive,
migrate_archive,
pack,
probe_compatibility,
unpack,
verify_archive,
)
pack(["project"], "project.lpk", profile="source", goal="balanced")
info=inspect_archive("project.lpk")
assertverify_archive("project.lpk", full=True).validunpack("project.lpk", output="restored")
# For a 0.1 archive:probe_compatibility("old-project.lpk")
migrate_archive("old-project.lpk", "project-1.1.lpk")

Functions return typed frozen result models.

Limitations

This is where I would rather be specific than sound finished too early. The format has no forward-compatibility promise during alpha. Version 0.2 deliberately introduced manifest schema 2 after the 0.1 security review; 0.2.4 provides a checked migration from format 1.0. Source dictionaries use bounded deterministic samples and only apply to Zstandard chunks. Telemetry canonical mode stores exact IEEE-754 values, but only exact mode preserves the original decimal spelling. Canonical transforms have a 64 MiB encoded/output cap until their decoder is streamed. See all limitations.

Citation

If you use this software in research or teaching, please cite the Zenodo archive / this repository:

@dev.mako (devkyato). (2026). LowPack: local-first application-aware lossless packing for archives (Version 0.2.4).

See CITATION.cff for machine-readable metadata.

Documentation index

The documentation index connects installation, format, profiles, security, compatibility, benchmarks, limitations, and release notes.

Applications

  • Deterministic source-tree archives.
  • Local offline backup and transfer bundles.
  • Lossless telemetry and experiment artifact packing.
  • Reproducible coursework and research data packaging.

Connected projects

ProjectRole
DataryLocal-first laboratory for reproducible program and simulation evidence
RelayTiming-risk source review for control programs
OpenNetTyped ONP/1 messaging for ESP32, Raspberry Pi, and backends
TapAuthRaspberry Pi NFC attendance and reservation kiosk
Custom Arduino LibrariesNon-blocking LED and digital-output patterns
Arduino Programs GuideSafety-first, compile-checked Arduino Uno course

Contributing and license

If the idea is useful to you, I would genuinely like the project to be easy to question and improve. Start with CONTRIBUTING.md. LowPack is released under the MIT License.

About

Local-first, application-aware lossless packing built on proven codecs.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages