Why We Migrated from Next.js to Vite and Hono

Published: (December 31, 2025 at 08:07 AM EST)
9 min read
Source: Dev.to

Source: Dev.to

Migration Overview (Late 2025)

In late 2025 we migrated Pluslide entirely away from Next.js.
Our new stack? Vite + React for the frontend and Hono for the API layer.

This was not a decision we made lightly. Next.js has shaped modern web development and remains the default choice for many React projects. After months of frustration with Cloudflare compatibility, growing security concerns, and architectural complexity, we realized that Next.js was no longer the right tool for our needs.

Below is a summary of what we discovered.


The Cloudflare Compatibility Problem

Pluslide runs entirely on Cloudflare. This infrastructure choice has been excellent for performance and cost, but Next.js and Cloudflare have never been a perfect match.

The Migration Pain

When we first deployed Next.js on Cloudflare we used next‑on‑pages, an adapter originally maintained by Cloudflare. The experience was never smooth. Even with official support we constantly hit edge cases and limitations that required work‑arounds.

  • September 2025: Cloudflare announced they were archiving the next‑on‑pages project.
    The official recommendation became OpenNext, a community‑maintained adapter.

Based on our experience with next‑on‑pages we developed a healthy skepticism toward adapter‑based solutions. Moreover, choosing this path means you cannot use the latest Next.js versions immediately—you must wait for the community to adapt and test compatibility.

Note: Migrating from next‑on‑pages to OpenNext also requires moving services from Cloudflare Pages to Cloudflare Workers. This is not a small change. If we were going to undertake a migration of that scale anyway, we had to ask ourselves:
Is this the right path forward?
Or should we step back and consider whether there is a better option entirely?

The Vercel Question

Our experience deploying Next.js on Cloudflare raised an uncomfortable question: what exactly is Vercel optimizing for?

  • Next.js is technically open source, but the best deployment experience (especially for Edge Runtime) lives on Vercel.
  • Features like Incremental Static Regeneration work seamlessly on Vercel but require significant effort elsewhere.
  • The gap between “runs on Vercel” and “runs anywhere else” keeps widening.

If you are not on Vercel, you become a second‑class citizen—a status we did not want.

Security Concerns That Accelerated Our Decision

In 2025 Next.js faced a series of critical security vulnerabilities. While these were not the primary reason for our migration, they shook our confidence.

CVE‑2025‑29927: Middleware Authorization Bypass

  • Date: March 2025
  • Severity: CVSS 9.1
  • Impact: Attackers could forge a specific HTTP header to completely bypass middleware‑based access controls, circumventing authentication checks, authorization logic, and CSP headers.
  • Scope: Affected versions spanning over four years of Next.js releases.
  • Reference: Security Labs – Next.js Middleware Auth Bypass

CVE‑2025‑55182: Remote Code Execution

These incidents reminded us that framework complexity comes with security costs—more abstraction layers mean more potential attack surfaces.

The Architecture Problem

Our Next.js codebase had become a tangled mess:

  • tRPC routers lived alongside React components.
  • Server and client code mixed in ways that made reasoning about data flow difficult.
  • Every file required mental overhead to determine whether it ran on the server, the client, or both.

We do not deny that part of this mess came from rapid prototyping where structure took a backseat to speed. This is not a flaw in Next.js per se, but the framework’s blurry boundaries between server and client made it too easy to let things get out of hand.

Practical consequences

  • Architecture became hard to read and reason about.
  • AI coding assistants frequently hallucinated about where code should run, generating server code in client files and vice‑versa.
  • Turborepo cache was essentially useless—any change to UI or API code invalidated both caches.
  • The build graph turned into a web of unnecessary dependencies.

Unifying on Cloudflare Workers

Before choosing our new stack we made another infrastructure decision: consolidate everything on Cloudflare Workers.

  • The distinction between Pages and Workers has always been confusing; their responsibilities overlap significantly, and the developer experience differs in subtle but frustrating ways.
  • In 2025 Cloudflare made their direction clear: they now recommend Pages users migrate to Workers (see the migration guide in the Pages documentation).

Bottom line: We were migrating to Workers no matter what.

Why Vite and Hono Became Our Answer

We needed tools with first‑class Workers support and a clean separation between frontend and backend.

Vite: Native Cloudflare Workers Integration

  • Vite’s first‑class Cloudflare Workers support is provided by the Cloudflare Vite plugin.
  • The plugin offers deep integration between Vite and the Workers runtime: you can run Vite’s dev server locally while executing your code directly in the Workers runtime.

Hono: Minimalist Edge‑Ready API Framework

  • Hono is a tiny, standards‑based router designed for edge environments.
  • It pairs perfectly with Workers, giving us a lightweight, type‑safe API layer without the heavy abstractions of Next.js.

Final Thoughts

Migrating away from Next.js was a painful but necessary journey. By moving to Vite + React for the UI and Hono for the API—both running on Cloudflare Workers—we gained:

  1. Predictable, first‑class Edge support
  2. Clear separation of concerns (frontend vs. backend)
  3. Simpler, faster builds and caches
  4. Reduced attack surface and quicker security patching
  5. Freedom from vendor lock‑in (no longer a second‑class citizen)

The migration has already paid dividends in performance, developer experience, and security. We’re now fully focused on building Pluslide’s next chapter on a stack that aligns with our long‑term goals.

No More “Works in Dev, Breaks in Production” Surprises

The Environment API introduced in Vite 6 was developed with direct input from the Cloudflare Workers team. It narrows the gap between development and production environments. We can now develop directly against edge environments while enjoying the full Vite experience.

The performance gains were a bonus. Our development server now starts in a few seconds, Hot Module Replacement is instantaneous, and production builds that took five minutes now complete in under two minutes.

Much of this speed comes from Rolldown, the new Rust‑based bundler powering Vite 8. It is still in beta, but it is already delivering impressive results in our production workflow.

Hono: The Edge‑Native Framework

Hono handles our API layer.

  • Tiny (under 12 KB with the minimal preset)
  • Zero dependencies
  • Uses only Web Standard APIs with perfect Edge Runtime support

This means identical code runs on Cloudflare Workers, Deno, Bun, AWS Lambda, or Node.js without modification.

Cloudflare uses Hono internally. According to their official blog post, all Workers Logs internal and customer‑facing APIs run on Workers using Hono. Cloudflare also uses Hono in the internals of KV and Queues. When the platform provider builds its own products with a framework, you know it works.

The developer experience is excellent:

  • First‑class TypeScript support
  • API feels familiar to Express developers but without legacy baggage
  • Middleware composition is clean and predictable

Clear Boundaries

With Vite and Hono, the separation is explicit:

Frontend (Vite + React) – Purely client‑side. Handles UI, routing, and state management. Knows nothing about database schemas or authentication logic.

API (Hono) – Purely server‑side. Handles business logic, data access, and authentication. Knows nothing about React components or UI state.

Shared – Only TypeScript type definitions. The API exports types that the frontend imports. No runtime code crosses the boundary.

The benefits went beyond easier reasoning about the code:

  • Turborepo cache hits increased dramatically.
  • Frontend developers can work without understanding backend implementation details.
  • Backend developers can refactor without worrying about breaking UI code.

This clean separation also made our AI‑assisted development significantly more effective. The models could reason about each layer independently without getting confused by mixed contexts.

Perhaps more importantly, debugging became straightforward. With Next.js and its Cloudflare adapter, pinpointing issues was a constant struggle: was the bug in our code, in Next.js internals, or in the adapter layer? OpenNext maintains extensive documentation on workarounds, performance tips, and known issues. We believe these documented issues represent just the tip of the compatibility iceberg.

After abandoning Next.js and the adapter layer—using a complete frontend‑backend separation—our bug rate dropped by over 70 %. When issues do arise, we identify and fix them significantly faster because the source is always clear.

What We Gained After Migration

A few months after completing the migration, here is what changed:

  • Build times dropped from five minutes to under two minutes.
    Our CI pipeline builds eight different services and compiles over ten shared packages, so this measurement includes the entire monorepo.

  • Turborepo cache‑hit rates increased dramatically.
    With clear boundaries between frontend and API, changing one no longer invalidates the other. Most builds now skip unchanged packages entirely.

  • Local development became instant.
    Dev server starts in seconds. Hot Module Replacement applies changes immediately. The feedback loop went from “wait and refresh” to “save and see.”

  • Cloudflare deployment became straightforward.
    No more compatibility layers. No more edge‑runtime workarounds. Workers do what Workers are supposed to do.

  • The codebase became easier to understand.
    New team members onboard faster. Code reviews focus on logic rather than “where does this run?” questions. Debugging is simpler because the execution context is always clear.

  • Security posture improved.
    Fewer abstraction layers mean fewer potential vulnerabilities. When security patches are needed, they apply to smaller, more focused codebases.

When Is Next.js the Right Choice?

We want to be clear: Next.js remains an excellent framework for many use cases. Our migration does not mean you should abandon it.

Next.js makes sense when:

  • Your team consists primarily of frontend developers who prefer not to manage a separate API server.
  • You want integrated backend capabilities to build full‑stack applications without context‑switching.
  • You rely on Vercel’s managed ecosystem (Analytics, Edge Functions, Image Optimization, deployment previews, etc.).
  • You need complex Incremental Static Regeneration (ISR) patterns with fine‑grained cache control.
  • Your architecture heavily uses React Server Components for streaming and progressive rendering.

The question we asked ourselves was simple: do any of these conditions apply to Pluslide?

The answer was no. We were committed to Cloudflare, not Vercel. Our pages were either fully static (marketing site, documentation) or fully dynamic (the presentation editor). We did not need ISR, nor were we using React Server Components.

For us, Next.js was adding complexity without delivering corresponding value.

Conclusion

Next.js is a powerful framework with many valid use cases. If Vercel is your platform and full‑stack React is your architecture, it remains an excellent choice.

But frameworks should serve your needs, not the other way around. When the friction becomes constant, when compatibility requires endless workarounds, or when security incidents keep you up at night, it might be time to reassess.

For Pluslide, Vite and Hono provided exactly what we needed: speed, simplicity, and seamless Cloudflare integration. The migration took effort, but the result is a codebase we actually enjoy working with.

Your situation may be different. If you find yourself fighting your framework more than building with it, know that alternatives exist. Sometimes the best technical decision is choosing tools that match your infrastructure rather than tools that fight against it.

This post was originally published on the Pluslide Blog.

Pluslide is a presentation‑generation API built on the stack described above. If you’re building apps that need to generate slides programmatically, check it out.

Have questions about our migration? Drop a comment below.

Back to Blog

Related posts

Read more »