How to streaming zip builder for developer workflows
- Step 1Bundle build output without checking out — When you just need to hand someone a build's artifacts, drop the dist/ folder into the Streaming ZIP Builder and Generate. No clone, no terminal, no upload — faster than rebuilding locally for a quick share.
- Step 2Mind the fixed level and ZIP-only output — There's no level slider and no format choice — it's DEFLATE 6, ZIP. If your pipeline expects maximum compression or a tarball, pair the Smart Archive Compressor (level 0-9) or zip-to-tar-gz.
- Step 3Normalise timestamps for reproducible builds — The Builder stamps entries from source file mtimes, so output isn't byte-stable across machines. Run streaming.zip through the Timestamp Normalizer with the 1980-01-01 ZIP epoch to get a reproducible archive.
- Step 4Attach a checksum for supply-chain attestation — Run the (normalised) ZIP through the Checksum Generator. Record the SHA-256 in your release notes or SBOM so downstream consumers can verify the artifact.
- Step 5Review artifact changes with Archive Diff — For a PR that changes packaged contents, run before/after archives through archive-diff to see exactly which entries were added, removed, or modified — like diff -r on the extracted trees.
- Step 6Know the automation boundary — There's no curl-able endpoint (
apiAvailable: false). For true CI automation, use fflate in Node directly; the browser tool is for interactive, ad-hoc packaging, with optional runner dispatch on paid tiers.
Dev tasks: Builder alone vs Builder + sibling
The Streaming ZIP Builder bundles; reproducibility, attestation, and diffing are sibling tools. Chain them for a complete dev workflow.
| Task | Builder alone | Add this sibling |
|---|---|---|
| Package dist/ for a teammate | Yes | — |
| Byte-reproducible artifact | No (timestamps vary) | timestamp-normalizer |
| SBOM / release hash | No | checksum-generator |
| See what changed between builds | No | archive-diff |
| Maximum compression | No (fixed level 6) | smart-archive-compressor |
| Tarball for a Linux deploy | No (ZIP only) | zip-to-tar-gz |
Reproducible-artifact recipe
Order matters: build, then normalise timestamps, then hash. The Builder is step 1 only.
| Step | Tool | Output |
|---|---|---|
| 1. Bundle artifacts | Streaming ZIP Builder | streaming.zip (timestamps = source mtimes) |
| 2. Normalise timestamps | timestamp-normalizer | ZIP with all entries at 1980-01-01 |
| 3. Hash for attestation | checksum-generator | SHA-256 to record in release notes |
Cookbook
Dev-flavoured recipes. The Builder handles bundling; the reproducibility and attestation steps are explicit follow-ons.
Package a front-end build for review
Bundle dist/ to share with a reviewer who doesn't want to run the build. JS/CSS/HTML compress well at level 6.
Drag ./dist into the dropzone -> Generate Result panel: Files: 142 Original: 28.4 MB -> Output: 7.1 MB Compression: 75.0% Download streaming.zip -> rename build-pr-481.zip -> attach to PR
Make the artifact reproducible
Two machines that run the Builder on the same dist/ can produce different bytes because entry timestamps differ. Normalise them to get a stable hash.
streaming.zip (mtimes vary by machine)
-> /archive-tools/timestamp-normalizer
targetTimestamp: 1980-01-01
-> reproducible.zip (identical bytes across machines)Hash for the release / SBOM
Record a SHA-256 so consumers can verify the exact artifact they received.
reproducible.zip -> /archive-tools/checksum-generator (SHA-256) -> 4c91...ae (paste into RELEASE.md / SBOM) Consumers re-hash and compare to confirm integrity.
Diff packaged contents across a PR
When a PR changes what gets bundled, compare the old and new ZIPs to see the precise entry-level delta.
old-artifact.zip + new-artifact.zip
-> /archive-tools/archive-diff
-> Added: dist/chunk-9f2.js
Removed: dist/chunk-1ab.js
Modified: dist/index.html (CRC changed)Then convert to tar.gz for a Linux target
If the deploy expects a tarball, build the ZIP then convert — the Builder won't emit tar.gz directly.
streaming.zip -> /archive-tools/zip-to-tar-gz -> streaming.tar.gz (DEFLATE entries repacked as gzipped tar)
Edge cases and what actually happens
Expecting byte-reproducible output
Not reproducible aloneEntry timestamps come from source file mtimes, so the same input on two machines (or two days) yields different bytes. Chain the Timestamp Normalizer (1980-01-01) after building to get a reproducible archive.
Looking for a CLI/API to wire into CI
No public APIArchive tools are browser-only with apiAvailable: false — there's no HTTP endpoint to call from a pipeline. For scripted ZIP creation in CI, use fflate in Node. Paid tiers can dispatch interactive runs via the @jadapps/runner, but that's not a build-server substitute.
Wanting maximum compression for a release artifact
Fixed level 6The Builder is locked to DEFLATE level 6. For the smallest artifact, use the Smart Archive Compressor with compressionLevel 9, accepting the extra CPU time.
Pipeline expects a tarball
ZIP onlyThe Builder writes ZIP. Many deploy systems want tar.gz. Build the ZIP, then run zip-to-tar-gz. There's no format selector in the Builder itself.
Source paths leak machine-specific structure
CautionIf dropped files carry absolute-ish relative paths, those become entry paths in the ZIP. Use path-prefix-remover afterward to strip a common top-level folder for a cleaner artifact.
Free-tier developer can't run it
Upgrade requiredThe tool is minTier: "pro". On Free the Generate action is gated. Either upgrade or use fflate locally for the same DEFLATE ZIP at no cost.
Huge dataset bundle pressures memory
Memory-boundThe finished ZIP is held as a single in-memory Blob, so packaging a large dataset can hit browser memory. For multi-GB dataset bundles, a Node fflate script or a CLI streams to disk instead.
Output filename collides with your naming convention
By designEvery build downloads as streaming.zip. CI naming conventions (with versions/commit SHAs) must be applied after download via a rename step — the Builder has no output-name field.
Frequently asked questions
Is there an API or CLI for CI?
Not a public HTTP API — archive tools have apiAvailable: false. For CI, use fflate directly in Node to build the same DEFLATE ZIP. Paid tiers can dispatch interactive runs through the @jadapps/runner headless session, but that's not designed as a build-server endpoint.
How do I make the output reproducible?
Build with the Streaming ZIP Builder, then pass streaming.zip through the Timestamp Normalizer with targetTimestamp 1980-01-01 (the ZIP epoch). That removes the per-machine timestamp variance, so the bytes — and the SHA-256 — match across builds.
Can I set the compression level?
No. It's fixed at DEFLATE level 6. For tunable compression in the browser, use the Smart Archive Compressor (level 0-9).
Can it output a tarball for my Linux deploy?
Not directly — it writes ZIP. Build the ZIP, then convert with zip-to-tar-gz. There's no tar/tar.gz selector in the Builder.
Does the output work as a CI artifact as-is?
Yes. It's a standard DEFLATE ZIP with no JAD-specific wrapper — drop it into any artifact store or unzip step. Just rename it from streaming.zip to your convention, since the name is hard-coded.
How do I attach a checksum for attestation?
Run the ZIP through the Checksum Generator (SHA-256 default) and record the hash in your release notes or SBOM. The Builder doesn't emit a checksum itself.
Can I diff what changed between two artifact builds?
Yes, with a sibling tool: feed the old and new ZIPs to archive-diff to get an entry-level added/removed/modified report. The Builder only creates archives; it doesn't compare them.
Will it preserve my dist/ folder structure?
When files arrive with relative paths (dragging a folder in Chromium), yes — entry paths use webkitRelativePath. Loose-file selection produces flat entries. For a guaranteed tree, folder-to-zip is purpose-built.
Can I strip a leading folder from the artifact paths?
Not in the Builder, but afterward yes: path-prefix-remover removes a common top-level prefix from every entry path (empty value auto-detects a single shared folder).
How large a bundle can I build?
Pro: 500 MB per file, 50,000 entries, 20 files per job. Pro+Media: 2 GB, 500,000 entries, 100 files. Developer: 2 GB, 500,000 entries, unlimited files. The assembled ZIP also has to fit in browser memory.
Is the output ZIP64-capable for big artifacts?
fflate's Zip writer switches to the ZIP64 extension when the 32-bit size/count limits are exceeded, and modern unzippers read it. For typical dev artifacts you'll hit the tier cap or browser memory before ZIP64's structural limits.
Why does it download as streaming.zip every time?
The output filename is hard-coded. There's no name field, so apply your versioned naming after download (or in the CI step that consumes it). Contents are unaffected by the rename.
Privacy first
Every JAD Archive tool runs entirely in your browser using fflate, @zip.js/zip.js, and the libarchive WASM bridge. Your archives never leave your device — verified by zero outbound network requests during processing.