Taking an assessment rather than buying one? This page is written for employers. Here is the page for candidates.
Software engineering · Mid level
How to assess a Full-Stack Developer
Full-stack is a breadth claim, and a take-home measures the candidate's strongest end. Someone genuinely strong at one layer will produce a submission that runs, because they will quietly route the hard part of the problem to the layer they know — validation into the browser, aggregation into a loop over every row, state into whichever place makes the demo work. The reviewer sees a working app and infers breadth that is not there. The characteristic bad full-stack hire is not incompetent; they are confidently wrong on exactly one side of the wire, and the screen is built so that the wrong side never has to bear weight.
A full-stack developer's day is mostly not writing new code. It is opening a feature request that describes an outcome rather than a change, finding the four places in an existing codebase that will have to move, and deciding which of them should absorb the complexity. That decision — where does this belong — is the job. Everything downstream of it is typing, and typing is the part that assistance has made abundant.
The distinction matters because "full-stack" is a claim about coverage, and coverage is the hardest thing to verify by looking at output. Stack Overflow's 2025 survey found full-stack to be how 27 percent of respondents describe themselves, against 14.2 percent for back-end and 4.3 percent for front-end; whatever else that tells you, it tells you the label is doing a lot of work for a lot of people, and that a hiring manager reading it learns almost nothing about which half is real. In practice most people who use the label have a home layer and a visiting layer. That is fine — it is arguably what the role is — but the hiring risk sits entirely in how the candidate behaves in the visiting layer. Do they know they are visiting? Do they ask, or do they guess and commit?
The top quartile is separated by two behaviours that a passing test suite cannot show. The first is boundary discipline: they treat the interface between client and server as a contract with someone else, so they notice when a change to a response shape is a breaking change for a consumer they cannot see, and they say so. The weaker candidate changes the field name, updates their own caller, and considers the work finished. The second is knowing which side a bug is on. Given a symptom that appears in the browser, a strong full-stack developer spends their first two minutes deciding whether this is a rendering problem, a state problem, a serialisation problem or a data problem, and the decision is usually right. A weaker one starts editing the component, because that is where the symptom was visible.
What a hiring manager is actually trying to predict is maintenance cost across a boundary they will not be looking at. A feature built by someone with a blind spot on the data layer works on the demo dataset and becomes a support ticket eighteen months later, when the table has grown and the query that loads every row into memory starts timing out. Nobody attributes that to the hiring decision because the causal chain is too long, which is precisely why it keeps happening.
This is the role where the follow-up conversation about the candidate's own code earns the most. The sandbox task deliberately puts the hard part on the server side of a feature whose symptom is visible in the UI, and the interview afterwards asks the questions a submission cannot answer for itself: why did this validation end up in the client, what happens if a second request arrives before the first one commits, which of your two components would you delete first and what would break. A candidate who reasoned through the boundary answers all three without preamble. A candidate who assembled a working demo answers the first one, hesitates on the second, and cannot answer the third at all — and the difference takes about four minutes to surface out loud, against several hours of code review to surface on paper.
What the job actually needs
- deciding where a problem belongs in the stack
- holding a contract between client and server
- reading an unfamiliar codebase
- pragmatic scoping
- debugging across a boundary
How people fail in this seat
- solves a data problem in the browser because that end is more comfortable
- changes an API response shape and breaks a consumer
- ships a feature with no error state
- treats the database as a bucket
- cannot tell which side of the wire a bug is on
What most employers do instead
CV screen, a timed algorithm test, then a take-home that asks for a small application with a front end and a back end, reviewed on whether it runs and looks reasonable.
The assessment
About 80 minutes end to end.
The systems it runs in
One repository holding a React and TypeScript client, a Node and Express server and a PostgreSQL schema, running together under Docker Compose, with the browser DevTools network panel, the server's logs and a psql session all available in the sandbox at the same moment. The rounding defect in t1 is on the server side of that wire, and all four surfaces are one click apart, so which one the candidate opens first is a choice rather than an artefact of what was reachable.
- React
- TypeScript
- Node.js
- Express
- PostgreSQL
- Docker Compose
- Chrome DevTools
- psql
- Git
Django with React, Ruby on Rails, Laravel, or .NET with Angular. What t1 measures is which of the four surfaces is opened first and whether a hypothesis about the layer preceded it, and every full-stack environment presents the same four. Buyers get the fixture on their own stack wherever they can supply a repository that runs; the seeded volume comment — four hundred rows here, several million in production — is the part that must be carried across, because it is what makes the client-side aggregation in t2 look correct.
What the candidate actually does
| Task | What happens |
|---|---|
| Which side of the wire coding_sandbox · 20 min | A bug report with a symptom that is visible in the browser and a cause that is not: a total on a dashboard is occasionally wrong by a few cents. The candidate has the whole application — client, server, database, network tab, logs. The actual cause is a rounding decision made during serialisation on the server. Nothing is scored on the fix, which is small. The score is on the first four minutes: the sandbox records whether the candidate opened the component, the network response, the serialiser or the query first, and whether they formed a hypothesis about the layer before opening anything. The cheap path starts editing where the symptom was seen. The correct path asks which layer could produce this symptom and eliminates the others cheaply. |
| The feature whose hard part is on the other side coding_sandbox · 30 min | A feature request phrased as an outcome: the team lead wants to see the top ten customers by revenue this quarter, on the existing dashboard, with a date range picker. The seeded database has four hundred orders and a comment in the schema recording that production has several million. The fork is the layer. The cheap path — and the one a model produces when asked from the browser side — fetches all orders and aggregates them in the client, which is instant against the fixture and unusable in production. The correct path aggregates in the database, which requires reading a schema the candidate did not design and a join they have to work out. Whichever they choose, the second half of the task makes them state the choice: the endpoint they add has to have a documented response shape. |
| The consumer you cannot see written_artifact · 10 min | To build the dashboard cleanly, the natural move is to change the shape of an existing endpoint's response. That endpoint has a second consumer elsewhere in the repository — a scheduled export job — and nothing points at it. The candidate writes the short note they would post before merging: what changed in the contract, who is affected, and what they propose to do about it. A candidate who never found the second consumer writes a note saying nothing is affected, and that is the observation. |
| Interview across your own boundary live_call · 20 min | A spoken conversation over the candidate's own code. Why did this calculation end up on the side of the wire it is on — and what would move it? You validate this input in the browser; what happens when someone calls the endpoint directly? A second request arrives before the first one commits — what does the second caller read? Which of your two components would you delete first and what breaks? Then the live change: the date range picker must now support comparing two ranges side by side. Tell me what changes on the server, what changes in the client, and which of the two you would rather it were. The point of the last question is that there is no correct answer, only a defended one — and defending a placement requires having chosen it. |
The mark scheme
Each criterion is scored 1 to 5 against written anchors, and every score is reported with the excerpt that earned it. A criterion marked floored is reported as a finding rather than averaged into the total. The first is open; open any other to read its anchors in full.
Puts the work on the right side of the wireweight 0.3Chooses the layer with a stated reason grounded in the data volume, and can describe what the alternative would have cost — including the case where t…
Locates a bug before editingweight 0.2States a hypothesis about the layer, tests it with the cheapest available observation, and is on the right side of the wire inside the first four minu…
Treats the interface as someone else's contractweight 0.2Finds the consumer, states the change is breaking, and proposes an order of operations — additive field first, migrate the consumer, remove later — or…
Ownership of the layer decisionsweight 0.2Volunteers a placement they now think was wrong, and for the comparison-ranges change gives a specific split with a stated preference and the cost of …
Behaviour in the visiting layerweight 0.1Names which side is their home layer, slows down visibly on the other, checks assumptions against the code rather than asserting them, and flags the p…
How it is scored
Weighted mean of five criteria, 1-5 against the anchors, reported with the excerpt, timeline moment or transcript line behind each. Note that a submission can be fully working, visually complete and demonstrably correct against the fixture while scoring 2 on the heaviest criterion, which is the precise failure the standard full-stack take-home cannot detect.
Integrity
- AI assistance permitted and logged; the design assumes both halves were generated
- Edit timeline retained across both sides of the stack, including which side was opened first for each task
- Time split between client and server work recorded — the visiting layer usually shows in the distribution
- Same-day interview with a live requirement change over the candidate's own code
- No automated cheating verdict; the record describes behaviour, the interview tests understanding
The log describes what happened. It does not produce a cheating verdict — the follow-up conversation is the control, because a statistical accusation is not something we would ask a reviewer to defend.
What you receive
- Full diff across both layers with edit timeline
- The contract-change note as written
- Interview recording and transcript including the comparison-ranges segment
- Per-criterion score with the excerpt or timeline moment behind it
Who decides
Recommended, and the reviewer should be comfortable on both sides of the stack or the breadth criterion collapses into the reviewer's own home layer — which is the same bias the assessment exists to remove. Where only a specialist reviewer is available, have them mark their own side and record the other as unreviewed rather than guessing.
What this does not measure
This design does not measure infrastructure, deployment, or operational breadth, which many full-stack roles include; a team hiring a one-person engineering department should assess those separately. It does not measure design sense, product instinct, or the ability to work from a rough sketch with a founder. It is also, deliberately, an assessment of breadth rather than peak depth, and it will under-rate a genuine specialist — that is the intended behaviour for this role and the wrong behaviour if the seat is really a backend seat with some UI attached, so read the job description before using it. The fairness risk to monitor is that the visiting-layer criterion can read hesitancy as weakness when it is honesty; the anchors reward naming the weaker side explicitly, and reviewers should be told that a candidate who says "I am stronger on the server, so I checked this twice" scores at the top of that criterion rather than the bottom. Offer the spoken segment with captions, extra time or in written form on request, and score content only.
The word full-stack is a claim about coverage, and coverage is the single hardest property to verify from output. A candidate who is genuinely strong on one side will produce a working application every time, because they will quietly route the difficult part of any problem to the layer they know. That is not deception; it is what competent people do under time pressure. But it means the standard take-home is built so that the candidate's weaker side never has to bear weight, and the reviewer sees a working app and infers a breadth that is not there.
This design's answer is to put the hard part where the symptom is not. In t1 the symptom is a wrong number on a dashboard and the cause is a serialisation decision three layers away. In t2 the request arrives phrased as a UI feature — a picker and a table — and the entire difficulty is an aggregate query against a schema the candidate did not design, with a row-count comment sitting in the schema file recording that production is several million rows rather than the four hundred in front of them. Both tasks can be completed on the wrong side of the wire. Both completions look fine on the fixture. That is the fork, it is identical to the fork at work, and it is the reason the heaviest criterion in the rubric is about placement rather than correctness.
Assistance changes the calculus in a way that is specific to this role. Ask a model for a top-ten-customers dashboard from inside the client code and it produces a client-side aggregation, competently, because that is where the question was asked from. Ask from the server side and it produces a query. The model does not decide where the problem belongs; it answers where it was asked. Deciding where to ask is the job, and it is the part that has not become abundant. The rubric is built around that observation, and the sandbox timeline is what makes it visible — which side was opened first, where the minutes went, whether the schema comment was read at all.
The contract note in t3 is small and does an unusual amount of work. The natural implementation changes an existing response shape, and a second consumer of that endpoint exists in the repository with nothing pointing at it. Nobody is told to look. A candidate who finds it has demonstrated the behaviour that most reduces maintenance cost across a boundary nobody is watching, and a candidate who writes "no other consumers affected" has demonstrated its opposite in a single sentence that takes ten seconds to mark. Neither is a trick: unseen consumers are the normal condition of any codebase older than a year.
The interview then asks the four questions a submission cannot answer for itself, and closes with a change that has no right answer. Supporting two date ranges side by side can be done on the server or in the client and both are defensible; what is not defensible is having no preference. A candidate who made the original placement decision will say which way they would go, why, and what it costs the other side, in about ninety seconds. A candidate who assembled a working demo answers the validation question, hesitates on the concurrent-read question, and cannot answer the delete-a-component question at all. That sequence takes four minutes out loud. Reaching the same conclusion by reading the code would take an afternoon, and most hiring processes do not have one.
Sources
Every figure on this page is traceable. Where a claim could not be sourced it is stated qualitatively instead.
- Stack Overflow, 2025 Developer Survey, Developers section, roughly 49,000 respondents worldwide, developer-type question answered by 43,560, https://survey.stackoverflow.co/2025/developers
- US Bureau of Labor Statistics, Occupational Outlook Handbook, Software Developers, Quality Assurance Analysts, and Testers, 2025, https://www.bls.gov/ooh/computer-and-information-technology/software-developers.htm
See what the employer actually receives. A full report for one role, with every score shown beside the excerpt that earned it, conduct findings reported rather than averaged, and a reviewer sign-off required before any decision. No form.
Read a sample reportOr talk to us about this role