Let's talk

Frontend

Hire Next.js Developers

Next.js engineers who know when rendering on the server helps and when it only adds cost.

Next.js earns its place when a product needs both an application and a set of pages that have to rank — a marketplace, a catalogue, a documentation-heavy tool — and you would otherwise run two codebases to get there. It stops earning its place when a purely internal application inherits the rendering complexity without ever needing the search benefit.

In the App Router there is really only one question, asked repeatedly: where does this code run, and what does it cost to be wrong about that. Everything else — server components, actions, streaming, revalidation — is a consequence of the answer.

Caching is the framework’s best feature and its worst failure mode

Next 15 changed the default so fetch is no longer cached unless you say so, which was the right call: the previous default produced pages that were correct in development and stale in production, and the mechanism was invisible in the code. Teams still carry habits from before that change.

The pattern we use is explicit revalidation per request rather than a blanket page setting — a listing that tolerates half a minute of staleness declares that on the fetch that loads it, and the next data source on the same page can declare something different. Blanket settings are convenient and they are also why “why is this page showing yesterday’s price” takes two days to diagnose.

One related judgement is worth stating because it is easy to get backwards: if the framework is already caching a response, do not also serve it from a CMS’s own edge cache. Two caches means two independent staleness windows, and the union of them is what your users experience.

What actually changes when you migrate from the Pages Router

Not the folder names. The three real changes are that data fetching moves into the component that needs it, that “client” becomes something you opt into at a boundary rather than a default, and that several APIs became asynchronous — in Next 15, route parameters and search parameters arrive as promises that have to be awaited.

Migrate route by route with both routers live rather than in one branch. The App Router and the Pages Router coexist, which means the migration can ship in pieces and be judged in production, and a route that turns out to be harder than expected does not hold the other forty hostage.

Where Next.js is the wrong choice

For a marketing site or documentation with no application behind it, a static generator produces a better result for less work and less runtime. We build our own site that way deliberately: the output is HTML on disk, there is no server to keep alive, and every crawler — including the answer engines, none of which execute JavaScript — gets the full text on the first request.

For a purely internal tool behind a login, the search advantages are worth nothing and the rendering model is pure additional complexity. A plain single-page application with a boring API is cheaper to build and much cheaper to debug.

And if the team’s deployment target is a container on infrastructure they run themselves, be honest that the smoothest Next.js experience is on the platform that develops it. Self-hosting works, but image optimisation, incremental revalidation and caching all need deliberate configuration that the managed platform supplies for free.

What we interview for

Ask a candidate to explain what runs on the server and what ships to the browser in their last project, and how they knew. Then ask what they cached, for how long and what invalidates it. Engineers who have operated an App Router application answer precisely. Those who have only followed a tutorial describe the folder structure.

Two follow-ups tend to settle it:

  • A secret was read in a component that later gained an event handler. What stops that secret being in the client bundle, and how would you find out if it already is.
  • A page shows stale data for one user and fresh data for another. Name three mechanisms that could cause it.

The first is a real class of incident, not a puzzle — the boundary between server and client is a security boundary, and it moves when someone adds an onClick.

What we watch for in review

Server actions with no validation on the input, because an action is a public endpoint whether or not it looks like one. useEffect fetching data that a server component could have loaded before the page rendered. And the quiet one: a shared utility imported by both a server and a client module, dragging a server-only dependency into the browser bundle and inflating it by an amount nobody attributes to that change for months.

We also insist on knowing the build’s own numbers. If a candidate cannot say roughly what their first-load JavaScript was, they were not treating the rendering model as a performance decision — which is the entire reason to choose this framework over a plainer one.

Teams are built for companies in the United States and the Gulf — the UAE, Saudi Arabia, Qatar, Kuwait, Bahrain and Oman. The engineers are in Pune, which matters mostly for the clock. Dubai is ninety minutes behind us and Riyadh two and a half hours, so a Gulf team shares almost the whole working day. New York is nine and a half hours behind, so American engagements run on a written handover and one fixed overlap window rather than on a standing call — a real constraint, and better stated than discovered.

What these engineers do

  • App Router, server components and server actions with clear client boundaries
  • Caching and revalidation tuned to the data, rather than accepting framework defaults
  • Deployment on Vercel, a Node runtime or self-hosted containers with equal comfort
  • Incremental migration from the Pages Router without freezing feature work
  • Metadata, structured data and Core Web Vitals treated as build-time requirements

Delivered AI-first

AI assistance is used to scaffold routes, layouts, loading and error boundaries, to draft server actions with their validation schemas, and to carry out the mechanical half of a Pages Router to App Router migration file by file. Caching and revalidation decisions stay with the engineer, since an incorrect cache boundary is the failure mode this framework is most prone to and the one an assistant is least able to reason about. Review discipline is unchanged. The measurable effect is throughput per engineer, not fewer reviews.

Next.js engineers in client teams

Tell us what the Next.js work is.

Roughly what it involves, the seniority you need, and when it has to start. We will say what it takes to staff it, or say honestly that we are not the right people for it.

A person reads every enquiry and replies within one working day.