install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/next-deployment-optimization" ~/.claude/skills/intense-visions-harness-engineering-next-deployment-optimization && rm -rf "$T"
manifest:
agents/skills/claude-code/next-deployment-optimization/SKILL.mdsource content
Next.js Deployment Optimization
Reduce bundle size, split code strategically, and optimize runtime performance for production
When to Use
- Reducing JavaScript bundle size to improve Time to Interactive (TTI)
- Lazy loading heavy components (rich text editors, chart libraries, maps) that are not needed on first paint
- Analyzing which modules contribute most to bundle size
- Optimizing for Vercel, Docker, or self-hosted deployments
- Reducing cold start times for serverless functions
Instructions
- Run
withANALYZE=true next build
to identify large modules in the bundle.@next/bundle-analyzer - Use
to lazy load Client Components that are not needed for initial render.next/dynamic - Pass
to{ ssr: false }
for components that use browser-only APIs (next/dynamic
,window
,document
).navigator - Use
directly inside Server Components for code splitting withoutimport()
.next/dynamic - Move large libraries (PDF generators, Excel parsers, video processors) to Route Handlers or Server Actions to keep them off the client bundle entirely.
- Set
inexperimental.optimizePackageImports
for icon and component libraries to tree-shake unused exports.next.config.ts - Use
to self-host fonts with zero layout shift — fonts are downloaded at build time.next/font - Enable compression and set proper cache headers in your deployment infrastructure for static assets.
// next.config.ts — bundle analyzer and package optimization import type { NextConfig } from 'next'; import bundleAnalyzer from '@next/bundle-analyzer'; const withBundleAnalyzer = bundleAnalyzer({ enabled: process.env.ANALYZE === 'true', }); const config: NextConfig = { experimental: { optimizePackageImports: ['lucide-react', '@radix-ui/react-icons', 'date-fns'], }, }; export default withBundleAnalyzer(config); // app/editor/page.tsx — lazy load heavy Client Component import dynamic from 'next/dynamic'; const RichTextEditor = dynamic(() => import('@/components/rich-text-editor'), { loading: () => <p>Loading editor...</p>, ssr: false, // editor uses window APIs }); export default function EditorPage() { return <RichTextEditor />; } // app/fonts.ts — self-hosted fonts import { Inter, Fira_Code } from 'next/font/google'; export const inter = Inter({ subsets: ['latin'], variable: '--font-inter' }); export const firaCode = Fira_Code({ subsets: ['latin'], variable: '--font-fira-code' });
Details
Next.js performs automatic code splitting at the route level — each page only loads its own JavaScript. Additional optimization opportunities exist at the component and library level.
Bundle analyzer workflow: Install
@next/bundle-analyzer, add it to next.config.ts, run ANALYZE=true next build. Two treemaps open (client and server bundles). Look for unexpectedly large modules, duplicated libraries (two versions of the same package), and server-only code in the client bundle.
vs React.lazy: next/dynamic
next/dynamic wraps React.lazy and adds Next.js-specific features: ssr: false, loading components, and named export support. Use next/dynamic in Next.js projects — React.lazy works too but lacks these features.
use cases: Components that import browser APIs at module level (not just in event handlers) must use ssr: false
ssr: false. Common examples: maps (Leaflet, Mapbox), rich text editors (Quill, TipTap), WebGL renderers.
: Icon libraries like optimizePackageImports
lucide-react export hundreds of icons. Without tree-shaking, importing one icon pulls in the entire library. optimizePackageImports tells Next.js to rewrite imports to their direct module paths, enabling tree-shaking.
Standalone output: For Docker deployments, set
output: 'standalone' in next.config.ts. This produces a minimal build artifact with only the production dependencies needed, significantly reducing Docker image size.
Source
https://nextjs.org/docs/app/building-your-application/optimizing
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.