Does JS need its own Laravel?

Andrii Kovalchuk
Just Eat Takeaway-tech
5 min read1 day ago
Photo by James Harrison on Unsplash

For a long time, JavaScript had little presence in the backend world. While Node.js existed, it was typically relegated to small or medium microservices created with Express. Meanwhile, the majority of applications were built with mature frameworks like Laravel, Ruby on Rails, and Django, which have undergone extensive development and refinement.

During this period, the frontend landscape grew increasingly complex. Single Page Applications (SPAs) encountered numerous challenges, particularly with data layers and state management. Traditional backend frameworks struggled to address these issues effectively, paving the way for “meta” frameworks like NextJS, which introduced solutions through Server-Side Rendering (SSR) and Static Site Generation (SSG). NextJS even took a revolutionary step with React Server Components and Server Actions, enabling a novel form of communication between server and client that can’t be replicated fully in frameworks like Laravel or Rails.

I started my career as PHP developer (who didn’t, right?), so I had extensive experience working with Laravel to build a wide range of applications, including CMS, CRMs, and webshops. My experience with Laravel has been overwhelmingly positive. However, the modern buzz around JavaScript meta frameworks prompted me to experiment with NextJS, leading to some controversial insights.

The Good and the Bad of NextJS

NextJS is undeniably a powerful tool, and the team behind it has done an impressive job. Relatively recently, NextJS unveiled React Server Components and server actions, marking a revolutionary approach to backend and frontend communication.

However, NextJS has some cons that don’t allow it to take the place of backend frameworks. Despite being treated as a full-stack framework, it often feels more like a skeleton of one. It lacks several built-in features essential for medium to large projects — such as authentication, ORM, translations, validation, cron jobs, etc.

Some argue that the lack of built-in features is an advantage, allowing developers to choose the necessary tools. However, having too much to choose from is not always good. Starting a project from scratch with NextJS feels more like walking on Lego bricks than building with them.

For instance, adding authentication and permissions to a project in NextJS (which is a very common feature, isn’t it?) means picking from several options: NextAuth.js, Lucia, Supabase Auth, Clerk, etc. Investigating all these options to find the best fit can be time-consuming and frustrating. When I tried using NextAuth for a pet project, I found the documentation terrible, and implementing a regular DB username-password login was a nightmare.

This has led to the rise of startups like Clerk and Supabase Auth. While they are good solutions with great teams behind them, they come with a price. Paying for authentication, a core feature in 99% of projects, feels like paying a subscription for heated seats in your BMW. And even though it’s not prohibitively expensive, it adds up.
Besides, what chance is there that Clerk or any other startup that you use will just stop functioning at some point or its price will increase by 100%? Small, but not zero. And just imagine the amount of work to rewrite such a weighty part of an already working project.

Almost every NextJS app ends up with a significant amount of glue code. It doesn’t function as seamlessly or cohesively as other all-in-one frameworks do, lacking the harmonious coordination between modules found in more integrated solutions.

This leads to another problem: keeping up. The JavaScript ecosystem is known for its rapid changes. Libraries and frameworks frequently update, often introducing significant changes. This can be a major headache when maintaining or upgrading projects. The community constantly jumps from Redux to Zustand, Styled Components to Tailwind, Prisma to Drizzle, etc.

Take the transition from Pages to the App Router in NextJS, for example. Such changes can require substantial rewrites, which are particularly painful for large projects. This also led to the fact that all other libraries adapted for NextJS also received significant changes.

In the case of frameworks like Laravel, popular add-ons often become its part. This means that in case of significant changes to the framework, you don’t have to worry about updating each part separately.

Moreover, switching between different NextJS projects can also be challenging due to the lack of standardization. Different projects might use different ORMs, state management libraries, and other tools, making it difficult to transfer knowledge and experience from one project to another.

And last but not least:

Sometimes, working with NextJS feels like there’s too much magic happening behind the scenes. With Laravel, I can usually dive deep into the framework code to debug issues. This level of transparency is often missing in NextJS. In NextJS, things either work or not, with little room for in-depth troubleshooting. While this might be acceptable for some parts of an app, it can be frustrating at times. For instance, their convoluted default caching mechanism applies to all network requests and renders, making it incredibly difficult to disable. Thankfully, they decided to remove some default caching in the 15th version.

Alternatives and the Future

At the same time, a few JavaScript frameworks are striving to offer a more comprehensive solution. For instance, Adonis was inspired by Laravel and looks a lot like a TypeScript version of it. However, it remains a traditional server-rendering framework and doesn’t provide the same client-side capabilities as NextJS.

RedwoodJS stands out as a framework that comes closest to the real full-stack solution. RedwoodJS had some weird decisions like having GraphQL by default for every project. Thankfully, they have removed it recently and adopted server components. RedwoodJS shows great potential for future growth and its roadmap looks very promising. However, it currently lacks the hype and resources that NextJS enjoys.

I believe that JavaScript meta frameworks are at a crossroads. The community and resources either need to shift more towards frameworks like RedwoodJS or steer NextJS towards becoming a true all-in-one solution. Otherwise, all the hype may disappear over time and the community will return to more old-school and “simpler” options.
I’m referring to tools like HTMX, which have gained significant popularity in recent years for a reason. There’s also Inertia, which acts as a bridge between the backend and frontend, addressing many of the issues that NextJS aims to solve, but in a much simpler way.

For now, I believe NextJS is well-suited for small startups. NextJS can act as a frontend on steroids for larger projects, but you’ll likely still require a dedicated backend. And if I had to choose a truly full-stack, bulletproof solution for a project, my choice would still be Laravel.

Want to come work with us at Just Eat Takeaway.com? Check out our open roles.

--

--