Is your feature request related to a problem?
When an app does not use next/og (ImageResponse, opengraph-image, etc.), the built .open-next/server-functions/default/handler.mjs still contains a dynamic import:
import("next/dist/compiled/@vercel/og/index.edge.js")
This comes from Next.js's internal externalImport helper and survives the existing patchVercelOgImport / patchVercelOgFallbackFont AST rules in packages/cloudflare/src/cli/build/patches/ast/vercel-og.ts, because those rules only rewrite the module specifier (index.node.js → index.edge.js); they don't strip the call site when @vercel/og is never actually reached at runtime.
Wrangler treats that dynamic import as a real module graph entry and pulls in:
@vercel/og edge bundle (~800 KiB uncompressed / ~260 KiB gzip)
resvg.wasm (~1.4 MiB)
For a CSR-heavy app that doesn't use OG images at all, this single dynamic import pushes the Worker over the Cloudflare free-tier 3 MiB limit (observed ~3.8 MiB vs ~1.6 MiB after rewrite).
Describe the solution you'd like
Add an opt-in flag to @opennextjs/cloudflare, e.g.:
// open-next.config.ts
export default defineCloudflareConfig({
cloudflare: { disableVercelOg: true },
});
When enabled, an AST rule under packages/cloudflare/src/cli/build/patches/ast/ rewrites the remaining import("next/dist/compiled/@vercel/og/index.edge.js") call sites to a rejected Promise (or a no-op stub), so Wrangler no longer bundles the @vercel/og edge module and resvg.wasm.
This keeps the default behavior safe and gives free-tier users a supported escape hatch without a post-build regex script.
Happy to send a PR (config flag + AST rule) if maintainers are open to it.
Describe alternatives you've considered
-
Auto-detect and stub. Scan user sources for next/og / ImageResponse / opengraph-image / twitter-image usage and, when none are found, automatically rewrite the call site. Safer defaults but more moving parts and edge cases.
-
Post-build regex patch (current workaround). We run a small script before wrangler deploy:
source = source.replace(
/import\("next\/dist\/compiled\/@vercel\/og\/index\.edge\.js"\)/g,
'Promise.reject(new Error("@vercel/og disabled"))',
);
After this patch our Worker is ~1.6 MiB instead of ~3.8 MiB and everything else (ProForm, admin UI, D1, R2, KV, Vectorize) works unchanged. But it's fragile — it depends on the exact emitted string and has to live in every project that hits the 3 MiB limit.
-
Do nothing / upgrade to paid plan. Not acceptable for free-tier / hobby projects that never use OG images.
@opennextjs/cloudflare version
1.19.2
Additional context
Before submitting
Is your feature request related to a problem?
When an app does not use
next/og(ImageResponse,opengraph-image, etc.), the built.open-next/server-functions/default/handler.mjsstill contains a dynamic import:This comes from Next.js's internal
externalImporthelper and survives the existingpatchVercelOgImport/patchVercelOgFallbackFontAST rules inpackages/cloudflare/src/cli/build/patches/ast/vercel-og.ts, because those rules only rewrite the module specifier (index.node.js→index.edge.js); they don't strip the call site when@vercel/ogis never actually reached at runtime.Wrangler treats that dynamic import as a real module graph entry and pulls in:
@vercel/ogedge bundle (~800 KiB uncompressed / ~260 KiB gzip)resvg.wasm(~1.4 MiB)For a CSR-heavy app that doesn't use OG images at all, this single dynamic import pushes the Worker over the Cloudflare free-tier 3 MiB limit (observed ~3.8 MiB vs ~1.6 MiB after rewrite).
Describe the solution you'd like
Add an opt-in flag to
@opennextjs/cloudflare, e.g.:When enabled, an AST rule under
packages/cloudflare/src/cli/build/patches/ast/rewrites the remainingimport("next/dist/compiled/@vercel/og/index.edge.js")call sites to a rejected Promise (or a no-op stub), so Wrangler no longer bundles the@vercel/ogedge module andresvg.wasm.This keeps the default behavior safe and gives free-tier users a supported escape hatch without a post-build regex script.
Happy to send a PR (config flag + AST rule) if maintainers are open to it.
Describe alternatives you've considered
Auto-detect and stub. Scan user sources for
next/og/ImageResponse/opengraph-image/twitter-imageusage and, when none are found, automatically rewrite the call site. Safer defaults but more moving parts and edge cases.Post-build regex patch (current workaround). We run a small script before
wrangler deploy:After this patch our Worker is ~1.6 MiB instead of ~3.8 MiB and everything else (ProForm, admin UI, D1, R2, KV, Vectorize) works unchanged. But it's fragile — it depends on the exact emitted string and has to live in every project that hits the 3 MiB limit.
Do nothing / upgrade to paid plan. Not acceptable for free-tier / hobby projects that never use OG images.
@opennextjs/cloudflare version
1.19.2
Additional context
16.1.14.83.0@opennextjs/cloudflarethat does not importnext/og. Compare.open-next/server-functions/default/handler.mjsandwrangler deploy --dry-runsize with and without the regex rewrite above.Before submitting