Skip to content

Frontend engineering in a Staff interview

Our hard frontend questions cross a boundary: the browser and a proxy, one release and the next, a component library and the apps built on it. At Staff they test whether you can follow a change past the layer it was made in.

An axis of our Staff fullstack target.

The check comes with every pass, covers all 12 competencies of our Staff fullstack target, and takes about 24 minutes. It reports each one as Ready, Borderline or a Gap for this level. It never predicts a pass.

Patterns our questions are designed to test at Staff

These are the distinctions the questions on this axis are written to separate — our judgement from writing them and having them reviewed, not a measurement of candidates. We have run no study, so nothing here is a statistic and none of it is phrased as one.

  1. 1.

    Two builds running at once

    After a deploy, tabs opened earlier still run the previous build and import its hashed chunks. A deploy that deletes those chunks, or a service worker that activates early and clears the old cache, breaks any of those tabs that still has a chunk to load. Our questions ask what an old tab requests after a release and what still holds the answer.

  2. 2.

    A trade-off reported as a win

    In one of our questions, server rendering puts the LCP image in the first response and cuts LCP by more than a second, while interactivity stays where it was because hydration waits for the same bundle. Our Staff questions ask for both numbers, and an answer that reports only the one that improved has left out half of the decision.

  3. 3.

    Safe by the types, breaking by the behaviour

    A patch release of a design system dropped type="button", and every button inside a form began submitting it, with all visual tests green. Defaults are part of a component's contract, and our questions ask what a release changes for the code that consumes it.

  4. 4.

    Same site is not same origin

    SameSite=Strict compares sites, the scheme plus the registrable domain, so https://files.example.com is same-site with https://app.example.com while being a different origin, and a form an uploaded page submits to the app carries its cookie. Our questions put user content, a CDN and a login popup beside the app and ask which boundary each check enforces: the origin, the site, or none.

What a strong answer sounds like: A strong answer says which other layer the change reaches and what that layer does with it, before it calls the change safe.

How the check measures it

3 questions drawn on this axis alone — 1 medium and 2 hard for a Staff target, because the bar is the level. Hard counts for one and a half times a medium, which is what makes the verdict relative:

Medium rightHard rightVerdict
1 of 12 of 2Ready
0 of 12 of 2Ready
1 of 11 of 2Borderline
0 of 11 of 2Gap
1 of 10 of 2Gap
0 of 10 of 2Gap

Three questions is coarse and the report says so beside every verdict. It is enough to separate this axis from the others in your target, which is what the check is for — there is no total, no percentage and no single number anywhere in the report.

What there is to practise

67 questions on this axis
46 medium, 21 hard. Easy is not drawn for a Staff target.

Every answer cites the source it was checked against.

Drawn from Frontend & React (78).

Practised in the Technical deep dive round
How things actually work and why they fail: networking, concurrency, performance, security, and diagnosing a symptom to its mechanism.

Practice is arranged by interview round rather than by topic, so you can work through it one round at a time.

Questions here most often also test performance, code quality & design, caching and security. Few questions on this axis test it alone, which is why the check reports every competency separately rather than averaging them.

One of them, in full

A question from the free demo, not written for this page. A demo quiz opens with it; the answer, the explanation and the source come when you submit — no account needed.

Frontend engineeringhard

An offline-capable app serves /app.js — the same name every release — and /sw.js, both with Cache-Control: max-age=86400. On install, the service worker calls self.skipWaiting(), opens a cache named for the release, app-v41, and calls cache.addAll(['/app.js']); on activate it deletes every other cache, and it answers fetches cache-first. After release 42 — new app.js, and an sw.js that names app-v42 — users who opened the app the day before are controlled by release 42's worker yet run release 41's code. Which explanation and change are right?

Answer it on the demo

One axis is not the loop

This axis is one of 12 in our Staff fullstack target, and being strong here says nothing about the others. The check covers all of them in one sitting and reports each separately, so what comes back is a profile rather than a score.