[Feature] report file size for ui extensions on build and dev#7205
[Feature] report file size for ui extensions on build and dev#7205robin-drexler wants to merge 1 commit intomainfrom
Conversation
abf63b1 to
b75d5eb
Compare
47bd3d6 to
675a667
Compare
675a667 to
25e7d56
Compare
There was a problem hiding this comment.
Pull request overview
Adds reporting of UI extension bundle sizes (original + compressed) to build and dev workflows to help developers understand proximity to Shopify’s 64kb compressed limit.
Changes:
- Append original and deflated-compressed bundle size information to UI extension build output (
app build). - Append bundle size information after successful rebuilds during
app devfor esbuild-managed extensions. - Introduce
bundle-sizeutility + unit tests, and add a changeset for@shopify/app.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/app/src/cli/services/dev/app-events/app-event-watcher.ts | Adds bundle size suffix to “Build successful” messages on rebuild during dev. |
| packages/app/src/cli/services/build/extension.ts | Adds bundle size suffix to UI extension “successfully built” output. |
| packages/app/src/cli/services/build/bundle-size.ts | New utility to compute raw + deflate-compressed sizes and format as a suffix. |
| packages/app/src/cli/services/build/bundle-size.test.ts | Adds unit tests for raw/compressed sizing and formatting behavior. |
| .changeset/tricky-results-roll.md | Declares a minor release for @shopify/app to ship the feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const [rawBytes, content] = await Promise.all([fileSize(filePath), readFile(filePath)]) | ||
| const compressed = await deflateAsync(Buffer.from(content)) |
There was a problem hiding this comment.
getBundleSize calls readFile(filePath) with the default {encoding: 'utf8'} and then wraps it in Buffer.from(content). For accurate byte-level compression (and to keep this utility safe for non-text/binary bundles), read the file as a Buffer explicitly (e.g., pass an options object that yields a Buffer) and deflate that buffer directly.
| const [rawBytes, content] = await Promise.all([fileSize(filePath), readFile(filePath)]) | |
| const compressed = await deflateAsync(Buffer.from(content)) | |
| const [rawBytes, content] = await Promise.all([fileSize(filePath), readFile(filePath, {encoding: null})]) | |
| const compressed = await deflateAsync(content) |
f1e1e0d to
d8e7d01
Compare
d8e7d01 to
dac58c5
Compare
| * Uses the same compression algorithm as the Shopify backend (Zlib::Deflate.deflate). | ||
| */ | ||
| export async function getBundleSize(filePath: string) { | ||
| const [rawBytes, content] = await Promise.all([fileSize(filePath), readFile(filePath)]) |
There was a problem hiding this comment.
does this need to wrap in a try/catch in case we exhaust the buffer? i'm unfamiliar with how we run the build and compression here
There was a problem hiding this comment.
the only actual usage of this already wraps it in a try / catch. should be good for now? https://github.com/Shopify/cli/pull/7205/changes/BASE..dac58c54bb75c3790b3fcdd8d7f63424aa4d135e
ryancbahan
left a comment
There was a problem hiding this comment.
seems reasonable to me. left a q about the read from buffer on the file, but i'm low context there

WHY are these changes introduced?
With 2025-10 version, we introduced strict 64kb limits for ui extensions. It's been difficult for developers to analyze their file sizes. We've already shipped a change that emits esbuild metafiles and allows developers to find out what's in their bundles.
The issue is that those sizes are being reported uncompressed. And while this is useful to sport large libraries etc, it doesn't give you the full picture and is confusing to some folks.
WHAT is this pull request doing?
This PR now shows extension file uncompressed and compressed sizes when running
app buildorapp devmaking it easier to spot when an extension is getting too big.We are not (yet) adding any size limit warnings. That information is currently afaik only available in the backend when you try to upload an extension. We can look into this at a later point. Just adding the information itself imo is already pretty useful.
build
dev
rebuild

How to test your changes?
pnpm shopify app build --path=/path/to/your/appinside the cli repoPost-release steps
Measuring impact
How do we know this change was effective? Please choose one:
Checklist