modern_patterns_2025 32 Q&As

Modern Patterns 2025 FAQ & Answers

32 expert Modern Patterns 2025 answers researched from official documentation. Every answer cites authoritative sources you can verify.

unknown

32 questions
A

Server Components run entirely on server, never re-render. Render once to generate UI, send to client as static output. Benefits: (1) Direct database/API access (no client-side data fetching), (2) Zero JavaScript sent to client (smaller bundle), (3) Server-only secrets (API keys stay server-side), (4) Better SEO (pre-rendered HTML). Pattern: async Server Component fetches data directly. Use for: Data-heavy logic, static content, initial page renders, SEO-critical pages. Client Components: Interactive UI (onClick, useState, useEffect). Boundary: 'use client' directive marks client components. Frameworks: Next.js App Router (v14+), Remix. 2025 status: Production-ready, mainstream adoption. Pitfall: Props must be serializable (no functions), many libraries client-only. Don't use for: Heavy interactivity, real-time updates, client-only state. Modern pattern: RSC for data + Client Components for interactivity.

99% confidence
A

Server Actions execute server-side code from client components without API endpoints. 'use server' directive marks server functions. Pattern: async function createUser(formData) { 'use server'; await db.users.create({name: formData.get('name')}); revalidatePath('/users'); }. Usage:

. Benefits: (1) No API boilerplate (no separate /api routes), (2) Type-safe (full TypeScript inference), (3) Progressive enhancement (works without JS), (4) Built-in revalidation. Use for: Form submissions, database mutations, server-side operations. Automatic: Serialization, error handling, pending states (useFormStatus). React 19: Native integration, no framework required (but Next.js has best support). Modern pattern: Form actions replace API calls. Combine with useOptimistic for instant UI feedback. 2025: Standard for data mutations in RSC apps.

99% confidence
A

Server Components: Default choice for static, data-heavy content. Use when: (1) Fetching data (databases, APIs), (2) Server-only logic (auth checks, secrets), (3) Large dependencies (server-only, reduce bundle), (4) SEO-critical content. Client Components: For interactivity. Use when: (1) Event handlers (onClick, onChange), (2) React hooks (useState, useEffect, useContext), (3) Browser APIs (window, localStorage, WebSockets), (4) Third-party interactive libraries. Pattern: Start with Server Components, add 'use client' boundaries only where needed. Minimize client JavaScript. Example: Server Component fetches data, passes to Client Component for interaction. Boundary placement: Push 'use client' deep in tree (not at root). Composition: Server Components can import Client Components (not vice versa). 2025 best practice: Server by default, client when interactive. Measure bundle size impact.

99% confidence
A

TanStack Query: Server state (API data, caching). Use for: Data fetching, mutations, cache invalidation, background updates. Eliminates 80% of state management needs. Zustand: Global client state (UI state, shared data). Use for: User preferences, app-wide state, simple stores. Benefits: No boilerplate, flexible, good performance. Jotai: Atomic client state (fine-grained reactivity). Use for: Complex interdependencies, preventing unnecessary re-renders, granular updates. Each atom is independent. Modern pattern (2025): TanStack Query for server data + Zustand for global client state. Or: TanStack Query + Jotai for maximum granularity. Context API: Simple prop drilling alternative (themes, auth). Redux: Legacy enterprise apps (avoid for new projects). Recommendation: Start with TanStack Query (handles most needs), add Zustand if need global state, consider Jotai if re-render optimization critical. Zustand is 2025 default for many teams (versatile, simple).

99% confidence
A

Zustand: Minimal state management with no boilerplate. Pattern: import create from 'zustand'; const useStore = create((set) => ({count: 0, increment: () => set((state) => ({count: state.count + 1})), reset: () => set({count: 0})})); Usage: const { count, increment } = useStore(). Benefits: (1) No providers (global by default), (2) Direct state mutation syntax (uses immer-like), (3) Computed values (selectors), (4) Middleware (persist, devtools, immer), (5) ~1KB size. Advanced: Slices pattern for organization, selective subscription (useStore(state => state.count) prevents re-renders). Async: set((state) => fetch().then(data => ({data}))). Middleware: persist(storeConfig, {name: 'storage'}) for localStorage. TypeScript: Excellent inference. 2025 recommendation: Default choice for most apps. Replaces Redux for simple/medium apps. Combine with TanStack Query for complete solution.

99% confidence
A

Jotai: Atomic state model with granular reactivity. Pattern: import { atom, useAtom } from 'jotai'; const countAtom = atom(0); function Counter() {const [count, setCount] = useAtom(countAtom); return <button onClick={() => setCount(c => c + 1)}>{count};}. Benefits: (1) Atoms are independent (no single store), (2) Components only re-render when used atoms change, (3) Derived atoms (computed values): const doubleAtom = atom((get) => get(countAtom) * 2). (4) Async atoms: const userAtom = atom(async () => fetch('/user').then(r => r.json())). (5) Bottom-up composition. Advanced: atomFamily for dynamic atoms, splitAtom for arrays, atomWithStorage for persistence. TypeScript: Excellent type inference. Use when: Complex state interdependencies, performance critical (prevent re-renders), need fine-grained control. 2025 pattern: Combine with TanStack Query (atoms for client state, Query for server state). Modern alternative to Recoil (simpler, more active).

99% confidence
A

Utility types transform existing types without duplication. Built-in types: (1) Partial - all properties optional: Partial allows {email?: string}. (2) Required - all properties required. (3) Pick<T, K> - subset of properties: Pick<User, 'id' | 'name'>. (4) Omit<T, K> - exclude properties: Omit<User, 'password'>. (5) Record<K, V> - object type with keys K and values V: Record<string, number>. (6) ReturnType - function return type: ReturnType. (7) Parameters - function parameter types. (8) Exclude<T, U> - remove types from union. (9) Extract<T, U> - extract types from union. (10) NonNullable - remove null/undefined. Use for: API responses (Omit sensitive fields), forms (Partial for partial updates), type transformations (avoid duplication). 2025 best practice: Prefer utility types over manual type definitions. Combine with generics for flexible APIs. Example: function update(id: string, data: Partial).

99% confidence
A

Conditional types enable type-level logic: T extends U ? X : Y. Pattern: type IsString = T extends string ? true : false. Use cases: (1) Type filtering: type NonNullable = T extends null | undefined ? never : T. (2) Return type extraction: type ReturnType = T extends (...args: any[]) => infer R ? R : never. (3) Distributive types: type ToArray = T extends any ? T[] : never; ToArray<string | number> becomes string[] | number[]. (4) Mapped + conditional: type ReadonlyDeep = {readonly [K in keyof T]: T[K] extends object ? ReadonlyDeep<T[K]> : T[K]}. Built-in utilities use conditional types: Exclude, Extract, NonNullable, ReturnType. Advanced: infer keyword extracts types: type ElementType = T extends (infer U)[] ? U : never. 2025 use: Library authors use extensively, app developers use built-in utilities. Powerful for generic constraints and type transformations.

99% confidence
A

Mapped types iterate over keys to transform types. Pattern: type Readonly = {readonly [K in keyof T]: T[K]}. Syntax: [K in keyof T] iterates, T[K] accesses value type. Use cases: (1) Make all optional: type Partial = {[K in keyof T]?: T[K]}. (2) Make required: type Required = {[K in keyof T]-?: T[K]} (-? removes optional). (3) Add modifiers: type Mutable = {-readonly [K in keyof T]: T[K]} (-readonly removes readonly). (4) Transform values: type Stringify = {[K in keyof T]: string}. (5) Remap keys: type Getters = {[K in keyof T as get${Capitalize<K & string>}]: () => T[K]}. Combine with conditional: type DeepPartial = {[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]}. 2025 patterns: Permission systems, configuration objects, API type transformations. Built-in utility types are mapped types. Essential for generic type manipulation.

99% confidence
A

Pure function: Output depends only on inputs, no side effects (no mutation, I/O, random, state). Pattern: function add(a, b) {return a + b;} - always same output for same inputs. Benefits: (1) Predictable (easy reasoning), (2) Testable (no setup/teardown), (3) Cacheable (memoization), (4) Parallelizable (no shared state), (5) Composable (combine safely). Impure: function addToCart(item) {cart.push(item); saveToStorage();} - mutates external state. Pure version: function addToCart(cart, item) {return [...cart, item];} - returns new array. React: Pure components enable React.memo, Suspense optimizations. 2025 trend: React Server Components embrace purity (server-side deterministic rendering). Use for: Business logic, transformations, utilities. Avoid: I/O operations (use effect handlers). Modern pattern: Pure core logic + thin impure shell. Essential for reliable, maintainable code.

99% confidence
A

Immutability: Never mutate data, create new copies. Patterns: (1) Array: spread [...arr, item] (add), arr.filter(i => i.id !== id) (remove), arr.map(i => i.id === id ? updated : i) (update). (2) Object: spread {...obj, key: value} (update), {...obj, nested: {...obj.nested, key: value}} (nested). (3) structuredClone: const copy = structuredClone(obj) - deep clone (2021+ native API). (4) Immutable libraries: Immer (use(draft => {draft.nested.value = 1})), Immutable.js (Map, List). Benefits: (1) Predictable state (no unexpected mutations), (2) Time-travel debugging (Redux DevTools), (3) React optimization (shallow comparison works), (4) Concurrent safety (no race conditions). Modern 2025: structuredClone for deep cloning, spread for shallow, Immer for complex updates. React: State updates must be immutable (setUsers([...users, newUser]) not users.push(newUser)). Essential for React, Redux, functional programming.

99% confidence
A

Function composition: Combine functions to build complex logic from simple pieces. Math: (f ∘ g)(x) = f(g(x)). JavaScript: const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x). Usage: const addThenDouble = compose(double, add5); addThenDouble(3) → double(add5(3)) → 16. Pipe (left-to-right): const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x); const addThenDouble = pipe(add5, double) - reads naturally. Benefits: (1) Reusability (small functions combined many ways), (2) Readability (declarative flow), (3) Testability (test pieces independently). Real example: const processUser = pipe(validateEmail, normalizeData, saveToDb, sendWelcomeEmail). Libraries: Ramda (R.compose, R.pipe), Lodash (_.flow). Modern 2025: Native pipe operator proposal (Stage 2). React: Custom hooks are function composition. Use for: Data transformations, middleware chains, validation pipelines. Essential functional programming technique.

99% confidence
A

Currying: Transform function with multiple arguments into sequence of functions each taking one argument. Pattern: function curry(fn) {return function curried(...args) {if (args.length >= fn.length) return fn(...args); return (...nextArgs) => curried(...args, ...nextArgs);}}. Example: const add = (a, b, c) => a + b + c; const curriedAdd = curry(add); curriedAdd(1)(2)(3) → 6; curriedAdd(1, 2)(3) → 6; curriedAdd(1)(2, 3) → 6. Benefits: (1) Partial application (reuse with some args fixed): const add5 = curriedAdd(5); add5(3)(2) → 10. (2) Function specialization: const multiply = curry((a, b) => a * b); const double = multiply(2); double(5) → 10. (3) Point-free style: const getUserNames = users.map(user => user.name) becomes users.map(prop('name')). Libraries: Ramda (all functions auto-curried), Lodash (_.curry). Modern 2025: Less common than partial application, but powerful for functional composition. React: Rarely needed (hooks handle most cases). Use for: Utility libraries, highly reusable functions, functional pipelines.

99% confidence
A

Vitest: Modern test runner built on Vite. Benefits over Jest: (1) Speed: 10-20x faster (leverages Vite's HMR, native ESM), (2) Config: Zero config for Vite projects (reuses vite.config), (3) ESM native: True ESM support (Jest uses CommonJS transpilation), (4) Watch mode: Instant with Vite HMR, (5) API: Jest-compatible (easy migration), (6) Features: Built-in TypeScript, JSX, code coverage, UI mode. Setup: npm install -D vitest @testing-library/react jsdom. Config: vitest.config.ts with environment: 'jsdom'. Migration from Jest: Change test scripts, rename jest.config → vitest.config, update imports (jest → vitest). 2025 status: Industry standard for Vite projects, growing adoption. Next.js: Still uses Jest (Turbopack future may change). Recommendation: Vitest for Vite projects, Jest for Next.js/legacy. Vitest is future of React testing (faster, modern, better DX).

99% confidence
A

Testing Library philosophy: Test behavior, not implementation. User-centric assertions. Principles: (1) Query by accessibility (getByRole, getByLabelText) not test IDs. (2) Interact like users (user.click, user.type from @testing-library/user-event). (3) Assert on visible output (screen text, not state). (4) Avoid implementation details (no enzyme .state(), .instance()). Modern patterns (2025): (1) User-event v14: await user.click(button) - async, realistic events. (2) MSW for API mocking: Mock network, not modules. (3) Testing Playground: Generate optimal queries. (4) Accessibility: Check ARIA attributes, keyboard navigation (tab, enter). (5) Async: waitFor, findBy queries for async updates. Anti-patterns: testid overuse (prefer role/label), implementation testing (spy on functions), synchronous queries for async content. Layered strategy: Unit tests (hooks, utils), integration tests (components with context), E2E (Playwright for flows). 2025: Vitest Browser Mode for accurate DOM testing. Essential for maintainable tests.

99% confidence
A

Test hooks in components (preferred) or with renderHook. Component approach: test hook behavior through component using it. Isolated testing: import {renderHook} from '@testing-library/react'; const {result} = renderHook(() => useCounter()). Access: result.current.count. Update: act(() => result.current.increment()). Async hooks: await waitFor(() => expect(result.current.data).toBeDefined()). Rerender with props: const {rerender} = renderHook(({id}) => useUser(id), {initialProps: {id: 1}}); rerender({id: 2}). Context: Wrap with provider: renderHook(() => useAuth(), {wrapper: AuthProvider}). Modern 2025: Test hooks through components when possible (more realistic). Use renderHook for: (1) Complex custom hooks, (2) Library hooks, (3) Reusable logic. Example: test('useCounter increments', () => {const {result} = renderHook(() => useCounter()); act(() => result.current.increment()); expect(result.current.count).toBe(1);}). Best practice: Test observable behavior (what users see), not internal state.

99% confidence
A

useTransition marks updates as non-urgent, keeping UI responsive. Pattern: const [isPending, startTransition] = useTransition(); startTransition(() => {setFilter(value);}). React prioritizes urgent updates (typing) over transitions (filtering list). isPending: Boolean for showing loading UI. Use cases: (1) Slow state updates (filtering large lists), (2) Route transitions, (3) Tab switching (render expensive content), (4) Search filtering (input responsive while results update). Benefits: UI stays responsive (no jank), user sees immediate feedback (pending state), React can interrupt/pause transition. Example: User types in search - input updates immediately (urgent), results filter slowly (transition). Without: Input lags as list filters. With: Input smooth, list updates when ready. 2025: Essential for concurrent React apps. Frameworks: Next.js App Router uses automatically for navigation. Combine with Suspense for optimal UX. Modern pattern: startTransition + useOptimistic for instant UI feedback.

99% confidence
A

useDeferredValue defers value updates, letting React prioritize urgent renders. Pattern: const deferredQuery = useDeferredValue(searchQuery). Deferred value lags behind actual value during transitions. Use cases: (1) Expensive derived values (filtered list from search), (2) Dependent renders (chart from data), (3) Third-party components (can't use startTransition). Difference from useTransition: useTransition controls when update happens (wrap setState), useDeferredValue controls when value is read (wrap value). Use useTransition when: You control state update. Use useDeferredValue when: You receive prop/value, can't control source. Example: Parent passes searchQuery, child uses deferredQuery = useDeferredValue(searchQuery) for expensive render. Benefits: Input updates immediately, expensive component uses stale value until ready. 2025 pattern: useDeferredValue for received values, useTransition for own state. Combine: Debounce input (external library) + useDeferredValue (React optimization). Modern: Essential for responsive UIs with expensive operations.

99% confidence
A

Suspense shows fallback while async operations load. Pattern: <Suspense fallback={}>. React 18+: Suspense for data fetching (not just code splitting). Modern pattern: Component throws promise during render, Suspense catches, shows fallback. When promise resolves, component re-renders with data. Libraries: TanStack Query (useSuspenseQuery), SWR, Relay support Suspense natively. React 19: 'use' hook for promises: const data = use(fetchData()). Example: function UserProfile() {const user = use(fetchUser()); return

{user.name}
;}. Wrap with Suspense: <Suspense fallback={}>. Benefits: (1) Declarative loading states, (2) Waterfall prevention (parallel fetching), (3) Streaming SSR (Next.js), (4) Coordinated loading (nested Suspense). 2025 best practice: Suspense boundaries at route level + component level for granular loading. Combine with useTransition for smooth transitions. Modern architecture: RSC + Suspense + streaming = instant page loads.

99% confidence
A

Higher-order function: Function that takes function as argument or returns function. Pattern: (1) Takes function: array.map(fn), array.filter(fn), array.reduce(fn). (2) Returns function: function createMultiplier(n) {return x => x * n;}. Use cases: (1) Abstraction: DRY principle, extract common patterns. (2) Callbacks: event handlers, async operations. (3) Partial application: const double = createMultiplier(2). (4) Decorators: function withLogging(fn) {return (...args) => {console.log('calling', args); return fn(...args);}}. Built-in: map, filter, reduce, forEach, some, every, find, sort. Benefits: Declarative code (what not how), composable (chain operations), reusable. Modern 2025: Essential for functional programming, React (hooks are HOFs), array methods. Example: users.filter(u => u.active).map(u => u.name).sort(). Advanced: Function factories, middleware, decorators, currying. React: Custom hooks return functions, event handlers are HOFs. Essential JavaScript pattern.

99% confidence
A

Server to Client prop passing: Only serializable data allowed. Serializable types: Primitives (string, number, boolean, null), arrays, plain objects, Promises, Date, Map, Set. NOT serializable: Functions (no callbacks), class instances (methods lost), symbols, WeakMap/WeakSet, DOM nodes, React elements with client components. Pattern: Pass data down, not functions up. Server Component passes data prop to Client Component. Workarounds: (1) Server Actions for callbacks: . (2) Serialization: Convert class to plain object, pass id instead of instance. (3) Context: Wrap Client Components with Context provider. Common errors: 'Functions cannot be passed directly to Client Components' - use Server Actions. 'Only plain objects can be passed' - stringify/parse or restructure. 2025 pattern: Server Components orchestrate data, Client Components handle interactivity with Server Actions for mutations. Modern architecture embraces constraint - cleaner separation of concerns.

99% confidence
A

RSC optimizations: (1) Minimize client components - keep 'use client' boundaries small, push deep in tree. (2) Streaming - use Suspense boundaries for progressive rendering: . (3) Parallel data fetching - fetch in parallel at same level, avoid waterfalls. (4) Static rendering - pre-render at build time when possible (Next.js generateStaticParams). (5) Partial Pre-Rendering (PPR) - mix static + dynamic in same route (Next.js 15 experimental). (6) Dedupe requests - React automatically dedupes identical fetch calls in RSC tree. (7) Cache strategically - use Next.js caching ('force-cache', 'no-store') for fetch. Anti-patterns: Sequential fetching (await in component tree), large client bundles (move logic to server), unnecessary client components. 2025 best practice: Server-first architecture - default Server Components, add client only for interactivity. Measure: Chrome DevTools, Next.js Speed Insights. Bundle size, Time to Interactive are key metrics.

99% confidence
A

Generics: Parameterized types for flexible, reusable, type-safe code. Pattern: function identity(value: T): T {return value;}. T is type parameter. Usage: identity(5), identity('hi') - or inferred: identity(5). Use cases: (1) Generic functions: function firstElement(arr: T[]): T | undefined {return arr[0];}. (2) Generic classes: class Box {constructor(public value: T) {}}. (3) Generic interfaces: interface Response {data: T; status: number}. (4) Constraints: function merge(obj1: T, obj2: T) - T must be object. (5) Default types: type Response<T = unknown> = {data: T}. (6) Multiple parameters: function map<T, U>(arr: T[], fn: (item: T) => U): U[]. Benefits: Type safety with flexibility, reusable code, better inference. 2025: Essential for libraries, utility functions, API wrappers. React: useState, useRef. Modern pattern: Constrained generics (T extends Base) for safer APIs.

99% confidence
A

Type guards: Functions that narrow types in conditional blocks. Pattern: function isString(value: unknown): value is string {return typeof value === 'string';}. Usage: if (isString(value)) {value.toUpperCase();} - TypeScript knows value is string. Built-in guards: (1) typeof: typeof x === 'string'. (2) instanceof: x instanceof Date. (3) in operator: 'name' in obj. (4) Truthiness: if (value) narrows to non-null. (5) Equality: if (x === y) narrows both. Custom guards: Use 'value is Type' return type. Example: function isUser(obj: unknown): obj is User {return typeof obj === 'object' && obj !== null && 'name' in obj && 'email' in obj;}. Discriminated unions: type Shape = {kind: 'circle'; radius: number} | {kind: 'square'; size: number}; if (shape.kind === 'circle') {shape.radius} - TypeScript narrows. 2025 best practice: Type guards for runtime safety + compile-time inference. Essential for APIs, form validation, error handling. Use with unknown for maximum safety.

99% confidence
A

Server state: Data from backend (API, database) - user profiles, posts, products. Cached, shared, potentially stale. Client state: UI-specific - modal open, form inputs, theme, filters. Local to client, ephemeral. Modern pattern (2025): Different tools for different state. Server state: TanStack Query (React Query), SWR, Apollo Client. Benefits: (1) Automatic caching, (2) Background refetching, (3) Optimistic updates, (4) Deduplication, (5) Stale-while-revalidate. Pattern: const {data, isLoading} = useQuery({queryKey: ['user', id], queryFn: fetchUser}). Client state: useState, Zustand, Jotai for global. Pattern: const [isOpen, setIsOpen] = useState(false). Why separate: Server state has different concerns (caching, synchronization, invalidation). TanStack Query handles 80% of state management (all server interactions). Remaining 20%: Client state with Zustand/Context. 2025 architecture: RSC for initial data + TanStack Query for client-side updates + Zustand for UI state. Avoid Redux for new projects (TanStack Query replaces most needs).

99% confidence
A

Layered testing approach: More unit tests at bottom, fewer E2E at top. Layers: (1) Unit tests (70%): Test isolated logic - pure functions, hooks (renderHook), utils. Fast, focused. Tools: Vitest. (2) Integration tests (20%): Test components with dependencies - render with context/providers, mock APIs (MSW), user interactions. Tools: Testing Library + Vitest. (3) E2E tests (10%): Test complete user flows - login, checkout, critical paths. Real browser. Tools: Playwright, Cypress. 2025 recommendations: (1) Test behavior, not implementation (Testing Library philosophy). (2) Mock network, not modules (MSW for realistic API mocks). (3) Vitest Browser Mode for integration tests (accurate DOM). (4) Parallel execution (Vitest native, Playwright sharding). (5) Visual regression tests for UI (Percy, Chromatic). Modern CI: Fast feedback (unit first), parallel execution, incremental testing. Avoid: Over-mocking (brittle tests), snapshot overuse (maintenance burden), 100% coverage goal (diminishing returns).

99% confidence
A

Accessibility testing with Testing Library: Query by role (built-in a11y testing). Pattern: screen.getByRole('button', {name: /submit/i}) - fails if button not accessible. Methods: (1) getByRole: Primary query, enforces ARIA. Roles: button, heading, textbox, checkbox, link, etc. (2) getByLabelText: Forms - screen.getByLabelText('Email'). (3) getByAltText: Images - screen.getByAltText('User avatar'). User interactions: @testing-library/user-event - await user.tab(), user.keyboard('{Enter}') test keyboard nav. Test patterns: (1) Keyboard navigation: Focus order, tab key, escape key. (2) Screen reader: ARIA labels, roles, descriptions. (3) Color contrast: Visual regression tools. (4) Focus management: Modal traps focus, dialogs restore focus. Tools: (1) jest-axe: Automated a11y assertions - expect(container).toHaveNoViolations(). (2) pa11y: CI integration. (3) Lighthouse CI: Accessibility scores. 2025 best practice: Accessibility is core, not afterthought. Query by role forces accessible patterns. WCAG 2.2 compliance standard.

99% confidence
A

Monad: Container with flatMap/chain method enabling safe operation chaining that may fail or be async. Core types: (1) Promise: Async operations, then(fn) is flatMap - ubiquitous JavaScript monad. (2) Either/Result: Error handling with detailed error information. Pattern: type Either<L, R> = Left | Right. Use for: explicit error types without try/catch. Example: parseJSON(str).flatMap(validateSchema).map(processData) - each step returns Either, errors propagate as Left, success as Right. (3) Maybe/Option: Null safety. Some(value) or None. Example: Option.of(user).flatMap(u => Option.of(u.address)).map(a => a.city) - eliminates null-pointer exceptions. (4) Array: flatMap built-in for flat mapping collections. Libraries: fp-ts (TypeScript, production-ready), monet.js (JavaScript). Benefits: eliminate null-pointer exceptions, unhandled exceptions, race conditions. 2025 status: Either/Result pattern gaining popularity for production error handling (replaces throw/catch in functional code). Promise remains most common monad. Optional chaining (?.) handles simple null cases. Use Either for complex error flows, validation pipelines, railway-oriented programming.

99% confidence
A

Render-as-you-fetch: Start fetching data immediately (not in useEffect), render while fetching (with Suspense). Pattern: (1) Initiate fetch early: const userPromise = fetchUser(); (2) Pass promise to component. (3) Component reads promise (throws if pending): const user = use(userPromise). (4) Suspense catches throw, shows fallback. Benefits: Parallel fetching (start before render), no waterfalls (sequential waits), better perceived performance. Code: function ProfilePage() {const userPromise = fetchUser(); const postsPromise = fetchPosts(); return <Suspense fallback={}>;}. Both fetch in parallel, render together. Traditional fetch-on-render (useEffect): Component renders → useEffect runs → fetch starts → loading state → re-render with data. Waterfall if nested. Modern (2025): Server Components render-as-you-fetch by default, TanStack Query prefetching, React Router loaders. Pattern is future: RSC + Suspense + streaming = instant page loads with progressive enhancement.

99% confidence
A

MSW intercepts network requests at service worker level, provides realistic mocks without changing code. Setup: import {http, HttpResponse} from 'msw'; import {setupServer} from 'msw/node'. Define handlers: const handlers = [http.get('/api/users', () => {return HttpResponse.json([{id: 1, name: 'John'}]);})]. Setup server: const server = setupServer(...handlers); beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()). Benefits: (1) Network-level mocking (not module mocking), (2) Same handlers for tests + browser dev, (3) Realistic (actual fetch calls), (4) Framework-agnostic. Test: render component, component fetches /api/users, MSW responds, assert UI. Override: server.use(http.get('/api/users', () => HttpResponse.json([]))). Error simulation: HttpResponse.json(null, {status: 500}). 2025 best practice: MSW for all API mocking (replaces axios-mock-adapter, fetch-mock). Vitest integration: import in setupFiles. Modern testing standard for realistic, maintainable mocks.

99% confidence
A

App Router: Next.js 14+ routing with React Server Components. File system routing: app/ directory structure maps to routes. Conventions: (1) page.tsx: Route UI, exports default component. (2) layout.tsx: Shared UI (nav, sidebar), wraps children. Nested layouts inherit. (3) loading.tsx: Instant loading UI (Suspense boundary). (4) error.tsx: Error boundary for route segment. (5) route.ts: API routes (GET, POST handlers). (6) not-found.tsx: 404 page. (7) template.tsx: Re-mounts on navigation (vs layout). Dynamic routes: [id]/page.tsx, [...slug]/page.tsx. Parallel routes: @folder for same-level alternatives. Intercepting: (.)folder for modals. Route groups: (group) for organization without URL. Metadata: export const metadata or generateMetadata(). 2025 features: Partial Pre-Rendering (static + dynamic), Server Actions native, Turbopack (faster builds). Migration: pages/ still supported, gradual migration. Modern pattern: App Router default for new projects (better performance, DX, RSC).

99% confidence
A

Bundle optimization strategies: (1) Code splitting: React.lazy for routes, dynamic import() for heavy features. (2) Tree shaking: Use ES modules (import/export), avoid * imports, configure bundler (Vite automatic, Webpack sideEffects). (3) Analyze: vite-bundle-visualizer, webpack-bundle-analyzer identify large deps. (4) Replace heavy libs: date-fns → date-fns-tz specific functions, moment → date-fns/dayjs, lodash → native methods. (5) Dynamic imports: const Chart = lazy(() => import('chart.js')); . (6) Server Components: Move non-interactive code to server (zero client JS). (7) Image optimization: next/image (automatic), modern formats (WebP, AVIF). Measurement: Lighthouse, Chrome DevTools Coverage tab, bundle analyzers. 2025 targets: < 200KB initial JS (mobile), < 500KB total. Modern wins: Vite's out-of-box optimization, RSC eliminates client JS for data-heavy components, ESBuild's speed. Best practice: Measure before optimizing (premature optimization trap), prioritize above-fold content, use performance budgets in CI.

99% confidence