My first thoughts on Next.js 13 and the new app router

There are two good articles that touch on some of the concerns and annoyances I also share, but I'll try to cover some of my views about it.

I had a chance to use Next.js 13 for a few weeks and noticed that some things make my job a lot simpler, while others hinder my basic coding tasks. So I wanted to share my initial thoughts about the downsides I can see, while they are still fresh, mainly related to developer experience and maintainability:

  • it's weird working with files containing ( ) @ [ ] and all the remaining jungle in their paths inside a terminal. Also, following a file hierarchy with such names can be very hard

  • tedious to split up and organize components in a meaningful way. Decisions on where and how to split the server <-> client code adds overhead. It can be hard to have a good organization for where things are supposed to be without having to constantly switch their places(server component broken down into server + client component or completely promoted to client component over time). Apps can hold a bunch of UI state, and it often happens that you start with server-side components pulling in data directly, and then afterward you figure out that you need to add some UI state for interactivity... then you need to reorganize the code, and create a new hierarchy. I usually love splitting up components but with Next.js it feels like I need to spend 50% more time working and thinking about it if I want to make optimal use of RSC(if not, why even use Next.js in the first place?!). Maybe you get used to it after a couple of projects. But I can't shake the feeling that it's a trade-off no one talks about. A simple design change can lead to rehaul of multiple files.

  • writing 'use client' and 'use server' all over the place gets annoying and if you don't settle on a good convention for placing things you'll never know which files contain only the server-side logic and which ones only the client, or both without taking a peek at the source and for me this is tiring. Even if you manage to neatly organize it, like I said, server <–> client boundaries tend to move places over time and require you to reorganize the functions/files. The alternative is to just "leave it for later" and eventually give up on any kind of organization in this regard

  • there are many downsides when it comes to the data layer. It's hard to debug, understand, and keep it in a good shape. Client-only apps usually call HTTP APIs which return pure data. That is very easy to debug using browser dev tools in terms of correctness and performance. Writing tests, mocks, automation scripts, and load tests is easy. There are a bunch of well-known and battle-tested tools for doing that. Next.js and React RSC move all of this into the new and unexplored territory and no one mentions this issue. I want to be able to dissect the complete data layer at any point in time using multiple approaches, add tests, and automation scripts. It seems like a bunch of inexperienced developers are currently jumping on this hype train without really thinking things through. For a framework that intertwines so much client and the backend side, I want to be able to debug and analyze all of the things we usually do through browser and backend side dev tools and do it with comparable ease

  • a lot of implicit logic comes from Next.js that you are just supposed to know. Somehow reminds me of AWS cloud service pricing where you need to hire an expert to help you figure out which things are used in a suboptimal way because it wasn't clear from the start. If Next.js takes over I can easily imagine that specialized consultants and agencies will thrive because IMO inexperienced devs can create such a mess with this stack that the pure client-side-apps could only dream of

  • more complex servers are required which could mean higher costs in some cases. This is not only about the actual server that serves the app's content, it's also about the servers that will run CI/CD and automation tasks in general, run alternative environments to production one, etc. If everything is primarily server rendered from the start and you don't expose digestible APIs, does that mean that you can no longer rely on basic test scripts to verify data returned by the an HTTP API, but rather that you need to move everything towards more costly and less stable e2e tests because you need to digest JSX generated markup instead? OK you can still build everything with HTTP endpoints, but I'd argue that that moves you back, one step closer to good old SPAs(comparing the advertised advantages of working with data in Next.js)

  • if you build a web app totally behind auth + app meant for users on a good internet connection, internal use apps etc. then low cache hits between user requests, and no SEO benefits means that if you go the Next.js route you trade client-side complexity for backend/infrastructure/hosting complexity and costs for the questionably low benefit

These are my 13 cents based on my limited experience with the version of Next.js. For now, I think I'll hold off on joining the Next.js hype but who knows, I'm sure that Vercel will work hard to improve the DX and the product overall. At the same time, I have an uneasy feeling that those improvements will come through a set of proprietary tools and services that will lock everyone in with Vercel over time.

Close and tight collaboration with React team gave Vercel a head start with RSC implementation but generated a thing that is still relatively open and free. From the business perspective, there must be something else. I'm afraid that the next iterations of solutions and tools they produce for this open platform will start to be more and more cloud-based and found behind a subscription plan. At the moment they have the edge in infrastructure hosting Next.js projects, but that could change over time since Next.js is an open project. I believe that there will be something else that you will need to pay for to have the best development and hosting experience.