Next.js Developers Who Know Where the Boundary Is
Server components, caching behaviour and rendering strategy are where Next.js projects go wrong, and they are exactly what a portfolio does not show. We vet on real production scenarios and send two or three profiles within three business days.
- Profiles in 3 business days
- Two-week replacement guarantee
- You brief the developer directly

What the Job Is Once the Demo Is Over
Building a page is the part everyone can do. The work that takes experience is deciding which parts of a route render on the server, what the caching behaviour should be on each one, and why the page is shipping four hundred kilobytes of JavaScript when most of it never needed to reach the browser.
Then there is the unglamorous half: making a loading state that does not shift the layout, keeping the mutation path and the cache in agreement, and working out why the production build behaves differently from the development server. These are the things that turn up in your sprint, and none of them appear in a portfolio.
A developer we place joins your standups, your board and your code review. You brief them yourself, because an account manager in the middle adds delay and loses detail.
React developers more broadlyApp Router or Pages Router, and What the Answer Reveals
We do not ask this to find out which one they prefer. We ask it because the answer dates a candidate and shows how they handle a model shift.
Only Ever Used Pages
Comfortable with a data-fetching function per page and a clear split between what runs on the server and what runs in the browser. Dropped into an App Router codebase, they tend to mark everything as a client component so familiar hooks work, which removes most of the reason you moved. Not a problem if your codebase is Pages. A real ramp-up cost if it is not.
Only Ever Used App
Fluent with server components and colocated data fetching, and often unable to work in a Pages codebase without friction, because the older data model is not a subset of the newer one. Many were also taught caching as defaults rather than as decisions, so they struggle the first time a page serves stale content.
Has Shipped Both
The answer we look for. They can name what the newer model improved, what it made harder, and where they still reach for a client component deliberately. They talk about the migration as a series of trade-offs rather than an upgrade. This is the person you want if your codebase contains both, which many do.
Tell us which router your application uses when you send the brief. It is one line and it changes the shortlist more than any other detail except seniority.
Server Components, Client Components and the Mistakes in Between
Almost every Next.js performance complaint we investigate traces back to this line being drawn in the wrong place.
The Boundary Pushed Too High
One interactive element needs state, so the developer marks its parent as a client component. Everything below it becomes client code too, including the parts that only render text. The page now ships a bundle nobody intended and renders on the server for no benefit. The fix is to push the boundary down to the smallest interactive piece, and it is usually a half-hour change with a large effect.
Non-Serialisable Props
A function, a class instance or a date-like object passed from a server component into a client one. Only serialisable values cross that boundary, and the failure is not always legible from the message. Experienced developers pass identifiers and primitives across and let the client component do its own work, rather than handing it behaviour.
Composition Instead of Conversion
A client component can still render server-rendered children if they are passed in rather than imported. Developers who know this keep large, static subtrees on the server even inside an interactive wrapper. Developers who do not convert the whole branch and then wonder why the bundle grew.
Secrets Across the Line
Code that reads an environment secret must stay on the server, and a careless import can pull it into a client bundle. We check whether a candidate thinks about this unprompted, because it is the kind of mistake that is invisible until somebody reads the shipped JavaScript.
The Reason Your Page Is Showing Yesterday
Next.js caches in several places at once. A developer who cannot name them will eventually ship a page that serves stale content and not know why.
What we look for is not memorised defaults, which change between releases. It is whether a developer treats caching as something they decide per route and can explain, rather than something that happens to them.
Choosing Per Route, Not Per Project
The useful skill is knowing that different routes in the same application should be rendered differently, and being able to say why for each one.
| Strategy | Fits | Costs you | Typical mistake |
|---|---|---|---|
| Static at build | Marketing pages, documentation, anything identical for every visitor and changing rarely | A deploy is required for a content change unless revalidation is wired up | Using it for a page whose data changes daily, then wondering why it is stale |
| Static with revalidation | Catalogues, listings and article pages where a short delay after a change is acceptable | Correctness now depends on a time window somebody chose | Setting a long window because it is cheaper, and inheriting support tickets about stale prices |
| Server rendered per request | Personalised pages, dashboards, anything that depends on who is asking | Every request does work, so a slow data source is now a slow page | Applying it to the whole route when only one small section is personal |
| Streamed with suspense | Pages where a fast shell plus a slower panel beats waiting for everything | Loading states have to be designed properly or the page visibly jumps | Streaming without stable placeholders, producing layout shift that feels worse than waiting |
| Client fetched | Highly interactive views behind a login where the first paint matters less than the interaction | The data is invisible to crawlers and arrives after the JavaScript does | Reaching for it out of habit on a page that would have been simpler rendered on the server |
In a vetting session we hand over a small application with the wrong strategy on three routes and ask which ones to change and why. The reasoning is the assessment; the change itself takes minutes.
Server Actions and Middleware
Two features that make things dramatically easier and are routinely used for things they should not be.
Server Actions
- Genuinely good for forms and mutations when the Next.js app is the only consumer of that operation
- An action is a public endpoint. It needs authorisation and input validation exactly like an API route would
- Pending and error states still have to be designed, or the interface simply looks broken for a second
- Revalidating the affected path after the mutation is what keeps the interface honest
- When a mobile app or a partner needs the same operation, build an API instead and have the action call it
Middleware
- Runs before the request reaches a route, which makes it right for redirects, locale handling and coarse auth gates
- Wrong for anything expensive: it is on the path of every matching request, including static assets if the matcher is careless
- Frequently runs on an edge runtime where familiar Node APIs and database drivers are unavailable
- Doing a full session lookup here is a common cause of latency added to every single navigation
- Authorisation decided only in middleware and not enforced where the data is read is a security problem, not a shortcut
If the backend work behind those actions is growing past what a route handler should hold, that is usually the point to add a Node developer rather than stretching the frontend hire.
Beyond the Obvious Host
Next.js is easiest on the platform built for it. Plenty of teams cannot or will not use it, and that is where developer experience genuinely differs.
Self-Hosted in a Container
Entirely workable, and you inherit the things the managed platform was doing quietly: image optimisation, cache headers, revalidation storage that survives a restart, and making sure multiple instances agree on what is cached.
Behind Your Own CDN
Now two caches have opinions about the same response. Getting headers and invalidation right across both is a real piece of work, and it is where stale-content incidents come from in self-hosted setups.
Static Export
Viable for a genuinely static site and immediately limiting: no per-request rendering, no server actions, no middleware. Fine if you chose it deliberately, painful if you discover the constraint halfway through.
Edge or Node Runtime
Middleware and some routes may run on a runtime without full Node APIs. Knowing which of your code paths is affected, before deploying, is a mark of someone who has shipped this rather than read about it.
Build and Environment
Values baked in at build time versus read at runtime is a distinction that produces confusing incidents. A developer who has debugged a wrong environment value in production explains it without hesitating.
Observability
Server rendering means errors happen on the server, where users cannot see them and neither can you unless you set that up. We ask what they would want logged before they would call a Next.js deployment production-ready.
When Next.js Is Overkill
We place developers, so recommending a framework you do not need would be easy and would cost you more than it costs us. Here is where we would push back.
An Internal Tool Behind a Login
Nothing needs indexing, nobody is waiting on a first paint from a cold visit, and every user is authenticated. A plain React application with a router and a data-fetching library is simpler to build, cheaper to host anywhere, and has far fewer behaviours to learn. Choosing Next.js here buys complexity and returns nothing.
A Content Site That Rarely Changes
If the content is written in files and published on a schedule, a static site generator does the job with a fraction of the moving parts and a hosting bill close to nothing. Next.js makes sense when content and interactivity have to live in the same application, not when the pages are documents.
A Backend With a Thin Interface
If the real product is data processing, integrations or scheduled work with a small dashboard on top, put the logic in a proper Node service and keep the interface simple. Route handlers are a poor home for background jobs, queues and long-running processes, and building them there is a decision you will unpick later.
Public Pages That Must Be Fast and Indexed
Marketing, catalogue, listings, articles. Server rendering and static generation are exactly what the framework is for, and the caching model stops being a burden and starts being the feature.
Mixed Public and Authenticated
An application with a public catalogue and a private account area, where different routes want different rendering strategies inside one codebase. Very little else handles that split as cleanly.
Already on Next.js and Unhappy
Before concluding the framework is wrong, it is worth finding out whether the problem is the boundary, the caching or the data layer. A fixed-scope audit answers that in writing, and it is cheaper than either a migration or another hire made on a guess.
How We Test Next.js Candidates
Live coding and system design on real production scenarios. Nothing that rewards memorising an API that will have changed by next year.
Shrink the Bundle
A page with the client boundary drawn far too high. Reduce what ships to the browser without changing what the user sees. Most candidates find something; the good ones explain the tree.
Find the Stale Page
A route serving old data after a mutation. We are watching whether they reason about which cache is responsible or start changing settings at random.
Review a Mutation
A server action with no authorisation check, no validation and no revalidation afterwards. Whether they treat it as an endpoint is the whole question.
Argue a Strategy
Five routes, and they choose a rendering approach for each and defend it, including the one where they would refuse to use Next.js at all.
Nearby Pages
React Developers
If the application does not need server rendering and a plain React build is the better answer.
React hiringNode.js Developers
For the backend work that outgrows route handlers: jobs, queues and anything with a second consumer.
Node hiringNode Frameworks
What to put behind a Next.js frontend when the API becomes its own service.
Compare frameworksPerformance Work
Fixed-scope: find out what is actually slow before deciding what to change.
Performance projectsHiring Next.js Developers
App Router or Pages Router: what should we be hiring for?
Hire for whichever one your codebase uses, and treat the answer to the question as a signal rather than a filter. A candidate who has only worked in the App Router often struggles in a Pages codebase because the data-fetching model is genuinely different. A candidate who has only worked in Pages tends to write client components everywhere in an App codebase, which quietly undoes the reason you chose it. The strongest candidates have shipped both and can say which parts of the newer model they think are an improvement and which they find awkward.
What boundary mistakes do people make with server and client components?
The common one is marking a component as a client component high in the tree, which makes everything beneath it a client component too, so the page ships far more JavaScript than intended and the server rendering benefit disappears. The other frequent mistake is passing something non-serialisable across the boundary, such as a function or a class instance, which fails in a way that is not always obvious from the error. We give candidates a page with exactly these problems and ask them to reduce the client bundle without changing behaviour.
Why did our Next.js page show stale data after a deployment?
Almost always caching, and almost always caching the team did not know was switched on. Next.js caches at several levels: the fetch result, the rendered route, the client-side router, and whatever your host puts in front of all of it. A page can be statically rendered at build time when the developer assumed it was rendered per request. The fix is to be deliberate about which routes are static, which revalidate on a schedule and which must be dynamic, and to invalidate on write rather than hoping a time window is short enough.
Are server actions ready for real applications?
They work well for form submissions and mutations in an application where the Next.js app is the only consumer. They remove a lot of boilerplate and keep the mutation next to the component that triggers it. The things to be careful about are that a server action is a public endpoint and therefore needs its own authorisation and validation exactly like an API route, that error and pending states still have to be designed properly, and that if a mobile app or a third party also needs the same operation, you want a real API rather than an action. We screen for whether a candidate treats actions as endpoints or as function calls.
When is Next.js the wrong choice?
When the application sits behind a login and nothing needs indexing or fast first paint for anonymous visitors, a plain React build with a router is simpler, cheaper to host and easier to reason about. When the site is mostly content and rarely changes, a static site generator does the job with less machinery. When the product is genuinely a backend with a thin interface, a proper Node service plus a small frontend beats putting business logic into route handlers. Next.js earns its complexity when server rendering, routing and data fetching genuinely need to cooperate.
Can your Next.js developers deploy somewhere other than the obvious host?
Yes, and we screen for it because it is where teams get stuck. Self-hosting in a container, running behind your own CDN or reverse proxy, or deploying to another cloud all work, but you become responsible for things the managed platform did silently: image optimisation, cache headers and invalidation, whether your middleware runs on an edge runtime or in Node, and how build output maps onto your infrastructure. A developer who has only ever deployed to the default platform can learn this, and you should know that is what you are asking for.
Can one Next.js developer cover both frontend and backend?
Up to a point, and the point arrives sooner than people expect. Route handlers and server actions cover a lot of application backend work. They are a poor home for background jobs, queues, scheduled work, long-running processes and anything a second consumer needs. If your roadmap includes those, plan for a Node developer alongside the Next.js one. We will say so in the profile rather than letting you find out in month three.
Tell Us Which Router and We Will Send People
App Router, Pages Router or a codebase running both. Two or three vetted profiles within three business days, and a replacement at no cost if the fit is wrong in the first two weeks.