Upgrade to Next.js 15
- Updated on
New apps created with Shipixen will come with Next.js 15. If you have an existing Next.js app, you can upgrade to version 15 to take advantage of the latest features and improvements. This guide will walk you through the process of upgrading your Next.js app to version 15.
1. Update Dependencies
Many dependencies needed to be updated to support React 19.
The easiest way to update is to replace your package.json with the newest one:
{
"name": "your-package-name",
"description": "Your description",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "cross-env PORT=6006 NODE_OPTIONS='--no-warnings' next dev",
"build": "cross-env next build && cross-env NODE_OPTIONS='--experimental-json-modules' node ./scripts/postbuild.mjs",
"serve": "next start",
"analyze": "cross-env ANALYZE=true next build",
"lint": "next lint --fix --dir pages --dir app --dir components --dir lib --dir layouts --dir scripts",
"pretty": "prettier --write ."
},
"dependencies": {
"@emotion/is-prop-valid": "^1.3.1",
"@hookform/resolvers": "^3.10.0",
"@radix-ui/react-accessible-icon": "^1.1.1",
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-alert-dialog": "^1.1.5",
"@radix-ui/react-aspect-ratio": "^1.1.1",
"@radix-ui/react-avatar": "^1.1.2",
"@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-collapsible": "^1.1.2",
"@radix-ui/react-context-menu": "^2.2.5",
"@radix-ui/react-dialog": "^1.1.5",
"@radix-ui/react-dropdown-menu": "^2.1.5",
"@radix-ui/react-hover-card": "^1.1.5",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-menubar": "^1.1.5",
"@radix-ui/react-navigation-menu": "^1.2.4",
"@radix-ui/react-popover": "^1.1.5",
"@radix-ui/react-portal": "^1.1.3",
"@radix-ui/react-popper": "^1.2.1",
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-radio-group": "^1.2.2",
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-select": "^2.1.5",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slider": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-toast": "^1.2.5",
"@radix-ui/react-toggle": "^1.1.1",
"@radix-ui/react-toggle-group": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.7",
"@shipixen/next-contentlayer-module": "^2.0.2",
"@shipixen/pliny": "^2.0.4",
"@tailwindcss/forms": "^0.5.10",
"@tailwindcss/typography": "^0.5.16",
"@tanstack/react-table": "^8.20.6",
"@types/react-dom": "^19.0.3",
"@vercel/analytics": "^1.3.1",
"@vercel/og": "^0.6.5",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.0.4",
"date-fns": "^2.30.0",
"embla-carousel-react": "^8.5.2",
"esbuild": "^0.24.2",
"framer-motion": "^12.0.5",
"github-slugger": "^2.0.0",
"image-size": "^1.2.0",
"lucide-react": "^0.400.0",
"mime-types": "^2.1.35",
"next": "^15.1.6",
"next-themes": "^0.4.4",
"react": "^19.0.0",
"react-day-picker": "^9.5.0",
"react-dom": "^19.0.0",
"react-hook-form": "^7.54.2",
"react-resizable-panels": "^2.1.7",
"reading-time": "1.5.0",
"recharts": "^2.15.0",
"rehype-autolink-headings": "^6.1.0",
"rehype-citation": "^1.0.2",
"rehype-katex": "^6.0.3",
"rehype-preset-minify": "6.0.0",
"rehype-prism-plus": "^1.6.0",
"rehype-slug": "^5.1.0",
"remark": "^14.0.2",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"shipixen-contentlayer": "2.0.2",
"sonner": "^1.7.2",
"tailwind-merge": "^1.14.0",
"tailwindcss": "^3.4.16",
"tailwindcss-animate": "^1.0.7",
"vaul": "^1.1.2",
"zod": "^3.24.1"
},
"devDependencies": {
"@next/bundle-analyzer": "^15.1.6",
"@svgr/webpack": "^8.1.0",
"@types/mdx": "^2.0.13",
"@types/react": "^19.0.8",
"@typescript-eslint/eslint-plugin": "^8.21.0",
"@typescript-eslint/parser": "^8.21.0",
"autoprefixer": "^10.4.20",
"cross-env": "^7.0.3",
"eslint": "^9.18.0",
"eslint-config-next": "^15.1.6",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-prettier": "^5.2.3",
"husky": "^9.1.7",
"lint-staged": "^15.4.2",
"postcss": "^8.5.1",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
"typescript": "^5.7.3"
},
"overrides": {
"react": "^19.0.0",
"next": "^15.1.6"
},
"resolutions": {
"react": "^19.0.0",
"next": "^15.1.6"
},
"lint-staged": {
"*.+(js|jsx|ts|tsx)": [
"eslint --fix"
],
"*.+(js|jsx|ts|tsx|json|css|md|mdx)": [
"prettier --write"
]
}
}
2. Run codemods
Besides the dependencies, you may need to run codemods to update your codebase to the latest APIs. Most codebases only need to run the following codemod:
npx @next/codemod@canary next-async-request-api .
This will work if you haven't customized the Next.js API routes (so you're using the default /api
folder that Shipixen sets up).
However, if you have customized the API routes, you may need to run the following codemods:
npx @next/codemod@latest app-dir-runtime-config-experimental-edge .
npx @next/codemod@latest next-request-geo-ip .
That's it!
You should now have a Next.js 15 app with the latest features and improvements. If you encounter any issues, refer to the Next.js 15 release notes for more information.