Quizzes

Check what you actually know

93 quizzes. Every answer explained as you go, with a reference — and no account needed.

Stop Writing JavaScript to Open Dialogs. `commandfor` Fixes It.
? HTML

Stop Writing JavaScript to Open Dialogs. commandfor Fixes It.

Every <dialog> and popover in your app still needs an addEventListener just to open and close — commandfor and the Invoker Commands API let the browser do it with zero JavaScript.

Take the quiz →
Stop Shipping Search Boxes With a Race Condition
? JavaScript

Stop Shipping Search Boxes With a Race Condition

Type fast into a search box wired to fetch(), and the result on screen isn't from your last keystroke — it's from whichever request happened to finish last. That's a race condition, and the fix is a one-line guard.

Take the quiz →
You're Blocking Scroll by Default. `passive: true` Fixes It.
? JavaScript

You're Blocking Scroll by Default. passive: true Fixes It.

Every touch and wheel listener you add can make the browser wait before it scrolls — because it has to check whether you'll call preventDefault(). `passive: true` tells it you won't, and scrolling stops waiting on your code.

Take the quiz →
NestJS 12.2: Why validationError.target Is Now undefined
? Nestjs

NestJS 12.2: Why validationError.target Is Now undefined

NestJS 12.2 defaults validationError.target to false, so a custom exceptionFactory reading error.target now gets undefined. The fix, plus a cheat sheet.

Take the quiz →
Stop Hacking Base64 With btoa(). toBase64() Fixes It Natively.
? JavaScript

Stop Hacking Base64 With btoa(). toBase64() Fixes It Natively.

btoa() throws on emoji, and the classic String.fromCharCode(...bytes) workaround crashes on large files. toBase64() and fromBase64() on Uint8Array fix both — no string round trip, no library.

Take the quiz →
getCurrentPosition() Has No Default Timeout. That's the Trap.
? JavaScript

getCurrentPosition() Has No Default Timeout. That's the Trap.

A "find my location" button that works instantly on your laptop and hangs forever on a phone with a weak signal isn't flaky — it's getCurrentPosition() doing exactly what its defaults tell it to do. No timeout, no cached position, and a watcher nobody told to stop.

Take the quiz →
Your Canvas Is Freezing the Page. OffscreenCanvas Fixes That.
? JavaScript

Your Canvas Is Freezing the Page. OffscreenCanvas Fixes That.

Click a button while your canvas animation is running and the whole page stalls — because the pixels it draws, your layout, and your input handling all queue up on the same main thread. OffscreenCanvas moves the drawing itself into a worker, so the UI keeps responding no matter how much canvas work is happening.

Take the quiz →
Next.js 16.4 ensureStatic: Locking Routes Fully Static
? Nextjs

Next.js 16.4 ensureStatic: Locking Routes Fully Static

Next.js 16.4 stabilizes ensureStatic: lock a route's shell, prefetch, or full navigation to static output at build time, with a copy-paste cheat sheet.

Take the quiz →
React Activity Component: The State Between Render and Remount
? React

React Activity Component: The State Between Render and Remount

React's Activity component hides a subtree without unmounting it — what state, effects, and renders actually do, plus a copy-paste cheat sheet.

Take the quiz →
Vue provide/inject: Why You Should Never Skip readonly()
? Vue

Vue provide/inject: Why You Should Never Skip readonly()

Vue's guide says wrap provide() state in readonly() — most tutorials skip it. The mutation bug that causes, verified against Vue 3.5, plus a cheat sheet.

Take the quiz →
I Deleted My Scroll-Lock Library's Ugly Hack. `scrollbar-gutter` Replaces It.
? CSS

I Deleted My Scroll-Lock Library's Ugly Hack. scrollbar-gutter Replaces It.

Opening a modal shifts your whole page sideways because the scrollbar vanishes with it — the bug every scroll-lock library papers over with a JS width measurement and a padding-right hack. `scrollbar-gutter: stable` fixes it in one line now that Safari finally caught up.

Take the quiz →
Stop Hardcoding Color Variants. Relative Color Syntax Does It.
? CSS

Stop Hardcoding Color Variants. Relative Color Syntax Does It.

A design system ships one brand color and four hand-picked hex variants for hover, pressed, border, and tint. Change the brand color and four of those five silently go stale. CSS relative color syntax derives every variant from the one color you actually update.

Take the quiz →
You're Writing Mouse and Touch Handlers. Pointer Events Does Both.
? JavaScript

You're Writing Mouse and Touch Handlers. Pointer Events Does Both.

A draggable card that works with mousedown/mousemove on desktop and breaks the moment you test it on a phone. The fix isn't a second set of touch listeners — it's deleting the mouse ones and switching to Pointer Events, which was built to handle mouse, touch, and pen as one input.

Take the quiz →
NestJS 12: @Optional() Not Inherited by a Redeclared Constructor
? Nestjs

NestJS 12: @Optional() Not Inherited by a Redeclared Constructor

NestJS 12 stops inheriting @Optional() once a subclass redeclares its own constructor — not when it has none at all. Cheat sheet included.

Take the quiz →
Stop Using a JS Masonry Library. CSS Grid Lanes Does It Natively.
? CSS

Stop Using a JS Masonry Library. CSS Grid Lanes Does It Natively.

Masonry layouts have meant a JS library or a CSS column-count hack that scrambles reading order ever since Pinterest made the look popular. CSS Grid Lanes finally does it natively — here's the real support story and how to ship it today.

Take the quiz →
font-display: swap Fixes Invisible Text. It Also Shifts Your Layout.
? CSS

font-display: swap Fixes Invisible Text. It Also Shifts Your Layout.

Setting font-display: swap kills the flash of invisible text, so most teams call the font-loading problem solved and move on. It doesn't — it just trades FOIT for a layout shift Lighthouse will happily dock you for. Here's the actual fix.

Take the quiz →
Stop Calling form.submit(). Use requestSubmit() Instead.
? JavaScript

Stop Calling form.submit(). Use requestSubmit() Instead.

A Save button living outside the <form> tag, wired to form.submit(), looks like it works — until a blank required field sails through and the page does a full reload your fetch handler never saw coming. requestSubmit() is the method that actually clicks the button for you.

Take the quiz →
Next.js 16 updateTag vs revalidateTag: What Changed
? Nextjs

Next.js 16 updateTag vs revalidateTag: What Changed

Next.js 16 deprecated revalidateTag's single-argument call and added updateTag. What the new profile argument changes, plus a copy-paste cheat sheet.

Take the quiz →
Stop Writing JS to Detect a Stuck Header. `scroll-state()` Fixes It.
? CSS

Stop Writing JS to Detect a Stuck Header. scroll-state() Fixes It.

A sticky header that should only cast a shadow once it's actually stuck to the top usually means a hidden sentinel div and an IntersectionObserver. CSS now tracks that state itself — the `scroll-state()` container query reads it directly, no sentinel, no observer, no JS math.

Take the quiz →
Vue v-for: The Directive Unmounted Hook Bug, Fixed in 3.5.41
? Vue

Vue v-for: The Directive Unmounted Hook Bug, Fixed in 3.5.41

A custom directive's unmounted hook could silently skip firing inside a keyed v-for list. The directive unmounted hook bug, Vue's real fix, and a cheat sheet.

Take the quiz →
You're Debouncing Scroll Wrong. requestAnimationFrame Fixes It.
? JavaScript

You're Debouncing Scroll Wrong. requestAnimationFrame Fixes It.

Debouncing a scroll handler makes it wait until scrolling stops — which is why your sticky header always lags half a beat. requestAnimationFrame fixes the lag by syncing updates to the browser's own paint clock instead of a timer.

Take the quiz →
My Reducer's Switch Stopped Being Exhaustive. `as const` Fixed It.
? TypeScript

My Reducer's Switch Stopped Being Exhaustive. as const Fixed It.

Object and array literals widen to `string` and `number` the moment you write them, which quietly breaks discriminated unions and exhaustive switch checks. `as const` keeps the literal types — but it also freezes the value, which bites in its own way.

Take the quiz →
Nuxt 4.6 nuxt/server: Why Mixing h3 Imports Throws NUXT_E8012
? Nuxt

Nuxt 4.6 nuxt/server: Why Mixing h3 Imports Throws NUXT_E8012

Nuxt 4.6 added a new nuxt/server import source alongside h3 — mix the two in one handler and you hit NUXT_E8012. The real boundary, plus a cheat sheet.

Take the quiz →
Your Custom Hooks Tear in React 18. `useSyncExternalStore` Fixes It.
? React

Your Custom Hooks Tear in React 18. useSyncExternalStore Fixes It.

A useState + useEffect hook that subscribes to window size, localStorage, or a WebSocket looks fine until React 18's concurrent rendering shows two parts of your UI two different values at once. useSyncExternalStore is the hook built to stop that.

Take the quiz →
NestJS 12 Lifecycle Hooks: The Order You Can't Assume
? Nestjs

NestJS 12 Lifecycle Hooks: The Order You Can't Assume

NestJS 12 changed how lifecycle hooks are ordered. Learn what onModuleInit and onApplicationBootstrap really guarantee, plus a copy-paste cheat sheet.

Take the quiz →
Stop Jamming Translate, Rotate, and Scale Into One `transform`
? CSS

Stop Jamming Translate, Rotate, and Scale Into One transform

A CSS :hover scale and a JS drag handler both write to `transform` — and the moment JS sets it, the hover rule silently stops working, no error, no warning. The `translate`, `rotate`, and `scale` properties exist so this never happens.

Take the quiz →
You're Letting the Browser Guess. `fetchpriority` Fixes That.
? Performance

You're Letting the Browser Guess. fetchpriority Fixes That.

Your hero image is losing a bandwidth fight against a web font and a chat-widget script — fetchpriority tells the browser which request actually matters first.

Take the quiz →
Next.js 16.3 Instant Navigations: How Partial Prefetching Works
? Nextjs

Next.js 16.3 Instant Navigations: How Partial Prefetching Works

Next.js 16.3 shipped Instant Navigations: Partial Prefetching plus the App Shell. Learn the model, the Suspense gotcha, and a copy-paste cheat sheet.

Take the quiz →
Stop Formatting Currency With Regex. `Intl.NumberFormat` Does It.
? JavaScript

Stop Formatting Currency With Regex. Intl.NumberFormat Does It.

A hand-rolled formatMoney() with toFixed() and a comma regex looks fine in a US demo and quietly breaks the moment a real user, a negative balance, or a non-dollar locale shows up. Intl.NumberFormat has handled all of it, built into every modern browser, since before most teams' codebases existed.

Take the quiz →
Vue 3.6: When a Watcher Throws, Your Other Watchers Stall
? Vue

Vue 3.6: When a Watcher Throws, Your Other Watchers Stall

A Vue 3.6 reactivity regression let a throwing watcher silently stall its siblings. The exact flush() mechanism, the fix, and a copy-paste cheat sheet.

Take the quiz →
Your 'Expand All' Button Is Quietly Causing Layout Thrashing
? JavaScript

Your 'Expand All' Button Is Quietly Causing Layout Thrashing

An 'expand all' click that stutters isn't a slow CPU — it's layout thrashing, a loop that forces the browser to recalculate layout once per row instead of once per click. Here's how to spot it and the two-line fix.

Take the quiz →
Nuxt 4.6 useSession: Server Sessions Without a Database
? Nuxt

Nuxt 4.6 useSession: Server Sessions Without a Database

Nuxt 4.6 ships useSession and runtimeConfig.appSecret — real, sealed-cookie sessions with no database or session store. How it works, plus a cheat sheet.

Take the quiz →
Stop Shipping Custom UI That Disappears in `forced-colors` Mode
? CSS

Stop Shipping Custom UI That Disappears in forced-colors Mode

Windows High Contrast Mode doesn't just boost contrast — it strips your backgrounds, shadows, and colors outright. Here's what `forced-colors` actually does, why a styled <div> vanishes while a real <button> survives, and the fix.

Take the quiz →
React 19.2 useEffectEvent: Why It Won't Fix Your Deps Array
? React

React 19.2 useEffectEvent: Why It Won't Fix Your Deps Array

React's useEffectEvent (stable in 19.2) kills stale closures in Effects without a ref trick — but it's not a deps-array shortcut. Guide + cheat sheet.

Take the quiz →
Inferred Type Predicates Won't Save filter(Boolean). Here's What Will.
? TypeScript

Inferred Type Predicates Won't Save filter(Boolean). Here's What Will.

TypeScript 5.5 added inferred type predicates, and the internet decided that meant filter(Boolean) finally narrows. It doesn't. Here's exactly what the feature fixed, why the mix-up happened, and the one-line pattern that actually gets you type-safe filtering.

Take the quiz →
Stop Letting One Widget Reflow the Whole Page. `contain` Scopes It.
? CSS

Stop Letting One Widget Reflow the Whole Page. contain Scopes It.

A live counter or chat widget shouldn't make the rest of your page recompute layout every time it updates. The CSS contain property draws a hard boundary the browser can actually trust — here's what it promises, and the one gotcha that breaks pages when people misuse it.

Take the quiz →
Stop Electing a Leader Tab. SharedWorker Just Holds the Connection.
? JavaScript

Stop Electing a Leader Tab. SharedWorker Just Holds the Connection.

Electing a leader tab to own one shared WebSocket works great — until the leader is the tab someone closes. SharedWorker skips the election: the connection lives in the worker, not in any tab, so there's no leader to lose.

Take the quiz →
You Installed a Library for Numbers PerformanceObserver Already Has.
? JavaScript

You Installed a Library for Numbers PerformanceObserver Already Has.

The web-vitals npm package gets credit for data your browser already computes. Here's what three PerformanceObserver calls give you for free — and the one piece of math it quietly saves you from getting wrong.

Take the quiz →
Your Tabs Each Open Their Own WebSocket. navigator.locks Elects One.
? JavaScript

Your Tabs Each Open Their Own WebSocket. navigator.locks Elects One.

Six open tabs means six live connections to your server, six duplicate pushes, six timers draining the battery. navigator.locks elects a single leader tab to hold the real connection — the rest just listen.

Take the quiz →
Next.js 16 Image: priority Deprecated, quality Now Allowlisted
? Nextjs

Next.js 16 Image: priority Deprecated, quality Now Allowlisted

Next.js 16 quietly deprecated Image's priority for preload and restricts quality to an allowlist (default: 75). What breaks, plus a copy-paste cheat sheet.

Take the quiz →
Vue watch vs watchEffect: The Complete Guide
? Vue

Vue watch vs watchEffect: The Complete Guide

Vue's watch() and watchEffect() look interchangeable but track dependencies, run timing, and cleanup differently. The exact rules, verified against Vue 3.5.

Take the quiz →
I Shipped a Fix. My Service Worker Kept Serving the Bug.
? JavaScript

I Shipped a Fix. My Service Worker Kept Serving the Bug.

A critical bug fix went out, and support tickets kept coming in from people who swore they'd refreshed. The code was fine. The service worker's cache-first strategy was doing its job perfectly — which was the whole problem.

Take the quiz →
Nuxt 4 Migration: The Breaking Changes That Actually Bite
? Nuxt

Nuxt 4 Migration: The Breaking Changes That Actually Bite

Nuxt 3 reached end-of-life on July 31, 2026. Here's exactly what breaks moving to Nuxt 4 — directories, data fetching, TypeScript — plus a cheat sheet.

Take the quiz →
Your Lighthouse Score Is 100. Long Animation Frames Explain the Jank.
? JavaScript

Your Lighthouse Score Is 100. Long Animation Frames Explain the Jank.

Lighthouse says 100 and CI is green, but a user still says the filter button feels sluggish. The Long Animation Frames API names the exact script and phase that blocked the frame — here's how to read it instead of squinting at a flame chart.

Take the quiz →
React 19.3 Fragment Refs: Skip the Wrapper Div for a Ref
? React

React 19.3 Fragment Refs: Skip the Wrapper Div for a Ref

React 19.3 Fragment Refs let you ref a sibling group with no wrapper div. Learn the FragmentInstance API, its limits, and get a copy-paste cheat sheet.

Take the quiz →
You Added `will-change` to Fix the Jank. You Made It Worse.
? CSS

You Added will-change to Fix the Jank. You Made It Worse.

will-change: transform looks like a free performance switch. Applied broadly or left on permanently, it does the opposite — here's the narrow, temporary pattern that actually works.

Take the quiz →
You're Animating for Everyone. `prefers-reduced-motion` Fixes That.
? CSS

You're Animating for Everyone. prefers-reduced-motion Fixes That.

Most animated UIs never check whether the visitor asked for less motion. `prefers-reduced-motion` is the CSS media feature that tells you — and a fail-closed pattern keeps you honest even when a browser doesn't support it.

Take the quiz →
Stop Losing Promise Errors. `unhandledrejection` Catches Them.
? JavaScript

Stop Losing Promise Errors. unhandledrejection Catches Them.

A rejected promise with no .catch doesn't crash and doesn't show up in your error tracker — it just disappears. The unhandledrejection event is the global safety net most apps never wire up.

Take the quiz →
Stop Retrying Immediately. Exponential Backoff Fixes It.
? JavaScript

Stop Retrying Immediately. Exponential Backoff Fixes It.

Retrying a failed fetch() right away feels responsible — until the server that failed was already overloaded, and five instant retries per client turn a blip into an outage. Exponential backoff with jitter is the fix.

Take the quiz →
I Built Cross-Tab Logout. The storage Event Skipped One Tab.
? JavaScript

I Built Cross-Tab Logout. The storage Event Skipped One Tab.

A cross-tab 'log out everywhere' feature built on the storage event worked in every tab except the one the user actually clicked in. The storage event never fires in the tab that made the change — and that's spec, not a bug.

Take the quiz →
Next.js Streaming Metadata: Why Your `<head>` Looks Incomplete
? Nextjs

Next.js Streaming Metadata: Why Your <head> Looks Incomplete

Next.js 16 streaming metadata sends users a page before generateMetadata resolves, but blocks crawlers for a complete head. How it works, plus a cheat sheet.

Take the quiz →
Vue defineModel: The v-model Contract, Explained
? Vue

Vue defineModel: The v-model Contract, Explained

Vue's defineModel macro replaces the modelValue prop and update:modelValue event with one ref. The exact v-model contract behind it, verified against Vue 3.5.

Take the quiz →
`beforeunload` Can Still Kill Your bfcache. Mount It Only When Dirty.
? JavaScript

beforeunload Can Still Kill Your bfcache. Mount It Only When Dirty.

A `beforeunload` listener you left mounted forever can still quietly cost you bfcache eligibility — and an `unload` listener reliably will. Here's the pagehide/pageshow fix, and why 'mount it only when there's something to lose' is the durable rule.

Take the quiz →
Nuxt 4.5 SSR Streaming: The Route Rules That Disable It
? Nuxt

Nuxt 4.5 SSR Streaming: The Route Rules That Disable It

Nuxt 4.5's experimental SSR streaming flushes HTML early, but cache, isr, swr, redirect, and ssr:false route rules silently fall back to buffering. Cheat sheet included.

Take the quiz →
Stop Hand-Rolling an Exclusive Accordion. `<details name>` Does It
? HTML

Stop Hand-Rolling an Exclusive Accordion. <details name> Does It

You've probably shipped an accordion with a hand-rolled 'close the other panels' loop in JavaScript. The `name` attribute on <details> does it natively — no JS, no ARIA plumbing.

Take the quiz →
React 19.3 ViewTransition: Animate State Without Losing It
? React

React 19.3 ViewTransition: Animate State Without Losing It

React 19.3's ViewTransition component animates state changes, not just page swaps — the mental model, enter/exit/update/share, and a cheat sheet.

Take the quiz →
Your Search Box Lags. Debounce Hides It; `useTransition` Fixes It
? React

Your Search Box Lags. Debounce Hides It; useTransition Fixes It

A big list re-render was blocking every keystroke — debouncing just moved the freeze. useTransition tells React which update can wait.

Take the quiz →
NestJS 12: Standard Schema Validation Without class-validator
? Nestjs

NestJS 12: Standard Schema Validation Without class-validator

NestJS 12 adds Standard Schema validation for @Body(), @Query(), and @Param() — validate with Zod or Valibot, no class-validator DTO. Cheat sheet included.

Take the quiz →
Stop Fixing Headline Gaps With Negative Margins. Use `text-box-trim`
? CSS

Stop Fixing Headline Gaps With Negative Margins. Use text-box-trim

Line-height reserves space for accent marks your headline never uses — a hand-tuned negative margin only fixes it for one font at one size. text-box-trim does, natively, from the font's own metrics.

Take the quiz →
`:nth-child(even)` Counts Hidden Rows. `of S` Fixes Your Stripes
? CSS

:nth-child(even) Counts Hidden Rows. of S Fixes Your Stripes

nth-child(even) counts every element in the DOM, including the ones you just hid with display:none. The fix isn't JavaScript — it's a CSS selector most people have never had a reason to use.

Take the quiz →
Vue computed(): What It Caches and When It Reruns
? Vue

Vue computed(): What It Caches and When It Reruns

Vue's computed() caches its result and only reruns when a tracked dependency changes, not on every read. The exact caching and invalidation model, verified against Vue 3.5.

Take the quiz →
Your `backdrop-filter` Is Working. Your Background Is Hiding It.
? CSS

Your backdrop-filter Is Working. Your Background Is Hiding It.

backdrop-filter looks like a one-line copy from a Codepen: blur(20px), ship the frosted navbar. Half the time it renders as a plain flat panel instead — because backdrop-filter blurs whatever is BEHIND an element, and that only shows up if the element itself is see-through. Here's the transparency rule, the stacking-context trap it quietly sets, and why it's one of the priciest effects you can scroll past.

Take the quiz →
Blocking `<script>` Won't Stop innerHTML XSS. `setHTML()` Will.
? JavaScript

Blocking <script> Won't Stop innerHTML XSS. setHTML() Will.

A regex that strips <script> tags misses the XSS that actually runs — an onerror attribute. Element.setHTML(), from the HTML Sanitizer API, strips it natively, and for once Firefox shipped the finished version before Chrome did.

Take the quiz →
Nuxt Server Routes Explained: How Nitro Builds Your API
? Nuxt

Nuxt Server Routes Explained: How Nitro Builds Your API

Nuxt server routes turn server/api into a real backend via Nitro and h3. Learn routing rules, defineEventHandler, middleware order, and the useState trap.

Take the quiz →
Your 'Save' Button Makes Copies. The File System Access API Doesn't.
? JavaScript

Your 'Save' Button Makes Copies. The File System Access API Doesn't.

The classic web 'save' — a Blob and an <a download> link — doesn't overwrite a file, it manufactures a new one every time, leaving notes.md, notes (1).md, notes (2).md scattered in Downloads. The File System Access API fixes this with real, permissioned read-write access to a file on disk. Here's the difference, and why it's Chromium-only progressive enhancement, not a drop-in replacement.

Take the quiz →
Stop Guessing When Scrolling Stops — Use scrollend
? JavaScript

Stop Guessing When Scrolling Stops — Use scrollend

For years, 'has the user stopped scrolling?' was a guess: debounce the scroll event, pick a delay, hope. The scrollend event answers the question directly — and as of Safari 26.2, it finally works everywhere. Here's the bug the guess causes, and the one-line fix.

Take the quiz →
Next.js Route Handlers: GET Stopped Caching in 15 — How to Cache in 16
? Nextjs

Next.js Route Handlers: GET Stopped Caching in 15 — How to Cache in 16

Next.js 15 made GET Route Handlers dynamic by default. What that changes for code written for 14, how to cache one on purpose in 16, plus a cheat sheet.

Take the quiz →
getCurrentPosition() Doesn't Just Check — It Prompts
? JavaScript

getCurrentPosition() Doesn't Just Check — It Prompts

You want to peek at whether location access is already granted before showing your own 'why we need this' banner. Calling getCurrentPosition() to find out fires the real system prompt. navigator.permissions.query() reads the state without ever asking.

Take the quiz →
NestJS Guards: CanActivate, ExecutionContext & Reflector
? Nestjs

NestJS Guards: CanActivate, ExecutionContext & Reflector

A complete guide to NestJS guards: how CanActivate, ExecutionContext, and the Reflector decide who reaches your route handler, with a cheat sheet.

Take the quiz →
localStorage Isn't Free — It's Blocking Your Main Thread
? JavaScript

localStorage Isn't Free — It's Blocking Your Main Thread

Autosave into localStorage looks harmless right up until the draft gets big. The API is synchronous by spec, so every write freezes the page for exactly as long as it takes — and debouncing doesn't fix it. IndexedDB does.

Take the quiz →
JSON.stringify Is Quietly Deleting Your File Uploads
? JavaScript

JSON.stringify Is Quietly Deleting Your File Uploads

An avatar upload form that passes every test, ships to production, returns 200 OK — and never actually uploads the picture. The bug is one function call that silently turns a File into an empty object, with no error anywhere.

Take the quiz →
The Background Task That Waited 40 Seconds for 'Idle'
? JavaScript

The Background Task That Waited 40 Seconds for 'Idle'

requestIdleCallback promises to run only when the browser has spare cycles — but on a page that's never truly idle, that promise has no upper bound. Here's why the callback can stall, why the timeout escape hatch has its own trap, and when to reach for it instead of setTimeout or scheduler.yield.

Take the quiz →
Vue Composables: The Shared State Trap (+ Cheat Sheet)
? Vue

Vue Composables: The Shared State Trap (+ Cheat Sheet)

Why two Vue components using the same composable can end up sharing state by accident, the mental model that explains it, and how to fix or embrace it.

Take the quiz →
The Dropdown You've Been Faking for a Decade
? CSS

The Dropdown You've Been Faking for a Decade

Every hand-built 'custom select' with icons and a styled popup exists because the real <select> couldn't do that. appearance: base-select just closed the gap — without you losing the native picker's keyboard nav and mobile UI.

Take the quiz →
Next.js proxy.ts Explained (with Cheat Sheet)
? Nextjs

Next.js proxy.ts Explained (with Cheat Sheet)

Next.js 16 renamed middleware.ts to proxy.ts and locked it to the Node.js runtime. Learn the network-boundary model, matcher config, and the migration path.

Take the quiz →
Stop Writing JavaScript To Fix `100vh` On Mobile
? CSS

Stop Writing JavaScript To Fix 100vh On Mobile

Your full-screen hero looks perfect in the simulator and cuts off the CTA on a real phone. It's not a bug in your code — it's `vh` answering a question you didn't ask. Three new units fix it with zero JavaScript.

Take the quiz →
React Derived State: Why That useState Is Probably a Bug
? React

React Derived State: Why That useState Is Probably a Bug

React derived state explained: why syncing a computed value into useState with an Effect causes extra renders and drift, and what to write instead.

Take the quiz →
Your Browser Is Rejecting Every Drop On Purpose
? JavaScript

Your Browser Is Rejecting Every Drop On Purpose

A drop zone with a correctly wired drop listener that never fires — no error, no typo, nothing in the console. The browser is silently refusing the drop by design, and only one specific line stops it.

Take the quiz →
Nuxt Hydration Mismatch: Why It Happens and How to Fix It
? Nuxt

Nuxt Hydration Mismatch: Why It Happens and How to Fix It

A Nuxt hydration mismatch happens when the server's HTML disagrees with the client's first render. Learn why, and the fixes that actually work.

Take the quiz →
Chrome Already Has The Eyedropper You're Building
? JavaScript

Chrome Already Has The Eyedropper You're Building

You're about to build a canvas-based color picker with a magnifier loupe. Chrome shipped a native one years ago — and it can sample pixels your own canvas can't even see.

Take the quiz →
NestJS Testing Module: Provider Overrides (with Cheat Sheet)
? Nestjs

NestJS Testing Module: Provider Overrides (with Cheat Sheet)

A complete guide to NestJS's testing module: how overrideProvider really wires mocks, why get() fails on scoped providers, and using useMocker.

Take the quiz →
The CSS Property That Fixes Dark Mode's Ugly White Boxes
? CSS

The CSS Property That Fixes Dark Mode's Ugly White Boxes

You shipped dark mode. The page is black, the text is white — and then the date picker opens like a floodlight. color-scheme is the one-line CSS property that tells the browser your native form controls need to catch up too.

Take the quiz →
Stop Debouncing Resize. The Browser Already Watches It.
? JavaScript

Stop Debouncing Resize. The Browser Already Watches It.

A debounced resize handler comparing window.innerWidth to a magic number can't ever see dark mode or reduced motion — and it fires dozens of times for one thing matchMedia fires once for.

Take the quiz →
Your Fetch Already Streams. You're Buffering It Anyway.
? JavaScript

Your Fetch Already Streams. You're Buffering It Anyway.

A chat UI that types out its reply letter by letter isn't proof it's streaming — it's often proof the opposite. fetch() delivers a real ReadableStream body, and most code drains it into one string before showing a single character.

Take the quiz →
Next.js Parallel & Intercepting Routes: Modals Done Right
? Nextjs

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 →
Your Custom Element Is Missing From FormData — ElementInternals Fixes It
? JavaScript

Your Custom Element Is Missing From FormData — ElementInternals Fixes It

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
? Vue

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
? JavaScript

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
? Nuxt

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
? CSS

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
? JavaScript

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)
? Nestjs

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)
? Nestjs

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 →