Studio ZIP
A VS Code extension to read and write archives directly, without unpacking them
first. Clicking a .zip opens a Studio ZIP tab — tree on the left, file preview
on the right — and every entry can also be opened as a real editor tab through
the zipfs: file system.
Status
The ZIP family reads and writes; everything else reads.
| Format |
State |
ZIP family (.zip .jar .war .vsix .epub .docx …) |
read + write |
tar family (.tar .tar.gz .tar.xz .tar.bz2 .tar.zst .tgz …) |
read |
Single compressed files (.gz .xz .bz2 .zst .br) |
read |
Packages (.deb .rpm .a .ar .cpio) |
read |
.7z .rar .cab .iso |
read |
.asar (Electron bundles) |
read |
| Encrypted ZIP entries (WinZip AES, ZipCrypto) |
read, asks for the password |
Nested archives (a .jar in a .war, data.tar.zst in a .deb) |
read + write¹ |
| Preview: text (Monaco), images, PDF |
in the tab |
.msi .dmg .AppImage (squashfs) |
not implemented |
Names that are one of the above under a different extension are routed too —
.unitypackage and .crate are gzipped tarballs, .gem is a tar, and
.msix/.appx/.aab/.love/.xlsm and friends are ZIPs.
¹ Writing works wherever the whole chain is ZIP. Anything else is read-only:
rewriting a .tar.xz means recompressing the entire archive on every save,
which is not a reasonable thing to do on Ctrl+S.
Saving rewrites the whole archive — that is what ZIP costs. The replacement is
atomic, compression method, mtime and the executable bit survive, and writes
against one archive are serialised. Archives with encrypted entries are
refused rather than half-written.
Layout
src/
archive/ Format-agnostic core. Nothing here imports vscode.
types.ts ArchiveBackend — the one interface a format implements
detect.ts Magic bytes and extension mapping
registry.ts Format → backend, resolved lazily
archiveIndex.ts Directory index, built once per open
mutations.ts Plans what a write changes, before any bytes move
zip/ yauzl reader, yazl writer
streaming/ Blob (random access over RAM or a spill file) + BlobBackend
tar/ 512-byte header indexer, GNU and PAX extensions
compress/ gzip/brotli/zstd via Node zlib, xz and bzip2 via libraries
ar/ cpio/ rpm/ Package containers, each a header parser over a Blob
libarchive/ 7z, RAR, CAB and ISO through one wasm build
fs/ The zipfs: file system
archiveUri.ts URI scheme with a nesting chain
archiveSessionPool.ts Shared, ref-counted open archives
archiveFileSystemProvider.ts
editor/ The custom editor tab
webview/ Tree + preview UI (bundled to media/webview.js)
monacoEditor.ts Monaco, bundled without web workers
pdfPreview.ts pdf.js, likewise without a worker
shared/ Message contract between host and webview
test/ Runs inside a real VS Code instance
media/
studio-zip.css Hand-written, tracked
webview.js/.css Build output, generated
codicons/ Copied from node_modules at build time
pdfjs/ Likewise: pdf.js CMaps, fonts and wasm decoders
Development
npm install
npm run compile # typecheck + bundle
npm run watch # or press F5, which runs this as the build task
npm test # downloads a VS Code build into .vscode-test/
F5 launches an Extension Development Host with the extension loaded. Open any
.zip there to see the tab.
Packaging and local install on Code - OSS:
npm run publish
code --install-extension publish/studio-zip-4.0.0.vsix
License
Proprietary, all rights reserved. See the LICENSE file for the terms of use. Third-party components and their
licenses are listed in THIRD_PARTY_NOTICES.md.