Skip to content

refactor: replace tar-fs, tar, and tar-stream with modern-tar#1486

Draft
gu-stav wants to merge 1 commit into
mainfrom
replace-tar-fs-with-modern-tar
Draft

refactor: replace tar-fs, tar, and tar-stream with modern-tar#1486
gu-stav wants to merge 1 commit into
mainfrom
replace-tar-fs-with-modern-tar

Conversation

@gu-stav

@gu-stav gu-stav commented Jul 13, 2026

Copy link
Copy Markdown
Member

Description

tar-fs, tar (node-tar), and tar-stream together carry ~30 transitive packages (~10 MB installed: streamx, bare-fs, bare-path, minipass, minizlib, ...) for three jobs: pack a directory into a tar stream, extract a tarball to disk, and stream tar entries. modern-tar does all three with zero dependencies and ships its own types, so @types/tar-fs and @types/tar-stream go too.

Before (tar-fs + tar + tar-stream + @types/*) After (modern-tar)
Direct dependencies 5 1
Transitive dependencies 22 0
Installed size ~6.8 MB 0.08 MB
node_modules on disk 10.5 MB 0.1 MB
Cold install 0.75 s 0.38 s
Warm install 0.30 s 0.24 s

Installed size is measured from the lockfile as the deduplicated union of the removed packages' dependency closures (sizes from disk, @types/node excluded since it stays regardless). The install benchmark uses an isolated fixture project containing only these dependencies: pnpm 10.34, median of 3 runs, cold = empty store and cache, warm = populated store, node_modules wiped between runs (Apple Silicon; deltas will be diluted inside a full @sanity/cli install).

Note: tar and tar-stream remain in the lockfile as transitive deps of @sanity/export and @sanity/runtime-cli; they're no longer direct dependencies.

What to review

The behavioral-parity claims. Both extraction paths were differentially tested against the old implementations on identical fixtures:

  • Remote-template extraction: byte-identical trees (content, permissions, symlinks) for both the whole-repo case and the filePath subtree case, including .github exclusion and prefix-sharing sibling dirs.
  • ndjson extraction: identical output for plain ndjson, gzipped ndjson, and tar.gz; identical error for a tarball without ndjson. On plain uncompressed tar the old code crashed with an uncaught AbortError during stream cleanup — the new code extracts correctly (latent bug, path was untested).
  • Deploy tarballs keep the <basename>/... top-level layout the service expects (verified with bsdtar).

Testing

Existing unit and integration tests updated to mock modern-tar/fs instead of tar-fs; deploy (88), extract-ndjson, and init template tests pass.

Notes for release

Replace tar-fs, tar, and tar-stream with the dependency-free modern-tar for deploy, backup, media-import, dataset-import, and template tarball handling

@gu-stav

gu-stav commented Jul 13, 2026

Copy link
Copy Markdown
Member Author

This change is part of the following stack:

Change managed by git-spice.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Stats — @sanity/cli

Compared against main (d388f763)

@sanity/cli

Metric Value vs main (d388f76)
Internal (raw) 2.2 KB -
Internal (gzip) 838 B -
Bundled (raw) 11.16 MB -
Bundled (gzip) 2.10 MB -
Import time 910ms +3ms, +0.3%

bin:sanity

Metric Value vs main (d388f76)
Internal (raw) 782 B -
Internal (gzip) 423 B -
Bundled (raw) 9.87 MB -
Bundled (gzip) 1.78 MB -
Import time 2.35s +78ms, +3.4%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-core

Compared against main (d388f763)

Metric Value vs main (d388f76)
Internal (raw) 108.1 KB -
Internal (gzip) 27.0 KB -
Bundled (raw) 21.72 MB -
Bundled (gzip) 3.46 MB -
Import time 800ms -1ms, -0.1%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — create-sanity

Compared against main (d388f763)

Metric Value vs main (d388f76)
Internal (raw) 908 B -
Internal (gzip) 483 B -
Bundled (raw) 931 B -
Bundled (gzip) 491 B -
Import time ❌ ChildProcess denied: node -
Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@socket-security

socket-security Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​modern-tar@​0.7.610010010088100

View full report

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Coverage Delta

File Statements
packages/@sanity/cli/src/actions/backup/archiveDir.ts 71.4% (±0%)
packages/@sanity/cli/src/actions/deploy/deployApp.ts 10.3% (±0%)
packages/@sanity/cli/src/actions/init/remoteTemplate.ts 3.8% (- 0.1%)
packages/@sanity/workbench-cli/src/actions/deploy/deployConfig.ts 100.0% (±0%)
packages/@sanity/workbench-cli/src/actions/deploy/deployWorkbenchApp.ts 93.3% (±0%)

Comparing 5 changed files against main @ d388f763cbacda2cdb42f8d547a80c95830f425d

Overall Coverage

Metric Coverage
Statements 74.6% (- 0.0%)
Branches 64.4% (±0%)
Functions 69.5% (- 0.0%)
Lines 75.1% (- 0.0%)

@gu-stav gu-stav changed the title refactor: replace tar-fs with modern-tar refactor: replace tar-fs, tar, and tar-stream with modern-tar Jul 13, 2026
tar-fs, node-tar, and tar-stream together carry ~30 transitive packages
(streamx, bare-fs, minipass, minizlib, ...) for directory packing, tarball
extraction, and entry streaming. modern-tar covers all three with zero
dependencies and ships its own types, so @types/tar-fs and
@types/tar-stream go too.
@gu-stav
gu-stav force-pushed the replace-tar-fs-with-modern-tar branch from 7d8aae5 to 89765d1 Compare July 13, 2026 09:18
gu-stav added a commit that referenced this pull request Jul 13, 2026
The @module-federation/vite 1.16.14 bump (#1484) left the lockfile with
two copies of runtime/runtime-core/sdk/error-codes: 2.7.0 for mf-vite
and a stale 2.6.0 still resolved for @sanity/workbench's ^2.6.0 range.
Any branch that touches dependencies picks up this dedupe as unrelated
churn (see #1486). Landing it separately keeps those diffs clean.
gu-stav added a commit that referenced this pull request Jul 13, 2026
The @module-federation/vite 1.16.14 bump (#1484) left the lockfile with
two copies of runtime/runtime-core/sdk/error-codes: 2.7.0 for mf-vite
and a stale 2.6.0 still resolved for @sanity/workbench's ^2.6.0 range.
Any branch that touches dependencies picks up this dedupe as unrelated
churn (see #1486). Landing it separately keeps those diffs clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant