TGZ to JSON — describing two compressed releases as data so the difference is visible
Two tar.gz releases of the same project look identical in a file listing; what changed is inside them. This route unwinds the gzip stream inside the browser tab, reads the tar members and emits a JSON inventory of names, kinds, uncompressed payload lengths, counts and extension grouping. Payloads are described, not unpacked, and nothing is uploaded.
tar mode bits, owner and group names are not carried into ZIP; directories are written as empty entries.
Processed on your device. Files aren’t sent anywhere.
Reading a compressed release as data
The gzip stream is decompressed and its checksum validated. The reader then validates TAR headers and records supported member names and lengths. Payload bytes are omitted from the resulting JSON, which is a report rather than an extracted copy.
- Every entry appears with its name and kind, file or directory.
- File entries report the uncompressed payload length, so two releases can be compared on real size.
- Directories are listed, which is where an extra bundled folder becomes obvious.
- Entries appear in the order the tar stored them; sorted-by-name is offered when you want the inventory alphabetical.
- unsupported entries abort the read with a named error, so the inventory never contains blank rows
Comparing two inventories
Convert each release separately and read the two outputs side by side.
| Inventory part | What a difference means |
|---|---|
| counts.entries | one release carries more members than the other |
| counts.directories | an extra or removed folder in the tree |
| grouped by extension | new file types appeared, such as bundled vendored code |
| counts.bytes | total payload grew or shrank |
| entries[].bytes | which specific member changed size |
What the counts block answers
The counts block is the part you diff first: entries, files, directories and total bytes give a summary without opening every entry. The symlink and other counts stay at zero, because unsupported entry types are rejected during the read rather than tallied — a release containing symlinks, hardlinks, device entries, PAX or GNU extended headers, traversal or duplicate paths or non-UTF8 names produces an error, not a partial inventory.
Extension counts describe filenames, not detected file types. A different packager can also add or omit explicit directory records without changing nested file paths. Compare the actual member names before interpreting a changed total.
What the schema refuses to report
There are no file contents, no hashes, no modification times and no compression ratio in the output. The gzip header's stored name and time are also not carried into the inventory.
That keeps the comparison about structure and payload size. If you need contents, unpack the release yourself; the inventory does not extract members to folders and does not classify content.
Matching inventory values do not prove identical contents: two files can share a name and length while containing different bytes. Use a separate content comparison or known hashes when that distinction matters.
Diffing the releases
Bounds apply while the gzip stream decompresses, so a release that inflates is stopped rather than filling memory.
- Convert the older .tar.gz to JSON and save the output.
- Convert the newer .tar.gz the same way.
- Diff counts.entries and counts.directories first.
- Read byExtension for extensions that appeared in the newer release.
- Compare entries[].bytes for members that grew.
- If conversion rejects, read the reason: limits, damaged input, unsupported TAR variants or unsafe names can all prevent an inventory.