Skip to content

CLI: Switch over to modern-tar#32763

Merged
ndelangen merged 5 commits into
storybookjs:nextfrom
ayuhito:perf/modern-tar
Oct 26, 2025
Merged

CLI: Switch over to modern-tar#32763
ndelangen merged 5 commits into
storybookjs:nextfrom
ayuhito:perf/modern-tar

Conversation

@ayuhito
Copy link
Copy Markdown
Contributor

@ayuhito ayuhito commented Oct 18, 2025

Related: #29038 cc @JReinhold

What I did

If there is any appetite to reduce the dependency count, I'd love to suggest using modern-tar that solely relies on native APIs to cut down the dependency tree and reduce the bundle size by around ~2MB. It also replaces gunzip-maybe with just node:zlib.

This has a very small surface area which makes me believe this is a safe migration to undertake. Please let me know if there any concerns! We also recently switched @bluwy/giget-core which is a very similar mechanism for create-astro!

image

Ref: https://npmgraph.js.org/?q=storybook#deps=devDependencies&select=exact%3A%40ndelangen%2Fget-tarball%403.0.9

Checklist for Contributors

Testing

This code should only affect the create-storybook package and many test helpers.

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests (I think so?)

Manual testing

  • Ran create-storybook/dist/bin/index.js directly.
  • Ran yarn task --task sandbox --start-from auto --template react-vite/default-ts

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Depending on the discretion of the Storybook team, I think a canary release to properly test npx create-storybook would be the most safe approach to testing this E2E since npx behaves slightly different than running the .js file directly. But this is an optional suggestion since the scope of this PR is very small.

Summary by CodeRabbit

  • Chores
    • Updated tooling for tarball handling: replaced dev dependency and moved to a streaming-based extraction pipeline for improved resource usage and reliability during package operations.
    • No changes to public APIs or end-user runtime behavior; functionality remains unchanged.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 18, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • code/yarn.lock is excluded by !**/yarn.lock, !**/*.lock

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

The pull request replaces a tarball download helper with a streaming-based extraction pipeline: removes the @ndelangen/get-tarball devDependency, adds modern-tar, and updates tarball extraction to fetch the tarball, validate the response, pipe through gunzip, and call unpackTar.

Changes

Cohort / File(s) Summary
Dependency Update
code/core/package.json
Removed @ndelangen/get-tarball from devDependencies; added modern-tar to devDependencies.
Streaming Tarball Extraction
code/core/src/cli/dirs.ts
Replaced downloadTarball call with a streaming pipeline: fetch(tarballUrl), validate response and body, pipe response body → gunzip → unpackTar. Removed import/use of the previous download helper and added explicit fetch/error handling.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as CLI code
    participant Fetch as Fetch API
    participant Stream as Gunzip/Streams
    participant Tar as modern-tar.unpackTar

    rect rgb(230,240,255)
    Note over CLI,Fetch: Streaming extraction flow
    CLI->>Fetch: fetch(tarballUrl)
    Fetch-->>CLI: Response
    alt response missing or !ok
        CLI-->>CLI: throw Error
    else ok
        CLI->>Stream: response.body (ReadableStream)
        Stream->>Tar: piped/gunzip stream
        Tar-->>CLI: extracted files
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
code/core/src/cli/dirs.ts (2)

33-36: Enhance error message with HTTP status details.

The error handling checks the response but doesn't include the HTTP status code or reason, making debugging more difficult when tarball downloads fail.

Apply this diff to include the status in the error message:

 const response = await fetch(url);
 if (!response.ok || !response.body) {
-  throw new Error(`Failed to download tarball from ${url}`);
+  throw new Error(`Failed to download tarball from ${url}: ${response.status} ${response.statusText}`);
 }

39-43: Consider using the strip option to eliminate the extra directory join.

The tarball extracts with a package/ root directory (as evidenced by line 45's join), but modern-tar's unpackTar supports a strip option that removes leading directory components during extraction.

Apply this diff to simplify the extraction:

 await pipeline(
   Readable.fromWeb(response.body as ReadableStream<Uint8Array>),
   createGunzip(),
-  unpackTar(tempDirectory)
+  unpackTar(tempDirectory, { strip: 1 })
 );

Then update line 45:

-return join(tempDirectory, 'package');
+return tempDirectory;

Based on learnings

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f47e861 and a488781.

⛔ Files ignored due to path filters (1)
  • code/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (2)
  • code/core/package.json (1 hunks)
  • code/core/src/cli/dirs.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,json,html,ts,tsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,json,html,ts,tsx,mjs}: Run Prettier formatting on changed files before committing
Run ESLint on changed files and fix all errors/warnings before committing (use yarn lint:js:cmd <file>)

Files:

  • code/core/package.json
  • code/core/src/cli/dirs.ts
**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Export functions from modules when they need to be unit-tested

Files:

  • code/core/src/cli/dirs.ts
code/**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

In application code, use Storybook loggers instead of console.* (client code: storybook/internal/client-logger; server code: storybook/internal/node-logger)

Files:

  • code/core/src/cli/dirs.ts
{code/**,scripts/**}/**/*.{ts,tsx,js,jsx,mjs}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not use console.log, console.warn, or console.error directly unless in isolated files where importing loggers would significantly increase bundle size

Files:

  • code/core/src/cli/dirs.ts
🔇 Additional comments (3)
code/core/src/cli/dirs.ts (2)

2-5: LGTM: Appropriate imports for streaming-based extraction.

The imports correctly set up the streaming pipeline: Node streams for interop, zlib for decompression, and modern-tar for extraction.

Also applies to: 12-12


39-43: No issues found. The directory is already created before unpackTar is called.

The tempDirectory on line 19 is obtained from await temporaryDirectory(), which explicitly creates the directory via mkdirSync() in its implementation (code/core/src/common/utils/cli.ts:21) before returning it. The created directory is then passed to unpackTar on line 42, so the concern about missing directory creation is already addressed.

Likely an incorrect or invalid review comment.

code/core/package.json (1)

292-292: The original review comment is incorrect.

The npm registry verification confirms that version 0.5.4 of modern-tar exists and is the current latest release. The package specification "modern-tar": "^0.5.4" is valid and will install successfully. The earlier learnings stating the latest stable was 0.4.0 were inaccurate.

Likely an incorrect or invalid review comment.

@vanessayuenn vanessayuenn added ci:normal maintenance User-facing maintenance tasks cli labels Oct 20, 2025
@vanessayuenn vanessayuenn changed the title perf(cli): switch over to modern-tar CLI: switch over to modern-tar Oct 20, 2025
@vanessayuenn vanessayuenn changed the title CLI: switch over to modern-tar CLI: Switch over to modern-tar Oct 20, 2025
@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented Oct 20, 2025

Package Benchmarks

Commit: 6f2a421, ran on 24 October 2025 at 13:43:27 UTC

The following packages have significant changes to their size or dependencies:

storybook

Before After Difference
Dependency count 43 43 0
Self size 24.84 MB 24.15 MB 🎉 -690 KB 🎉
Dependency size 17.36 MB 17.36 MB 0 B
Bundle Size Analyzer Link Link

@storybook/cli

Before After Difference
Dependency count 187 187 0
Self size 928 KB 928 KB 0 B
Dependency size 74.79 MB 74.10 MB 🎉 -690 KB 🎉
Bundle Size Analyzer Link Link

@storybook/codemod

Before After Difference
Dependency count 169 169 0
Self size 35 KB 35 KB 0 B
Dependency size 71.22 MB 70.53 MB 🎉 -690 KB 🎉
Bundle Size Analyzer Link Link

create-storybook

Before After Difference
Dependency count 44 44 0
Self size 1.55 MB 1.55 MB 🎉 -60 B 🎉
Dependency size 42.20 MB 41.51 MB 🎉 -690 KB 🎉
Bundle Size Analyzer node node

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Oct 22, 2025

View your CI Pipeline Execution ↗ for commit 6f2a421

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 45s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-24 13:53:12 UTC

@ayuhito
Copy link
Copy Markdown
Contributor Author

ayuhito commented Oct 22, 2025

=> Failed to build the preview
[vite-plugin-storybook-nextjs-swc]

Caused by:
unknown field disablePageConfig at line 1 column 7538
file: ./.storybook/preview.ts
Error:

Caused by:
unknown field disablePageConfig at line 1 column 7538

Latest merge commit triggered these failures. Seems to be unrelated to this maybe?

@ndelangen
Copy link
Copy Markdown
Member

yes, unrelated, we're working on it!

Copy link
Copy Markdown
Contributor

@JReinhold JReinhold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it! 🎉

@ndelangen ndelangen merged commit a423349 into storybookjs:next Oct 26, 2025
54 checks passed
@github-actions github-actions Bot mentioned this pull request Oct 26, 2025
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:normal cli maintenance User-facing maintenance tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants