Hire React developers
React is the component library behind most modern web front ends, and hiring for it means hiring for state and rendering discipline rather than syntax.
What React actually is
React is an open-source JavaScript library for building user interfaces out of components. It was released by engineers at Meta and is now maintained by a core team there together with a large body of outside contributors. Its job is narrow on purpose: React renders a tree of components and keeps that tree in step with application state. It does not ship a router, a data layer, a form library or a build system, which is why every React codebase is really React plus a set of decisions somebody made around it.
That narrowness is the single most important thing to understand when you hire. Two engineers can both have five years of React on a CV and have built almost nothing in common, because one worked in a Next.js application with server components and a typed data layer while the other maintained a client-rendered dashboard wired to Redux and a REST API. The library is the same. The skills barely overlap. A hiring process that tests React in the abstract will pass both and tell you nothing.
React's programming model is declarative. You describe what the interface should look like for a given state, and React works out which parts of the document to change. The developer's real work is deciding what counts as state, where that state lives, and when it is allowed to change. Almost every serious React performance problem and almost every hard-to-reproduce bug traces back to one of those three decisions rather than to React itself.
The part that separates seniors from mid-levels
React re-renders by calling component functions again. When state changes, React calls the component, gets a new description of the interface, compares it with the previous description and applies the minimum set of changes to the document. Calling a component function is cheap; what is not cheap is everything a careless component does on the way through, such as building a new object on every render, sorting a large array inline, or creating a new function identity that invalidates a memoised child. A mid-level developer knows that re-renders happen. A senior one can tell you which of them actually cost anything, and can prove it with a profiler rather than guessing.
Hooks are the second thing that separates levels. useState and useEffect are easy to use and easy to misuse. The common failure is treating useEffect as a general-purpose 'run this code' hatch rather than as a way to synchronise a component with something outside React, such as a subscription or the document title. Effects that derive state from props, effects that fetch in a chain, and effects with dependency arrays that have been trimmed until the warnings stopped are the three signatures of a codebase that will be expensive to change. Ask a candidate to talk through an effect they later deleted, and you learn more than any whiteboard question will tell you.
The modern split between server and client components changes the shape of the job again. Work that runs on the server can reach a database directly and never ships its code to the browser; work that runs on the client can hold interactive state but pays for every kilobyte. Deciding which side of that boundary a piece of the interface belongs on is now a core React skill, and it is one that developers whose experience predates the split often have not had to exercise.
Where React is used
The label “React developer” covers several jobs that share a technology and little else. These are the settings the work usually turns up in, and the one you are hiring into should shape the whole process, because the judgement each demands is different.
SaaS product interfaces
Dashboards, settings, billing and admin surfaces where the same component vocabulary is reused across dozens of screens and consistency matters more than novelty.
Commerce storefronts
Category, search and checkout flows where render performance and Core Web Vitals translate directly into conversion, usually paired with server rendering.
Internal tools
Operations consoles, back-office screens and support tooling, where speed of delivery outweighs polish and component libraries do most of the work.
Financial and trading interfaces
High-frequency data views where render batching, virtualised lists and careful memoisation are the difference between usable and unusable.
Content and publishing
Marketing sites and editorial front ends built against a headless CMS, where static generation and incremental revalidation carry the traffic.
Design system implementation
Shared component libraries consumed by several product teams, where API design, accessibility and versioning matter more than any individual screen.
If a candidate's experience sits in a different row of that list from the work you have, that is not a reason to reject them, but it is the thing to probe. Ask what would be different about their approach in your setting. Someone who can answer that has transferable judgement. Someone who says it would be much the same has probably not thought about it.
Which React versions are still supported
React ships behind a stable public API and a documented release cadence. The table below is read live from public release data, so it reflects what is actually supported rather than what a job specification was written against.
React does not publish dated end-of-life commitments for its release lines in the way a language runtime or an operating system does, so the table below gives release dates and the latest patch on each line rather than a support window. In practice the support boundary is set by the ecosystem rather than by a policy: once the major libraries around it drop a line, staying on that line gets expensive whether or not anyone has declared it dead.
| Release | Released | End of life | Status | Latest patch |
|---|---|---|---|---|
| 19 | 2024-12-05 | none published | No published end-of-life date | 19.3.0 (2026-09-09) |
| 18 | 2022-03-29 | none published | No published end-of-life date | 18.3.1 (2024-04-26) |
| 17 | 2020-10-20 | none published | No published end-of-life date | 17.0.2 (2021-03-22) |
| 16 | 2017-09-26 | none published | No published end-of-life date | 16.14.0 (2020-10-14) |
| 15 | 2016-04-07 | none published | No published end-of-life date | 15.7.0 (2020-10-14) |
Source: endoflife.date public release data, read 2026-09-25.
Two questions follow from this table in an interview. The first is which line the candidate has most recently shipped against, because someone whose last production work was on an unsupported line has not had to deal with the changes since. The second is how they have handled an upgrade. Version migrations are where you see whether a developer reads release notes, writes characterisation tests before changing anything, and knows how to stage a rollout, or whether they upgrade in place on a Friday and hope.
The toolchain around it
Nobody hires for React alone. The surrounding tools are where most of the day-to-day work happens, and a gap in any of them costs more time than a gap in the core library. This is the set that turns up most often on real job specifications alongside it.
- TypeScript
- Types on props, state and API responses. Effectively the default in new work; untyped React is now the exception.
- Next.js
- The most common framework wrapper, supplying routing, server rendering and the server-component boundary.
- Vite
- Build tool and dev server for applications that do not need a full framework.
- TanStack Query
- Server-state caching, revalidation and request deduplication, replacing most hand-rolled fetching effects.
- Redux Toolkit or Zustand
- Client state that genuinely needs to be shared widely, after simpler options have been ruled out.
- React Hook Form with Zod
- Form state and schema validation shared between client and server.
- Testing Library with Vitest or Jest
- Behaviour-level component tests that assert what a user sees rather than internal state.
- Playwright
- Browser-level end-to-end tests over the flows that actually earn money.
Related skills that frequently appear on the same specification: Node.js, GraphQL, Next.js, TypeScript, React Native.
What to test in an interview
These are the topics that separate candidates in practice. Each one is given with why it discriminates, what a strong answer sounds like, and the response that should make you slow down. None of them requires a whiteboard.
Where state should live
Almost every architectural problem in a React codebase is a state-placement problem wearing a disguise.
- Strong answer: Distinguishes server state from client state, keeps state as local as it can be, and can name a time they moved state down rather than up.
- Warning sign: Reaches for a global store by default, or describes context as a performance tool.
useEffect and what does not belong in it
Effect misuse is the most reliable predictor of a codebase that is hard to change.
- Strong answer: Can name things that should not be effects: derived values, event responses, fetch chains. Talks about cleanup and race conditions.
- Warning sign: Describes effects as 'where you put the code that runs after render' and has never removed one.
Re-render cost and how they measured it
Separates people who have optimised from people who have read about optimising.
- Strong answer: Names the profiler, describes a specific fix, and can say what the measurement was before and after.
- Warning sign: Wraps everything in memo on principle, or cannot describe a case where memo made no difference.
Server and client component boundaries
The current dividing line in React work, and a real gap in older experience.
- Strong answer: Explains what crosses the boundary, why props must be serialisable, and how they decide which side something belongs on.
- Warning sign: Treats the two as interchangeable, or cannot explain why a hook fails in a server component.
Accessibility in practice
Usually the first thing dropped under deadline, and expensive to retrofit.
- Strong answer: Talks about focus management, keyboard paths through dialogs, and labelled controls as part of building rather than as an audit.
- Warning sign: Equates accessibility with adding ARIA attributes.
Testing strategy
Reveals whether they have maintained an application or only shipped one.
- Strong answer: Tests behaviour over implementation, keeps end-to-end tests few and aimed at revenue paths, and can explain what they choose not to test.
- Warning sign: Quotes a coverage percentage as the goal.
A React decision they now regret
The single most informative question in a front-end interview.
- Strong answer: Gives a specific decision, the constraint that produced it, and what it cost later.
- Warning sign: Cannot produce one, or blames the framework.
Warning signs in a React codebase
The fastest way to read a candidate is to ask what they have found wrong in code they inherited. These are the patterns that come up most often, what they cost, and what fixing them looks like. A developer who recognises three or four of these from their own experience is worth more than one who can recite the documentation.
Deriving state in an effect
- What you see: useState plus useEffect where a plain calculation during render would do.
- What it costs: An extra render pass, a window where the two values disagree, and a bug class that only shows under slow networks.
- The fix: Calculate during render. Reach for useMemo only when profiling shows the calculation is actually expensive.
Global store as a default
- What you see: Every value lives in Redux or a context, including values used by one component.
- What it costs: Unrelated components re-render, ownership becomes unclear, and changing anything means reading the whole store.
- The fix: Start local. Promote state only when a second consumer genuinely appears, and separate server state into a query cache.
Dependency arrays trimmed to silence warnings
- What you see: Effects that reference values not listed as dependencies.
- What it costs: Stale closures producing bugs that reproduce only on a colleague's machine.
- The fix: Treat the linter as correct. If the honest dependency list causes a loop, the effect is modelling the wrong thing.
Memoising everything
- What you see: memo, useMemo and useCallback applied uniformly across the codebase.
- What it costs: More code to read, comparison work on every render, and no measurable gain.
- The fix: Profile first. Apply memoisation at the few boundaries where the profile shows a cost.
Prop drilling through many layers
- What you see: A value passed through five components that do not use it.
- What it costs: Every intermediate component has to change when the shape changes.
- The fix: Compose with children, or introduce context at the one place a genuinely shared value is read.
Fetch waterfalls
- What you see: A component fetches, then a child fetches from the result, then a grandchild fetches again.
- What it costs: Load time that is the sum of every request rather than the longest one.
- The fix: Hoist the data requirement, fetch in parallel, or move the work to the server where it can be one round trip.
What each level can own
Job titles are not comparable between companies, so it is more useful to describe levels by what a person can be left to own without supervision. These are the boundaries we use when we assess a React developer.
- Junior
- Builds screens from an existing component library against a defined API. Needs the state shape decided for them. Reviews catch effect misuse and missing loading and error states.
- Mid-level
- Owns a feature end to end, including its data fetching, error states and tests. Can read a profiler. Still benefits from review on where state should live and on accessibility.
- Senior
- Owns the shape of an area of the application. Decides the server and client boundary, sets the data-fetching pattern, and can justify those choices against the alternatives. Raises the level of the people reviewing with them.
- Staff
- Owns cross-cutting concerns: the design system contract, the rendering strategy, the performance budget, and the migration path off whatever the codebase has outgrown. Measured by what other teams stop having to decide.
How the work is usually scoped
Team shape follows the kind of work, not the headcount you happen to have budget for. These are the shapes that come up most often and the constraint that actually governs each one.
New product front end
- Usual team: Two to three React developers with one senior setting the patterns, plus a designer.
- What governs it: The first three weeks decide the next three years. Under-staffing the senior seat here is the most expensive saving available.
Design system build
- Usual team: One senior React developer plus a designer, part-time accessibility review.
- What governs it: Scoped by component count and by how many consuming teams have to be kept working, not by screens.
Performance remediation
- Usual team: One senior React developer, time-boxed.
- What governs it: Starts with measurement. Any proposal that begins before a profile exists should be rejected.
Legacy migration
- Usual team: Two developers, one of whom knows the outgoing stack.
- What governs it: Runs far longer than estimated whenever the old application has no tests. Budget for characterisation tests first.
Feature team augmentation
- Usual team: One to three mid or senior developers joining an existing team.
- What governs it: The constraint is the client's review capacity, not the developer count.
Migration work you may actually be hiring for
A large share of React work is not new development. It is moving an existing system from one state to another while it stays in service. These are the migrations that come up most often, and each one asks for a different kind of experience from the person you hire.
Class components to function components with hooks
- Why teams do it: Hooks are where the ecosystem, the documentation and every new library now live, so class components get progressively harder to staff and to integrate with.
- What to watch: Lifecycle methods rarely map one-to-one onto effects. A mechanical translation of componentDidUpdate into useEffect reproduces the old behaviour and the old bugs. The migration is worth doing component by component, with tests written before each one moves.
Client-rendered single-page application to a server-rendered framework
- Why teams do it: Search visibility, first-load performance and the cost of shipping a large JavaScript bundle to every visitor. For commerce and content sites this is usually a revenue argument rather than a technical one.
- What to watch: Code that assumed a browser exists will break on the server: direct window access, browser-only libraries and state held in module scope. Budget for the data layer too, because fetching patterns that were acceptable in the browser often become the bottleneck once rendering is on the server.
Redux as the single store to a query cache plus local state
- Why teams do it: Most of what sits in a typical Redux store is server data that the store was never designed to keep fresh. Splitting server state into a cache removes a large amount of hand-written synchronisation code.
- What to watch: Do it incrementally, one domain at a time, with both in place. Teams that attempt it in one pass usually stall halfway and end up maintaining two patterns permanently, which is worse than either.
JavaScript to TypeScript
- Why teams do it: Refactoring confidence and a contract at the API boundary. The payoff grows with the size of the team rather than the size of the codebase.
- What to watch: Turning strictness on everywhere at once produces thousands of errors and kills the effort. Migrate file by file with strict settings from the start on new files, and treat any use of a permissive escape hatch as debt that is written down rather than forgotten.
Migration work rewards a different temperament from greenfield work. The useful question in an interview is not whether someone has done the specific migration you face, but whether they have ever run one incrementally: behind a flag, with both paths live, and with a way back. Developers who have only done big-bang cutovers tend to propose them again.
What a good brief for this role contains
Most of the time lost in hiring a React developer is lost before anyone is interviewed, in the gap between what the brief says and what the team actually needs. These are the points that, for this technology specifically, change who the right candidate is. A brief that answers them can be matched in days. One that does not produces a shortlist that looks reasonable and converts badly.
- Whether the application renders on the server, in the browser, or both. This single answer changes which half of the candidate pool is relevant.
- What the data layer is: REST, GraphQL, a typed client, or direct database access from server components. Fetching patterns are where most of the day goes.
- Who owns design, and whether a component library already exists. A developer building against an established design system is doing a different job from one inventing it.
- What the accessibility obligation is. Public-sector work, regulated industries and enterprise procurement carry requirements that need to be designed in, not audited in later.
- Which browsers and devices genuinely have to work, and whether there is a performance budget anyone is measuring against.
- Whether the work is new development, maintenance of something that exists, or a migration. These reward different people and the brief usually leaves it implied.
If you cannot answer some of these yet, that is normal and it is still worth writing down which ones are open. An unknown that is named can be worked around. An unknown that is papered over in a job specification turns into a rejected shortlist and a restart four weeks later.
What the US market pays for this work
React work is counted by the US Bureau of Labor Statistics under Software Developers. That classification is broader than the technology itself, so treat the figures as the shape of the market a React developer is hired into rather than as a rate card for the skill. Across the United States the Bureau counts 1,687,890 people in this occupation, with a median annual wage of $135,980.
The spread matters more than the midpoint. The 90th percentile is about 2.6 times the 10th, which is a wide band for a single occupation and tells you that the title on its own carries very little pricing information. Two people described as a React developer can sit at $82,460 and $214,670 in the same national dataset. When a budget is set from a median without asking which end of that range the work actually needs, the hire that follows is usually the wrong one in one direction or the other.
Related classifications are worth reading alongside it, because teams hiring for React frequently end up recruiting against these titles too:
| Occupation | Employed | 25th percentile | Median | 75th percentile | 90th percentile |
|---|---|---|---|---|---|
| Software Developers | 1,687,890 | $105,210 | $135,980 | $171,980 | $214,670 |
| Web Developers | 70,190 | $64,230 | $92,650 | $126,230 | $162,290 |
Source: BLS Occupational Employment and Wage Statistics, May 2025. Figures cover all US employers and are not FuturByte rates.
These are employer-side wage figures for people on a US payroll. They exclude employer taxes, benefits, recruitment cost and the months a seat sits empty, all of which are real and none of which appear in a salary line. The useful way to read the table is as the cost of the alternative you are comparing against, not as a number to match.
How US metro markets compare for this role
The same job is priced very differently across the country. Ranked by median annual wage for Software Developers, the gap between the highest and lowest of the 28 metro areas covered here is a factor of about 1.7. San Jose sits at the top with a median of $213,110; Pittsburgh sits at the bottom with $124,500. A budget built from a national median will be wrong in both of those markets, in opposite directions.
| Metro area | Employed | Median wage | vs US median | Location quotient |
|---|---|---|---|---|
| San Jose, CA | 87,350 | $213,110 | +57% | 7.09 |
| San Francisco, CA | 69,030 | $186,640 | +37% | 2.68 |
| Seattle, WA | 92,770 | $167,280 | +23% | 4.10 |
| New York, NY | 121,000 | $166,830 | +23% | 1.17 |
| Boston, MA | 42,310 | $166,090 | +22% | 1.44 |
| San Diego, CA | 20,610 | $163,270 | +20% | 1.23 |
| Los Angeles, CA | 55,540 | $160,920 | +18% | 0.82 |
| Portland, OR | 18,260 | $156,000 | +15% | 1.39 |
| Washington, D.C. | 69,060 | $154,930 | +14% | 2.03 |
| Baltimore, MD | 16,850 | $138,900 | +2% | 1.14 |
| Denver, CO | 27,010 | $137,610 | +1% | 1.55 |
| Charlotte, NC | 20,820 | $135,920 | 0% | 1.41 |
| Chicago, IL | 40,370 | $134,380 | -1% | 0.82 |
| Austin, TX | 31,960 | $134,120 | -1% | 2.28 |
| Dallas-Fort Worth, TX | 67,030 | $133,290 | -2% | 1.52 |
| Philadelphia, PA | 28,480 | $133,040 | -2% | 0.91 |
| Atlanta, GA | 36,300 | $132,960 | -2% | 1.16 |
| Raleigh, NC | 12,580 | $132,770 | -2% | 1.56 |
| Miami, FL | 18,900 | $132,650 | -2% | 0.62 |
| Phoenix, AZ | 29,380 | $131,750 | -3% | 1.14 |
| Minneapolis-St. Paul, MN | 27,410 | $130,920 | -4% | 1.29 |
| Detroit, MI | 24,870 | $130,760 | -4% | 1.20 |
| Tampa, FL | 14,230 | $130,450 | -4% | 0.91 |
| Orlando, FL | 13,440 | $129,620 | -5% | 0.88 |
| Salt Lake City, UT | 19,040 | $129,600 | -5% | 2.12 |
| Houston, TX | 22,940 | $129,440 | -5% | 0.64 |
| Kansas City, MO | 12,160 | $124,990 | -8% | 1.02 |
| Pittsburgh, PA | 10,320 | $124,500 | -8% | 0.85 |
Location quotient compares how concentrated this occupation is in the metro against the national average. A value above 1 means the metro has more of this work than its size would predict.
The location quotient column is the more useful one for hiring. A high median tells you what a role costs; a high quotient tells you whether the people exist. San Jose, San Francisco, Seattle, Washington, D.C., Denver, Austin each have a quotient of 1.5 or above, meaning the work is concentrated there well beyond what the size of the local economy would predict. Those are the markets where a search is likely to be quick and competitive at the same time, and where a counter-offer is most likely to take a candidate off the table late in the process.
The opposite case is worth planning for too. In a metro with a low quotient, the total pool is small even when wages look reasonable, so the realistic options are to widen the search radius, accept a longer time to hire, or bring the capability in from outside the local market entirely. That last option is what most teams are weighing when they come to us.
Hiring risks worth naming
Every one of these has produced a bad hire somewhere. They are written down so that the process tests for them deliberately rather than discovering them in month three.
React experience that is entirely client-rendered. Test the server and client boundary explicitly. This is the most common gap in otherwise strong candidates.
Framework knowledge without JavaScript depth. Ask about closures, equality and asynchrony directly. React papers over these until it does not.
No accessibility practice. Ask for a keyboard path through a dialog they built. Retrofitting accessibility costs several times what building it in costs.
Never having maintained what they built. Ask what broke six months after launch. Developers who have only ever shipped greenfield work carry decisions that do not survive contact with change.
Hiring React developers by metro area
Wages for this occupation vary more between US metro areas than most budget models assume. Each page below sets out the published employment and wage figures for that market, how it compares with the national picture, and what the local industry mix means for the kind of React developer who will be available.
- New York, NY $166,830 median
- Seattle, WA $167,280 median
- San Jose, CA $213,110 median
- Washington, D.C. $154,930 median
- San Francisco, CA $186,640 median
- Dallas-Fort Worth, TX $133,290 median
- Los Angeles, CA $160,920 median
- Boston, MA $166,090 median
- Chicago, IL $134,380 median
- Atlanta, GA $132,960 median
- Austin, TX $134,120 median
- Phoenix, AZ $131,750 median
- Philadelphia, PA $133,040 median
- Minneapolis-St. Paul, MN $130,920 median
- Denver, CO $137,610 median
- Detroit, MI $130,760 median
- Houston, TX $129,440 median
- Charlotte, NC $135,920 median
- San Diego, CA $163,270 median
- Salt Lake City, UT $129,600 median
- Miami, FL $132,650 median
- Portland, OR $156,000 median
- Baltimore, MD $138,900 median
- Tampa, FL $130,450 median
- Orlando, FL $129,620 median
- Raleigh, NC $132,770 median
- Kansas City, MO $124,990 median
- Pittsburgh, PA $124,500 median
Frequently asked questions
Do I need a React specialist or a full-stack developer?
If the interface is the product, hire a React specialist. If the front end is a thin layer over a substantial back end, a full-stack developer who is strong on the server and competent on the client is usually the better value. The failure mode to avoid is hiring a full-stack developer and expecting specialist front-end judgement on state, rendering and accessibility.
Is React still the right choice for a new project?
For most commercial web applications, yes, mainly because the hiring pool and the component ecosystem are larger than for any alternative. The honest caveat is that React is a bigger commitment than it looks: you are also choosing a framework, a data layer and a state approach, and those decisions matter more than the library.
How much does React experience transfer to React Native?
The component model, hooks and state thinking transfer directly. Layout, navigation, platform APIs, build tooling and release process do not. Budget several weeks for a strong React developer to become productive in React Native, and do not assume the reverse transfer is automatic either.
Should I test React skill with a take-home or a live session?
A short live session on a real codebase beats a take-home for signal per hour, because you see how someone reads unfamiliar code and what they ask. If you do set a take-home, keep it under two hours and pay for it. Long unpaid take-homes filter for availability rather than ability.
How do I tell a senior React developer from a mid-level one?
Ask what they removed. Mid-level developers describe what they added; senior ones describe a store they deleted, an effect they replaced with a calculation, or a dependency they took out. The ability to make a codebase smaller is the clearest seniority signal in front-end work.
What does a React developer need from us to be productive?
A running local environment on day one, a designated reviewer, access to the real API rather than a mock, and a decision about who owns design. Teams that supply the first three and skip the fourth lose more time to rework than to anything technical.
Can one React developer own a whole front end?
For a focused product, yes, and a senior developer often should. The risk is not capacity but single-point knowledge. Pair them with a reviewer from the start, even a part-time one, so that the decisions are written down somewhere other than one person's head.
How long before a new React developer is contributing?
On a well-documented codebase with a running environment, a senior developer opens useful pull requests within the first week. On an undocumented codebase with a manual setup, the same person can spend three weeks before their first merge. The difference is almost entirely on the hiring side.