Next.js Image Optimization Broke Our Client Build: The Sharp Fix
When our client's Next.js build passed but images stayed unoptimized in production, we traced it to a missing sharp binary in the standalone output. Here is the explicit declaration and file tracing fix we now bake into every project.
Author
The Incident: Image Optimization Silently Failed in Production
Last month our team shipped a marketing site for a Pune-based SaaS startup using Next.js 15 with output: "standalone". The build passed in CI, the container started, and the homepage loaded. But every <Image> tag served the original .png and .jpg bytes instead of optimized .webp variants. No errors in the logs. No failed builds. Just silently bloated payloads.
The Client Setup and Build Pipeline
The project lives at /apps/marketing inside our monorepo. We build with:
cd /apps/marketing
NODE_OPTIONS=--max-old-space-size=4096 npm run build
Then we copy .next/standalone into a slim node:20-alpine Docker image and run node server.js. The Dockerfile uses multi-stage builds, so only the final stage ships to production.
The Silent Failure: No Errors, Just Unoptimized Images
Next.js logs showed nothing. Chrome DevTools Network tab showed content-type: image/png for assets that should have been image/webp. The /_next/image endpoint returned 200 but with full-size bytes. This is the exact behavior described in the Next.js docs under "Sharp Missing In Production" Sharp Missing In Production.
What We Tried and What Failed
First Attempt: Installing sharp as a Dev Dependency
We added sharp to devDependencies thinking it would be picked up during build:
"devDependencies": {
"sharp": "^0.34.2"
}
It did not work. The --omit=dev flag in our Docker production stage stripped it out, and even locally the standalone output did not include the native binary.
Second Attempt: Relying on Next.js Optional Dependency Resolution
Next.js 14.2+ pulls sharp in as an optional dependency automatically Fix: Next.js Image Optimization Errors. We assumed this would just work. It did not. Our CI runner uses --omit=optional to trim install size, which stripped sharp before the build even started.
Third Attempt: Copying node_modules Between Architectures
We tried copying node_modules from our macOS build machine into the Linux container. Sharp installed fine locally but failed at runtime with:
Error: Could not load the 'sharp' module using the linux-x64 runtime
The native binary was compiled for darwin-x64, not linux-x64 Next.js Image Optimization in CI.
The Working Approach: Explicit sharp Declaration and File Tracing
Adding sharp to dependencies in package.json
We moved sharp from devDependencies to dependencies so it survives production installs:
"dependencies": {
"next": "^15.3.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"sharp": "^0.34.2"
}
Configuring outputFileTracingIncludes in next.config.js
The standalone output does not automatically trace native binaries like sharp. We added explicit includes:
// next.config.js
const nextConfig = {
output: "standalone",
outputFileTracingIncludes: {
"**/*": [
"node_modules/sharp/**/*",
"node_modules/@img/**/*"
]
}
};
module.exports = nextConfig;
This ensures the prebuilt platform binaries ship with the standalone server Fix image optimization in NextJS standalone.
Verifying sharp Loads at Runtime with require('sharp')
Before deploying, we run a quick check inside the container:
docker run --rm our-marketing-app node -e "require('sharp'); console.log('sharp OK')"
If this throws Cannot find module 'sharp', the binary is missing and we rebuild.
Pitfalls We Would Warn an Intern About
The --omit=optional Trap in Docker and CI
Any CI pipeline or Docker stage using --omit=optional will strip sharp. Check your install commands:
# Bad
npm ci --omit=optional
# Good
npm ci
Architecture Mismatches Between Build and Runtime
Building on macOS and deploying to Linux requires platform-specific binaries. Always install sharp on the target platform:
npm install --cpu=x64 --os=linux sharp
Silent Failures vs. Loud Errors in Image Optimization
Next.js does not throw when sharp is missing in production. It silently falls back to serving original images. This makes the bug hard to catch in staging. We now add a runtime verification step to every deployment.
What We Would Do Differently Next Time
Pin sharp Version and Test on Target Platform Early
We will pin sharp to a specific version and test the build on the target platform before merging. Version mismatches between 0.33.x and 0.34.x have caused build failures for other teams GitHub Discussion #66303.
Add Runtime Verification to Deployment Checks
Every deploy now runs:
node -e "const s = require('sharp'); console.log('sharp version:', s.versions.sharp)"
If this fails, the deployment aborts.
Consider a Custom Loader for Static Exports
For projects using output: "export", we skip the built-in optimizer entirely and use a custom loader pointing to Cloudflare Image Resizing or imgix. This avoids the sharp dependency altogether FixDevs.
The Bottom Line
Image optimization failures in Next.js are silent, sneaky, and easy to miss. The fix is simple: declare sharp as a direct dependency, configure outputFileTracingIncludes, and verify at runtime. We have added this checklist to our standard deployment playbook at Agentic Academy Labs.
Next time you see unoptimized images in production, check sharp first. It is almost always the culprit.
Sources you may cite:
- Sharp Missing In Production: https://nextjs.org/docs/messages/sharp-missing-in-production
- Next.js "Image Optimization using the default loader ... requires sharp" in CI | Latchkey Learn: https://latchkey.dev/learn/frontend-build/nextjs-image-optimization-requires-sharp-in-ci
- Fix image optimization not working in NextJS in Docker: https://ermakovich.ru/posts/2025-06-30-fix-image-optimization-nextjs-standalone-build/
- Fix: Next.js Image Optimization Errors - Invalid src, Missing Loader, or Unoptimized - FixDevs: https://fixdevs.com/blog/nextjs-image-optimization-error/
- For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended. · vercel/next.js · Discussion #66303 · GitHub: https://github.com/vercel/next.js/discussions/66303
- Next.js on K8s: Solving the 5 Most Common Production Issues: https://privatedevops.com/articles/nextjs-kubernetes-5-common-production-issues
- How to Fix 'Image Optimization' Errors in Next.js: https://oneuptime.com/blog/post/2026-01-24-nextjs-image-optimization-errors/view
- RFC: Use Sharp for image optimization if installed · vercel next.js · Discussion #27073 · GitHub: https://github.com/vercel/next.js/discussions/27073
Sources
Related reading
Enjoyed this article?
Back to Blog


