How to Fix: Satori version outdated in @vercel/og + next/og
@vercel/og and next/og can silently pull in an older Satori version than your project expects, which leads to rendering differences, missing features, font/layout inconsistencies, or failures that are hard to debug because the issue looks like an application bug when it is actually a dependency-resolution problem.
Table of Contents
What Is Happening
This issue appears when @vercel/og and next/og depend on a bundled or pinned version of Satori that lags behind the latest release published on npm. If your Open Graph image generation code relies on behavior introduced in a newer Satori release, the runtime still executes the older implementation shipped through the framework package.
In practice, that means you may see:
- Different rendering output between standalone Satori usage and next/og
- CSS support mismatches
- Font rendering bugs that were already fixed upstream
- Unexpected behavior in edge runtime image generation
- Confusion when checking npm and seeing a newer package version that is not actually being used
Understanding the Root Cause
The core problem is transitive dependency versioning. Your app imports APIs from @vercel/og or next/og, but those packages internally rely on Satori. Even if a newer Satori version exists on npm, your application does not automatically use it unless the parent package updates its dependency range and republishes.
There are usually three technical reasons this happens:
- Pinned dependency versions: the package may reference a specific Satori version instead of a broad semver range.
- Framework release cadence: Next.js or Vercel packages may update less frequently than Satori itself.
- Bundled runtime behavior: in some cases, the effective implementation is determined by the framework build/runtime layer, so installing a newer top-level Satori package does not override what next/og actually executes.
This is why adding satori@latest to your project often does not fix the issue. Your code path still flows through ImageResponse in next/og or @vercel/og, and that package decides which Satori version is used internally.
Step-by-Step Solution
The safest fix is to confirm the installed dependency tree, upgrade the parent package if a newer release exists, and use package-manager overrides only when you have verified compatibility.
1. Inspect the resolved Satori version
Check which version is actually installed in your dependency graph.
npm ls satori @vercel/og next
Or with pnpm:
pnpm why satori
Or with Yarn:
yarn why satori
This shows whether @vercel/og or next is locking your project to an older Satori release.
2. Upgrade Next.js and @vercel/og first
Before forcing anything, install the latest compatible versions of the parent packages.
npm install next@latest @vercel/og@latest
If your project only uses next/og, updating next may be enough because next/og is distributed through Next.js.
3. Verify whether the fix already landed upstream
Check the release notes or changelog for Next.js and Vercel OG-related packages. If maintainers have already bumped Satori in a newer release, upgrading is the cleanest solution.
4. If necessary, force the version with overrides or resolutions
If the upstream package has not yet been updated and you have validated that the newer Satori version works, use your package manager’s override feature.
npm:
{
"overrides": {
"satori": "latest"
}
}
pnpm:
{
"pnpm": {
"overrides": {
"satori": "latest"
}
}
}
Yarn:
{
"resolutions": {
"satori": "latest"
}
}
Then reinstall dependencies:
rm -rf node_modules package-lock.json pnpm-lock.yaml yarn.lock
npm install
Use the matching cleanup command for your package manager and lockfile strategy.
5. Re-test your OG image route
For example, in a Next.js route handler:
import { ImageResponse } from 'next/og'
export const runtime = 'edge'
export async function GET() {
return new ImageResponse(
(
<div
style={{
display: 'flex',
height: '100%',
width: '100%',
alignItems: 'center',
justifyContent: 'center',
fontSize: 48,
background: 'white',
}}
>
Satori version check
</div>
),
{
width: 1200,
height: 630,
}
)
}
After reinstalling, confirm the dependency tree again:
npm ls satori
If the version is still unchanged, the package may be bundling or otherwise constraining resolution in a way overrides cannot affect cleanly.
6. If overrides do not work, use a temporary fallback strategy
When the framework package is not compatible with the newer Satori release, you have two realistic options:
- Wait for an upstream patch from Next.js or Vercel
- Implement a custom image pipeline outside
next/ogif you urgently need a newer Satori capability
That fallback is less convenient, but it avoids patching framework internals in production.
7. Track the upstream issue and lock your app deliberately
Once you identify the working combination, pin versions explicitly in your project until the ecosystem catches up. This prevents future installs from drifting into another mismatched state.
{
"dependencies": {
"next": "14.2.0",
"@vercel/og": "0.6.2"
}
}
Use the actual versions validated in your environment rather than copying example numbers blindly.
Common Edge Cases
1. Installing satori directly changes nothing
This is the most common misunderstanding. A top-level dependency does not guarantee that next/og will use it. The internal dependency path still controls the runtime behavior.
2. Lockfile caching hides the real result
If you add overrides but keep an old lockfile or cached install artifacts, your project may continue resolving the previous version. Always remove install artifacts and regenerate the lockfile when testing dependency fixes.
3. Edge runtime differences
ImageResponse often runs in the Edge Runtime. A newer Satori release may behave differently there than in local Node.js scripts, especially around fonts, fetch access, and supported APIs.
4. Monorepo hoisting confusion
In a monorepo, one workspace may appear to have the correct Satori version while another route actually resolves a different copy due to hoisting or workspace-level overrides. Check the dependency tree from the exact app package that serves the OG route.
5. Incompatible forced upgrades
Forcing a newer Satori version can fix one rendering issue but introduce another if @vercel/og expects older internal behavior. Overrides are a tactical workaround, not always a permanent solution.
6. Mismatch between local and deployment environments
Your local machine may resolve one version while your deployment platform uses a cached lockfile or different install mode. Confirm the built dependency tree in CI and production, not just locally.
FAQ
Why does npm install satori@latest not update the version used by next/og?
Because next/og uses Satori as an internal dependency. Your direct dependency does not automatically replace the version resolved by the parent package unless package-manager overrides or upstream updates allow it.
Is this a bug in Satori or in Next.js/@vercel/og?
Usually it is not a rendering bug in your code. It is primarily a dependency update lag in @vercel/og or next/og, where the framework package has not yet adopted the newer Satori release.
What is the best long-term fix?
The best long-term fix is to upgrade to a framework release where the maintainers have officially bumped and tested the newer Satori version. Use overrides only as a temporary, verified workaround.
If you are debugging this issue in a real project, the most reliable process is: inspect resolved versions, upgrade parent packages, test overrides carefully, and avoid assuming npm’s latest tag reflects the version actually used by next/og.