fix(cloudflare): stop bundling @vercel/og when it is unused#1221
Merged
vicb merged 1 commit intoopennextjs:mainfrom Apr 22, 2026
Merged
fix(cloudflare): stop bundling @vercel/og when it is unused#1221vicb merged 1 commit intoopennextjs:mainfrom
vicb merged 1 commit intoopennextjs:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 8db8d43 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
2 tasks
vicb
approved these changes
Apr 22, 2026
Contributor
vicb
left a comment
There was a problem hiding this comment.
Great investigation!
LGTM, thank you so much for the fix!
commit: |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1220 (and the original #1211).
Problem
Next.js's internal
externalImporthelper emits a dynamicinto the app handler even for apps that never use
next/og(ImageResponse,opengraph-image,twitter-image, …). Today, whenpatchVercelOgLibrarydecidesuseOg === false,bundle-server.tsmarks that module asexternal:esbuild honors
externaland leaves theimport("…@vercel/og/index.edge.js")call site intact. Wrangler then resolves that external module againstnode_modulesand bundles:@vercel/ogedge bundle (~800 KiB uncompressed / ~260 KiB gzip)resvg.wasm(~1.4 MiB)…even though the code path is unreachable. For CSR-heavy apps that never use OG images this single dynamic import pushes the Worker over the 3 MiB free-tier gzip limit.
Reproduced on a real Next 16 app with
@opennextjs/[email protected]and1.19.2:wrangler deploy --dry-runuseOg=false, external)14098.57 KiB / gzip 3119.42 KiB❌11875.51 KiB / gzip 2415.74 KiB✅(The same savings were previously achievable only via a post-build regex script that rewrote the emitted handler.)
Fix
When
useOg === false, alias the edge entry to the existingthrow.jsshim instead of marking it external:The unreachable dynamic import now resolves to a tiny
throw "OpenNext shim"module, and Wrangler no longer drags the real@vercel/oglibrary +resvg.wasminto the Worker bundle. If the dynamic import is ever executed at runtime (which would indicate a bug inpatchVercelOgLibrary'suseOgdetection), the shim throws immediately — the same failure mode users already get from@ampproject/toolbox-optimizerand other shimmed modules, rather than a silent runtime mismatch.When
useOg === truethe behavior is unchanged: the real edge build is copied and patched bypatchVercelOgLibraryas before.Why not a config flag?
The original issue proposed an opt-in flag (
cloudflare: { disableVercelOg: true }), but the adapter already computes the exact signal it needs (useOg), so this can be done safely with no new config surface.Validation
pnpm --filter cloudflare test— 31 files / 317 tests pass.pnpm code:checks(prettier + eslint + tsc) — clean.app/router, nonext/og) against this fork, confirmedhandler.mjsno longer containsnext/dist/compiled/@vercel/og/index.edge.jsandwrangler deploy --dry-runsize dropped as shown above.Changeset
Included as a
patchbump under.changeset/drop-unused-vercel-og.md.