Senior frontend coding rounds rarely ask for red-black trees. They ask you to write a debounce that handles the edge cases, orchestrate async work with a concurrency limit, build an accessible autocomplete in Vue in forty minutes, add a validated API route with a page that consumes it, or pair on a refactor while explaining your reasoning. The material is the everyday craft; the difference at senior level is that your code is correct on the edges, typed, tested in your head, and narrated.
null), clarity (naming, small functions, types), communication, handling of feedback, and knowledge of the platform (built-ins you reach for: structuredClone, Map, AbortController, Intl, Object.groupBy, Array.fromAsync, Promise.withResolvers).<script setup lang="ts"> with typed props and emits, defineModel, composables for logic, no reactivity leaks (toRef/toValue for arguments, cleanup in onScopeDispose), accessibility by default (labels, roles, keyboard), and awareness of SSR when the sandbox is Nuxt.useFetch/useAsyncData with keys, server/api with validation and createError({ status }), useState instead of module state, middleware for redirects, routeRules for caching, and nuxt-auth-utils for sessions.| Page | Drill |
|---|---|
| JavaScript utilities | debounce, throttle, memoize, deep equal, deep merge, groupBy, chunk, once, event emitter, LRU cache, pick/omit, retry |
| Async and data processing | concurrency pool, promiseAll by hand, timeout, retry with backoff, cancellation, in-flight dedupe, async iteration, tree ↔ flat list, normalisation |
| Vue component drills | todo with filters, autocomplete, modal with focus trap, tabs, data table, infinite list, form with validation, useDebounce, useLocalStorage, useIntersectionObserver |
| Nuxt drills | validated API route plus page, auth middleware and session, error page, SEO route, cached route rules, plugin, shared state, mini layer |
| Algorithms at frontend depth | complexity, hashing, two pointers, sliding window, stacks and queues, trees and DOM traversal, recursion, binary search, tries, light dynamic programming |
| Take-home and pairing | scoping, README, tests, commits, code review drills, refactoring, pairing etiquette, the evaluator's rubric |
The five-step live-coding script, with a worked debounce:
1. Restate "debounce(fn, wait) returns a function that delays fn until wait ms have passed without a call;
each call resets the timer; the last arguments win; `this` is preserved; and it exposes cancel/flush."
2. Interface function debounce<T extends (...args: any[]) => void>(fn: T, wait: number): T & { cancel(): void; flush(): void }
3. Simplest correct timer + clearTimeout + setTimeout(fn.apply(this, args))
4. Walk through calls at t=0, 50, 120 with wait=100 → fn runs once at t=220 with the t=120 args
5. Improve + tests cancel, flush, leading option; tests with fake timers: resets, last-args, cancel, flush, `this`
export function debounce<T extends (...args: any[]) => void>(fn: T, wait: number) {
let timer: ReturnType<typeof setTimeout> | undefined
let pending: { args: Parameters<T>, self: unknown } | undefined
const debounced = function (this: unknown, ...args: Parameters<T>) {
pending = { args, self: this }
clearTimeout(timer)
timer = setTimeout(debounced.flush, wait)
} as T & { cancel: () => void, flush: () => void }
debounced.cancel = () => { clearTimeout(timer); timer = undefined; pending = undefined }
debounced.flush = () => {
if (!pending) return
const { args, self } = pending
debounced.cancel()
fn.apply(self, args)
}
return debounced
}
Reaching for a clever one-liner or an O(n) approach before the straightforward version works is how candidates run out of time with nothing to show. Correct first, then better, and say that this is your plan.
"I restate the problem and list the edge cases, agree on the interface with types and what happens on empty input and errors, then write the simplest version that is correct and walk through it with a concrete example. Only then do I improve it: complexity, cancellation, accessibility, or whatever the problem rewards. I narrate the whole time so the interviewer can steer, and I finish by naming the tests I would write. At a senior level the code has to be right on the edges and readable; the clever version can come after."
Nothing yet. Notes filed here show up on every page of this section.
Developer experience and debugging
Nuxt DevTools and what it reveals, debugging SSR and Nitro code with breakpoints, source maps and the Node inspector, HMR and dev-server troubleshooting, environment files and per-environment config, reproducible local environments, onboarding in ten minutes, scripts and generators, and a debugging method for the classic Nuxt failures.
JavaScript utilities
The utility-function drills that recur in senior frontend interviews — debounce and throttle, memoize, once, deep equal, deep clone and deep merge, groupBy and chunk, pick and omit, an event emitter, an LRU cache, retry — each with the edge cases that separate a working answer from a senior one, typed implementations and the built-ins that replace hand-written code in 2026.