Check what you actually know
97 quizzes. Every answer explained as you go, with a reference — and no account needed.

Next.js Parallel & Intercepting Routes: Modals Done Right
How Next.js parallel routes (@slot) and intercepting routes ((.), (..), (...)) combine to build shareable, refreshable modals — verified against Next.js 16.3.
Take the quiz →
The Star Rating That Never Reaches Your Server
A custom <star-rating> element sits inside a <form>, looks like a form field, and gets left out of the submission entirely. The browser has a real fix for this — most teams reach for a hack instead.
Take the quiz →
Vue nextTick Explained: How DOM Updates Are Batched
How Vue batches reactive writes into one DOM update, why the DOM looks stale right after a change, and how nextTick and watch's flush option fix it.
Take the quiz →
The 'Read Aloud' Button That Only Works on the Second Click
A text-to-speech button that works perfectly every time you test it — and silently fails or picks the wrong voice for a real visitor's first click. The bug is a timing race baked into the Web Speech API that most code never accounts for.
Take the quiz →
useAsyncData Keys in Nuxt: Caching, Dedupe & the Sharing Bug
Learn how Nuxt's useAsyncData and useFetch generate cache keys, how dedupe (cancel vs defer) really works, and why wrapper composables silently share data.
Take the quiz →
The Search Highlight That Deletes Your Selection
A search-highlight feature that rebuilds its DOM on every keystroke can wipe out a user's own text selection with no warning. The CSS Custom Highlight API fixes it by styling text ranges without ever touching a DOM node.
Take the quiz →
My .catch() Never Ran. The Bug Was Two Lines Above It
A function that sometimes throws synchronously instead of returning a promise will skip every .catch() chained to it — because the promise never gets created. Promise.try() fixes it, and does one thing try/catch can't.
Take the quiz →
NestJS Module Encapsulation Explained (with Cheat Sheet)
How NestJS module boundaries actually work: what exports really cross, why @Global() isn't a shortcut, and how forwardRef breaks circular module dependencies.
Take the quiz →
NestJS Dependency Injection Explained (with Cheat Sheet)
How the NestJS DI container resolves providers: tokens, module scope, singleton vs request vs transient, and why 'singleton' can still mean two instances.
Take the quiz →
Stop Regex-Parsing document.cookie. Use CookieStore
document.cookie hands you one flat string and no way to know when it changes. The Cookie Store API gives you async get/set/delete and a change event — but its set() defaults to a stricter SameSite than the one you're used to.
Take the quiz →
addDays() Mutated a Date Three Components Away From Where I Called It
A date utility that calls .setDate() and returns the same object looks pure. It isn't — Date is mutable, so the caller and everyone else holding that reference get changed out from under them. Temporal, now shipping in real browsers, fixes it by making dates immutable.
Take the quiz →
React Form Actions: useActionState & useFormStatus Guide
How React 19 form Actions manage pending state automatically — useActionState, useFormStatus, and useOptimistic explained with the bug they replace.
Take the quiz →
I Shipped 'Passwordless Login.' It Still Asked for a Username.
WebAuthn's own demo code creates a credential the browser can't find on its own — so your passkey button quietly turns into a fancier security key instead of an actual passwordless sign-in. One option fixes it.
Take the quiz →
Those Share Buttons Are Guessing What's On My Phone
Every blog footer hardcodes the same row of share icons — X, Facebook, copy link — and none of them know what's actually installed on your phone. The Web Share API hands the job to the OS instead, and it can do something a custom row never could: share an actual file.
Take the quiz →
Next.js Server Actions: Mutations & Security (Cheat Sheet)
Next.js Server Actions look like plain functions but compile to public POST endpoints. Learn the mutation flow, built-in CSRF checks, and the auth you owe.
Take the quiz →
Your Required Field Turns Red Before You Type Anything
A signup form's email input shows a red border the instant the page loads — before the visitor has typed a single character. The obvious CSS causes it, and the obvious fix is a native pseudo-class nobody reaches for first.
Take the quiz →
Web Workers in JavaScript: The Complete Guide
Learn JavaScript Web Workers step by step: message passing, transferable objects, error handling, and a copy-paste cheat sheet for offloading work.
Take the quiz →
One CSS Property Replaces Your Checkbox Hack
Recoloring a checkbox to match the brand usually means appearance: none, a hand-drawn checkmark, and a rebuilt focus ring. accent-color does the same job in one line — and knowing where it stops matters as much as knowing that it works.
Take the quiz →
Your Recipe App Is Hiding a Silent Video
Cooking sites, workout timers, and boarding-pass pages used to autoplay an invisible, muted, looping video for one job only: stopping your phone from locking its screen. The Screen Wake Lock API replaces that hack with three lines of JavaScript — and it comes with one gotcha the docs bury.
Take the quiz →
React Compiler 1.0: What useMemo You Can Delete
React Compiler 1.0 is stable. Here's the re-render model it automates, which useMemo/useCallback/memo calls you can delete, and what still needs you.
Take the quiz →
Your Timer Doesn't Know You Tabbed Away
window blur feels like the obvious way to detect an idle tab, and it's wrong in ways that only show up in production. The Page Visibility API answers the actual question — can anyone see this? — so polling, timers, and video stop wasting work the moment nobody's looking.
Take the quiz →
The await That Silently Breaks navigator.clipboard.writeText()
navigator.clipboard.writeText() only works while the document is focused and the user gesture is still fresh. Any await before the call can let both expire, so a copy button fails with an uncaught NotAllowedError and nobody ever sees why.
Take the quiz →
Shadow DOM Needed JavaScript to Exist. Now It Doesn't.
attachShadow() is a JavaScript-only API with no HTML serialization, so a server-rendered web component ships an empty host element until the client hydrates it. Declarative Shadow DOM attaches the real shadow root during HTML parsing — zero JS required.
Take the quiz →
Next.js Cache Components Explained (with Cheat Sheet)
How Next.js Cache Components decide what's static, what's cached, and what streams — the use cache directive, cacheLife, and Suspense explained.
Take the quiz →
Your Router Doesn't Intercept Navigation. It Reacts To It.
Double-click a link during a slow route change and most SPA routers render two pages and settle on the wrong one — because they're listening for navigation after it already happened. The Navigation API lets you stop it before it starts.
Take the quiz →
Debounce and Throttle in JavaScript: The Complete Guide
Learn debounce and throttle in JavaScript step by step, with worked examples, edge cases, and a copy-paste cheat sheet for search, scroll, and resize.
Take the quiz →
You Don't Need a WebSocket for That Live Feed
A live notification badge, a progress bar, a dashboard counter — you reached for socket.io and started hand-rolling reconnect logic. The browser already ships a simpler API that does it for you.
Take the quiz →
Nuxt useState vs ref(): Why Server State Leaks Across Users
A module-scope ref() in Nuxt is shared by every request that hits your server. Learn why useState isolates state per user, and how to fix the leak.
Take the quiz →
Delete Your padding-bottom Aspect-Ratio Hack
For a decade the only way to keep a responsive box's shape was a padding percentage and an absolutely positioned wrapper. One CSS property replaces it — with one gotcha on real images nobody warns you about.
Take the quiz →
React Re-render vs Remount: What Actually Triggers Each
A practical guide to React re-render vs remount: what type, position, and key decide, why state resets unexpectedly, and how to force a remount.
Take the quiz →
The outline: none Debate Has Been Over Since 2020
A designer flags the ugly blue focus ring in review. An engineer deletes it with outline: none. Nobody notices the keyboard-only user who now can't tell where they are on the page.
Take the quiz →
NestJS Request Lifecycle Explained (with Cheat Sheet)
A complete guide to the NestJS request lifecycle: the exact order middleware, guards, interceptors, pipes, and filters run, and why it matters.
Take the quiz →
Your Grid Has Invisible Columns: auto-fill vs auto-fit
A responsive card grid that works perfectly with twelve items breaks with two — not from a bug, but from one word in a repeat() you copy-pasted without reading.
Take the quiz →
You're truncating bios with .slice(). Intl.Segmenter knows where the emoji actually end.
A 30-character bio limit that cuts off mid-emoji isn't a rendering bug — it's .length counting UTF-16 code units instead of what's on screen. Intl.Segmenter counts graphemes, words, and sentences the way a reader actually sees them, and every major browser supports it now.
Take the quiz →
Delete Your Auto-Resize Textarea JS. CSS Does It Now.
The scrollHeight hack everyone copy-pastes for auto-growing textareas has a one-line CSS replacement — plus the one gotcha that bites if you skip max-height.
Take the quiz →
JavaScript Closures: The Complete Guide (with Cheat Sheet)
Learn how JavaScript closures really work — lexical scope, private state, memoization, and the classic loop bug — with worked examples and a cheat sheet.
Take the quiz →
CSS Animations Can't Pause. The Web Animations API Can.
Toggling a class to restart a CSS animation works — until you need to pause it, reverse it mid-flight, or ask how far through it is. element.animate() returns an object with those methods built in, natively, in every browser you already support.
Take the quiz →
Vue Reactivity Explained: ref vs reactive (+ Cheat Sheet)
A complete guide to Vue reactivity: how ref and reactive really work, why destructuring breaks updates, when to use each, and a copy-paste cheat sheet.
Take the quiz →
JavaScript Proxy and Reflect: The Complete Guide
Learn JavaScript Proxy and Reflect from the ground up — traps, invariants, and reactive state — with worked examples and a copy-paste cheat sheet.
Take the quiz →
The CSS Selector Built to Lose Every Fight
You keep reaching for !important to override a component's styles. There's a selector that fixes this by contributing zero specificity, on purpose.
Take the quiz →
One version bump, 40 files to edit. Import maps fix that.
Bare specifiers like import _ from 'lodash' don't work in a browser without a bundler — unless you tell the browser how to resolve them yourself, in one JSON block instead of forty hardcoded URLs.
Take the quiz →Your fetch in beforeunload is silently killed. navigator.sendBeacon guarantees delivery.
When the page unloads, the browser may cancel any in-flight fetch or XHR before it completes. navigator.sendBeacon sends a POST the browser commits to delivering, even after the document is gone.
Take the quiz →
The Modal Was Open. So Was Everything Behind It.
A keyboard-only pass found a background button still worked while a modal was open — aria-hidden had hidden it from screen readers but never touched focus or clicks. One boolean attribute, inert, closes that gap in a single line.
Take the quiz →
Stop Writing Regex to Match URLs — The Browser Already Can
A service worker's route regex was missing one anchor and started caching live edit forms as if they were read-only pages. URLPattern, native since 2021, doesn't let you make that mistake.
Take the quiz →
Stop Writing Media Queries for Font Size
A design system audit found five breakpoints for one heading. clamp() replaces all of them with one line that never jumps.
Take the quiz →
I Ripped Out a Carousel Library. CSS Replaced It.
A scroll listener, a debounce, and 200 lines of carousel-library glue code — replaced by three CSS properties that snap smoother than any of it did.
Take the quiz →
Stop Writing Math.cos() in a Resize Listener
CSS learned trigonometry. Here's the radial menu that used to need a resize listener — and doesn't anymore.
Take the quiz →
I Can Finally Delete My max-height: 9999px Animation Hack
CSS transitions have never been able to animate to height: auto, because auto isn't a number the engine can interpolate. calc-size() and interpolate-size finally give it real numbers — no JavaScript, no magic-number ceiling.
Take the quiz →
Five tabs open, one refresh token — the race nobody noticed
Users with multiple tabs open triggered a silent race: every tab refreshed the same expiring auth token at once, and the server started invalidating its own sessions. navigator.locks fixes it with a real mutex, no polling or localStorage hacks required.
Take the quiz →
You copy and reverse the array to find the last match. findLast() searches from the end directly.
The usual workaround — `[...arr].reverse().find()` — allocates a full copy just to walk it backward. ES2023 added `findLast()` and `findLastIndex()` to search from the end without touching the original.
Take the quiz →English B2: mixed conditionals — when the time of the condition and the result differ
The three textbook conditionals assume the if-clause and the result share a time frame. Real regret rarely does. Mixed conditionals are how you say a past mistake still shapes today.
Take the quiz →Your fetch() in beforeunload is being silently dropped. Use navigator.sendBeacon().
Browsers cancel in-flight network requests when a page unloads. The common fix — synchronous XHR — is deprecated. `navigator.sendBeacon()` is the correct, fire-and-forget API designed exactly for this case.
Take the quiz →Spanish A2: pretérito vs imperfecto — the photo and the film
Spanish has two past tenses and they are not interchangeable. One takes a photograph of a completed event; the other films the background it happened against.
Take the quiz →
You're blocking touchmove events to contain scroll. overscroll-behavior does it natively.
When a scrollable container hits its edge, the page behind it starts scrolling too. Developers block this with JavaScript event handlers or body overflow tricks. overscroll-behavior is the CSS property that turns off scroll chaining in one line.
Take the quiz →Turkish A2: -dı vs -mış — the past you saw and the past you heard about
Turkish has two past tenses, and the choice is not about time. One says you witnessed it; the other says you did not. Getting this wrong makes you sound like you are inventing things.
Take the quiz →
You're polling setInterval to detect DOM changes. MutationObserver fires when they happen.
Watching for DOM mutations with setInterval or custom event dispatch is fragile and imprecise. The MutationObserver API delivers a callback exactly when attributes, text content, or child elements change — with full control over which types of mutations you watch.
Take the quiz →English B1: used to, would, and be used to — three things that look alike
Used to walk, would walk, and be used to walking are not variations of one structure. Two describe the past, one describes a state, and mixing them is one of the most common B1 errors.
Take the quiz →
You're importing pako to gzip data. CompressionStream does it natively.
pako is one of npm's most downloaded packages — pulled in by thousands of projects to compress data before storing or sending it. CompressionStream and DecompressionStream do the same job natively, in any modern browser and Node.js 18+, with no dependencies and native C-speed execution.
Take the quiz →Spanish A1: ser vs estar — two verbs for 'to be', and the line between them
Spanish splits 'to be' into ser and estar. The usual advice — permanent versus temporary — breaks immediately. Here is the line that actually holds.
Take the quiz →
Stop using the localStorage hack to sync browser tabs. BroadcastChannel does it natively.
Syncing state across browser tabs with localStorage events is a widely-used trick that requires JSON.stringify, event filtering, and careful cleanup. The Broadcast Channel API delivers messages between tabs directly, with none of the side effects.
Take the quiz →Turkish A1: vowel harmony — the rule that makes every ending predictable
Turkish glues endings onto words, and the vowel in the ending changes to match the word. Learn the two harmony rules and you stop memorising endings and start deriving them.
Take the quiz →
You built your modal with a <div> and a focus trap library. The native <dialog> does all of that.
The `<dialog>` element ships with focus trapping, Escape-to-close, backdrop rendering, and correct ARIA semantics — no library, no boilerplate. It's been Baseline since 2022.
Take the quiz →
Stop importing uuid. crypto.randomUUID() has been native since 2021.
The `uuid` package is downloaded hundreds of millions of times a week. Most installs exist to call uuid/v4 — exactly what `crypto.randomUUID()` does natively, with no import, no bundle cost, and guaranteed cryptographic randomness.
Take the quiz →
You're installing date-fns for 'X hours ago'. Intl.RelativeTimeFormat does it natively.
Most apps display relative timestamps — '3 minutes ago', 'last week'. Developers still reach for date-fns or moment for this. The Intl.RelativeTimeFormat API handles it natively, with full locale support and zero dependencies.
Take the quiz →
You use obj.hasOwnProperty(key) to check property ownership. It can silently fail. Object.hasOwn() is the safe replacement.
Two real cases where `obj.hasOwnProperty(key)` throws or returns wrong results — and why `Object.hasOwn(obj, key)` is the ES2022 fix that ESLint's `no-prototype-builtins` rule has been nudging you toward for years.
Take the quiz →
Container queries can check more than size — style queries let components read custom property values
Size queries react to container width. Style queries react to CSS custom property values on a container ancestor — enabling component-level theming and variant switching in pure CSS, no JavaScript involved.
Take the quiz →
You're collecting async iterable results with a for-await loop. Array.fromAsync does it in one call.
A for-await loop that pushes into an array, or the `await Promise.all([...asyncIterable])` workaround that silently fails — `Array.fromAsync` replaces both with a single awaited call. It's Baseline 2024.
Take the quiz →
Your browser renders everything, even what you can't see — content-visibility: auto fixes that
Browsers lay out and paint the entire page on load, including the 80% below the fold. `content-visibility: auto` tells the browser to skip that work for off-screen elements — and it's Baseline 2024.
Take the quiz →
CORS Explained: The Complete Guide (with Cheat Sheet)
A complete guide to CORS: the same-origin policy, preflight requests, and Access-Control-Allow-Origin headers — with worked examples and a cheat sheet.
Take the quiz →
Your UI is freezing because you never gave the browser a break
Long synchronous tasks block the main thread and make your interface unresponsive. `scheduler.yield()` is the native way to hand control back to the browser mid-task so it can paint, handle input, and resume your work exactly where it left off.
Take the quiz →
You're writing dark-mode colors twice. light-dark() fixes that.
Every `@media (prefers-color-scheme: dark)` block duplicates your color definitions. `light-dark()` lets you write both values on the same line, in the same rule, with no separate block and no build step. Baseline 2024.
Take the quiz →
You've been wrapping new URL() in try/catch. URL.parse() does it natively.
Validating an untrusted URL before parsing it used to mean a try/catch wrapper or a regex. `URL.canParse()` checks validity without constructing. `URL.parse()` parses and returns null on failure. Both are Baseline 2024 — no wrapper needed.
Take the quiz →
CSS has no native scoping. @scope changes that.
BEM, CSS Modules, and scoped component styles all exist because CSS leaks — a rule written for one component can silently affect another. `@scope` gives the cascade a lower boundary so styles stay where you put them, natively, with no build step.
Take the quiz →
Array methods are eager. Iterator helpers are lazy. Here's why that matters.
Every `.map()` and `.filter()` on an array creates a new intermediate array. Iterator helpers — built into JavaScript since 2024 — give you the same pipeline but evaluate one element at a time, with no wasted allocations.
Take the quiz →
You reach for Sass to mix colors. color-mix() does it natively.
Sass's `darken()`, `lighten()`, and `mix()` functions solved real problems CSS couldn't handle for decades. `color-mix()` is the native answer, and it ships in every modern browser with no build step required.
Take the quiz →
You hand-edit headlines to avoid orphaned words. text-wrap: balance does it natively.
The classic fix for a headline that breaks awkwardly — a manual `<br>`, a `­`, or a max-width tweak — exists because CSS had no way to distribute line breaks evenly. `text-wrap: balance` and `text-wrap: pretty` are the native answers.
Take the quiz →
You're watching window to detect element size changes. ResizeObserver watches the element itself.
A `window` resize listener only fires when the viewport changes. ResizeObserver fires whenever the element's own box changes — from content loading, parent reflow, container queries, or anything else.
Take the quiz →
You use a setTimeout to trigger CSS entry animations. @starting-style makes it unnecessary.
Before `@starting-style`, the moment an element entered the DOM was invisible to CSS — transitions had no 'before' state to interpolate from. The at-rule gives you one, natively, with no JavaScript required.
Take the quiz →
You still write finally { resource.close() }. The using keyword does it automatically.
The Explicit Resource Management proposal adds a `using` declaration that calls cleanup the moment a scope exits — normal return, early return, or throw. No more try/finally boilerplate for timers, event listeners, connections, or any other resource you need to release.
Take the quiz →
You've been doing Set math by hand. JavaScript finally shipped .union(), .intersection(), and friends.
Set has always been missing its obvious operations. ES2025 adds `.union()`, `.intersection()`, `.difference()`, `.symmetricDifference()`, and three boolean predicates — native methods that used to require four lines of spread syntax each.
Take the quiz →
You keep escaping the Promise constructor. Promise.withResolvers does it right.
The 'deferred promise' pattern — storing resolve and reject outside the constructor so you can call them later — is a daily JavaScript idiom that's always felt awkward. ES2024 added a one-liner for it.
Take the quiz →
You're rethrowing errors and losing context. Error.cause fixes that.
Every time you catch an error and rethrow a new one without forwarding the original, you lose the stack trace, the error type, and everything useful about what actually went wrong. ES2022 added `Error.cause` to fix exactly this.
Take the quiz →
TypeScript Generics: The Complete Guide (with Cheat Sheet)
Learn TypeScript generics from the ground up — generic functions, constraints, defaults, and classes — with worked examples and a copy-paste cheat sheet.
Take the quiz →
Your scroll listener fires on every pixel. IntersectionObserver fires when visibility actually changes.
Detecting whether an element is in the viewport by listening to scroll events runs an expensive layout calculation on every frame. `IntersectionObserver` is the browser-native alternative — it fires only when visibility changes, off the main thread, with no scroll handler involved.
Take the quiz →
You're using Floating UI to position your tooltip. The browser does it natively now.
CSS Anchor Positioning is Baseline 2026 — it lets any element declare itself an anchor and any floating element position relative to it in pure CSS. No JavaScript, no layout math, no ResizeObserver wiring.
Take the quiz →
Your margin-left doesn't exist in Arabic. CSS logical properties fix that.
Physical CSS properties like `margin-left` and `padding-right` break silently when a layout needs to support right-to-left languages. Logical properties replace the physical axis with a writing-mode-aware model — one codebase, every direction.
Take the quiz →
Your CSS Grid cards look misaligned. subgrid is the fix you didn't know existed.
CSS Grid controls your outer container, but its children can't participate in the same tracks. `subgrid` closes that gap — nested elements align to the parent grid's rows and columns without padding hacks, fixed heights, or JavaScript measurements.
Take the quiz →
Your .sort() is mutating state. JavaScript finally gave you the fix.
The classic array methods — sort, reverse, splice — mutate the original array, silently breaking React state updates and surprising anyone who forgot to spread first. ES2023 added four immutable counterparts: toSorted, toReversed, toSpliced, and with.
Take the quiz →
You've been writing this reduce a hundred times. Object.groupBy does it in one.
Grouping an array by a key is one of the most common data transforms in frontend code. You've been wiring it by hand with `reduce` for years. `Object.groupBy` is the native version — no helper, no library, no ceremony.
Take the quiz →
JavaScript Event Loop Explained: The Complete Guide
Learn how the JavaScript event loop really works — call stack, microtasks, and macrotasks — with worked examples, edge cases, and a cheat sheet.
Take the quiz →
You reach for Promise.all for every concurrent request. Here's when to use the other three.
`Promise.all` fails the moment any one request fails. `allSettled`, `any`, and `race` each solve a different concurrency problem — dashboard partial results, CDN failover, and timeouts. Here's the taxonomy.
Take the quiz →
Your dropdown is a div. The browser has a native popover now.
Custom dropdowns, tooltips, and menus built with stacked divs and click-outside listeners — the Popover API landed in every browser in 2024, and the baseline version is two HTML attributes.
Take the quiz →
Your TypeScript config objects are losing type information. satisfies fixes it.
Type annotations widen your object types and erase the precise values TypeScript inferred. The `satisfies` operator validates against a type without changing what TypeScript keeps — you get the check without the widening.
Take the quiz →
You've been deep-cloning objects with a JSON hack. structuredClone does it right.
JSON.parse(JSON.stringify(obj)) silently corrupts Dates, Maps, Sets, and undefined values. structuredClone is the native replacement — no library, no import, no surprises.
Take the quiz →
You kept Sass for one reason. Native CSS nesting just ended it.
CSS has supported nesting natively since 2023 — pseudo-classes, pseudo-elements, and @media queries nested inside the rules they belong to. No compiler required.
Take the quiz →
You can't transition a CSS variable. @property says otherwise.
CSS custom properties are string substitution — the browser doesn't know a number from a color. Register one with @property and it gains a real type, an initial value, and the ability to animate.
Take the quiz →
Your scroll listener is doing CSS's job
Reading progress bars, reveal-on-scroll effects, parallax — you've been writing these in JavaScript. CSS scroll-driven animations bind them directly to scroll position, off the main thread, in a handful of lines.
Take the quiz →