Skip to content
Blog

Nuxt 2 to Nuxt 3 Migration – Why Now and How to Succeed

Nuxt 2 has officially reached its end of life as of June 30, 2024. This means it no longer receives updates – including crucial security patches and browser compatibility fixes. For businesses still running Nuxt 2 applications, this presents an urgent need to plan for migration.

Why Migrate Now?

Nuxt 2’s end-of-life means that upgrading is now a necessity. While your Nuxt 2 applications won’t stop working overnight, you’ll start seeing deprecation warnings from your package manager. More importantly, you’ll face compatibility issues with Node.js versions; Nuxt 2 only supports Node 14 and 16, while Nuxt 3 works with Node 18 and newer. As older Node.js versions reach their own end-of-life, this becomes a serious security risk.




Before diving deeper into this article: In Coditive, we help companies implement Nuxt-based apps and websites, migrate their current stack to Nuxt, and of course, migrate from Nuxt 2 to Nuxt 3.

Learn more about our Nuxt Development Services


The Real Cost of Waiting

Every month you delay the upgrade, you’re:

  • Accumulating technical debt that becomes increasingly expensive to address. It’s easier to make regular and small updates than big ones
  • Risking security vulnerabilities
  • Potentially facing deployment issues (for example, Vercel will stop supporting Node 16 by late January 2025)

Real-World Migration Experience: A Case Study

Recently, we completed a migration for a client whose content-focused website serves thousands of daily users. The site uses Strapi as a CMS backend with Nuxt handling the frontend in static mode. While it might seem straightforward – primarily landing pages and blog posts – the reality was much more complex.

The site features numerous modules and sections that can be combined into content blocks, many with interactive elements like search, filtering, and personalization capabilities. I’d say it’s a hybrid between a content site and a web application, which presents unique migration challenges.

Instead of creating another step-by-step guide (you can find excellent information about this in the Nuxt documentation), I’d like to share insights from our experience and highlight key considerations.

Key Migration Decisions and Insights

Why We Skipped Nuxt Bridge

On the Nuxt website you can read:

Bridge is a forward-compatibility layer that allows you to experience many of the new Nuxt 3 features by simply installing and enabling a Nuxt module.

Using Nuxt Bridge, you can make sure your project is (almost) ready for Nuxt 3 and you can gradually proceed with the transition to Nuxt 3.

Nevertheless, while using Nuxt Bridge, you can gradually adopt Nuxt 3 features without a complete overhaul, our experience is aligned with what many developers in the community have found. On Reddit, developers debated between two migration paths: going directly from Nuxt 2 to Nuxt 3 versus using Nuxt Bridge. The most popular response suggests:

Straight to Nuxt 3 would be my first approach. Components can work straight out of the box just with some small tinkering. I did it for a small hobby app I did and it went quite painlessly except that I had to learn a bit about the differences. In fact I converted quite a few of them to Composition API and it was super-fast.

Source

In our case, while Bridge’s support for Composition API, Nitro, and Vite was appealing, we ultimately decided against it. The main dealbreaker? We wanted to leverage new composables like useAsyncData and useFetch, which aren’t available in Bridge. This limitation, combined with our specific needs, made a direct migration more appealing.

Webpack to Vite: A Game-Changing Move

Moving from Webpack to Vite during the migration delivered immediate benefits. As I once wrote on X (formerly Twitter): “Moving from Webpack to Vite a few years ago was an absolutely jaw-dropping coding experience.” And that sentiment holds true every time. Each migration to Vite reminds me how much time I previously wasted when using Webpack. The development experience improvement was dramatic – faster build times and instant hot module replacement made our development workflow significantly more efficient.

The switch from Webpack to Vite may not be just a simple swap – you need to thoroughly review your nuxt.config file. Pay special attention to any custom build configurations you’ve set up, as Vite handles these differently from Webpack. Missing this step could break your build process.

From Vuex to Pinia: Simplifying State Management

We migrated to Pinia, now Vue’s officially recommended state manager, and the benefits went beyond just following best practices. Even though our use case was relatively simple (storing user language preferences and currency settings), Pinia’s intuitive API and better TypeScript support made the transition worthwhile. By the way, did I mention that Nuxt 3 has improved TypeScript support? Yes, and it’s great! 🙂

Modernizing Code Structure

Moving from Mixins to Composables

Mixins were Vue 2’s way of sharing reusable code between components and we have a few in our code. We took the opportunity to replace them with Composables, resulting in more maintainable code.

We took this refactoring opportunity even further, extracting additional reusable logic into new Composables that didn’t exist before, making our codebase cleaner and more aligned with DRY principles. If you’re interested in learning more about the benefits of Composables, I highly recommend checking out VueSchool’s comprehensive article:

https://vueschool.io/articles/vuejs-tutorials/what-is-a-vue-js-composable/

From Axios to $fetch

In Nuxt 3, the $fetch helper is the preferred way to make HTTP calls, replacing axios from Nuxt 2. You’ll want to familiarize yourself with the useAsyncData() composable and its wrapper, useFetch(). Be sure to read the documentation to implement these composables correctly. For a detailed explanation, check out this excellent video by Alexander Lichter:

Leveraging Modern Tools During Migration

ESLint Configuration Update

A Nuxt 3 migration presents an excellent opportunity to modernize your ESLint configuration. The shift to flat config files represents the new standard in ESLint configuration. We highly recommend using the official Nuxt ESLint Module, which provides excellent support for these flat config files. In our case, we paired it with @antfu/eslint-config, creating a robust and maintainable linting setup.

Enhanced Tailwind Capabilities

Our migration included updating from Tailwind 3.1 to 3.4, which brought significant improvements to our styling capabilities. This update unlocked powerful features like native support for the :has() selector and dynamic viewport units (e.g., h-dvh). These new features immediately improved our ability to create more sophisticated layouts and responsive designs with less code.

AI-Assisted Migration

For repetitive aspects of the migration, we found the Cursor editor to be an invaluable tool.

However, when using AI tools in your development process, remember to consider privacy implications. We recommend enabling privacy mode in Cursor, which ensures zero data retention and prevents your code from being stored or trained on by Cursor or any third parties.

Speaking of Cursor, we also strongly recommend defining custom .cursorrules per project to ensure consistent and project-specific code generation. You can check out this .cursorrules file for reference as a starting point.

Critical Considerations for Migration

Managing Dependencies

One of the most crucial aspects of the migration process is to carefully review your package.json. Here’s our recommended approach:

  • Audit all dependencies for Nuxt 3 compatibility
  • Look for modern alternatives to incompatible packages
  • Take advantage of the opportunity to update all dependencies to their latest versions
  • Pay special attention to packages handling core functionality

In our case, we needed to replace several packages, including our sitemap and feed generation package, but we successfully found modern alternatives that worked seamlessly with Nuxt 3.

Document as You Go: Your Future Self Will Thank You

You’ll discover many unexpected issues while fixing the planned ones – it’s a normal part of the migration process. Create a dedicated space for both your migration checklist and side notes (GitHub Issues and using project’s Readme worked great for us). Document problems the moment you spot them – you’d be surprised how many small but important details can slip away if you wait. Having everything in one organized space ensures you won’t miss critical steps or lose those hard-won solutions.

Component Migration: Taking It One Step at a Time

We started with simpler components, getting comfortable with the new patterns before tackling more complex ones. This gradual approach gave us time to identify patterns in our code that could be extracted into composables, making our codebase more maintainable in the long run.

Development Process

Throughout the migration, we maintained a delicate balance between moving forward with the upgrade and keeping our regular development work on track. Rather than isolating our migration work completely, we regularly merged changes from the main branch into our migration branch. This strategy helped us avoid a pile of merge conflicts that could have occurred from new features being added to the main site during the migration process. As a result, the final launch was remarkably smooth.

Preparing for Launch

Before your Nuxt 3 migration goes live, here are the critical steps to consider:

  1. Environment Variables Review – review and update your environment variables to match Nuxt 3’s new format. Double-check your server configuration before taking your migrated app live.
  2. Rollback Strategy – having a solid rollback strategy is crucial. We used Vercel, which makes both deployment and potential rollbacks straightforward thanks to its built-in version management. Its preview deployments give us a safe way to test changes before production.
  3. Platform Selection – speaking of rollbacks and deployments, choose a platform that lets you quickly preview, deploy and rollback changes. Thanks to Nitro’s integrations with Vercel, Netlify, and Cloudflare, everything is blazing fast. If you pick Cloudflare, you can use NuxtHub for an even better developer experience.

Remember, it’s all about stable migration process that minimizes risks and maximizes efficiency.

Deployment and post deployment checks

Our experience shows that no matter how thorough your staging environment testing is, production requires its own comprehensive verification immediately after deployment. After pushing your changes live, run a thorough check using Google PageSpeed Insights to ensure your performance hasn’t degraded. 

We’ve also found great value in using Ahrefs for the migrations – running an audit can reveal issues that might otherwise go unnoticed, such as pages suddenly returning 404 errors or broken SEO tags. Such tools serve as your safety net, helping catch any issues that could impact your site’s performance or SEO.

Looking Forward: Why Not Nuxt 4?

While the Nuxt team is already working on version 4, as of January 2025, it’s still in heavy development, and an official release date hasn’t been announced. For production applications, we strongly recommend migrating to Nuxt 3 rather than waiting for version 4.

While smaller projects might consider experimenting with Nuxt 4, for applications serving thousands of users, I suggest a more conservative approach. Once your application is running smoothly on Nuxt 3, you’ll be in a much better position to evaluate and implement future upgrades to Nuxt 4 when it reaches maturity.

Conclusion

The migration from Nuxt 2 to Nuxt 3 brings significant improvements to your codebase. The migration process offers an excellent opportunity to modernize your codebase, improve performance, and set up your application for future growth. While the process requires careful planning and execution, the benefits of improved development experience, better performance, and future-proof architecture make it worthwhile.

Ready to start your migration journey? Contact us to discuss how we can help make your Nuxt migration smooth and successful.

Paweł Madeja
Paweł Madeja
Hey there! I'm Pawel, entrepreneur, tech founder and AI future enthusiast. I lead the software house Coditive, where we combine solid development practices with deep business understanding. Working with Vue, Nuxt, and WordPress, we create solutions that help companies grow online.

Need a reliable partner?

Ready to discuss your project?
We’re here to help. Take the next step.
Let’s talk