RN

Active problem-solving

Practice Prompts

Try it before you reveal. Each coding and system-design prompt unfolds in stages — approach, then solution — so you practice retrieval, not recognition. Mark what you solved; revisit the rest.

Solved 0 / 51
Level
  1. CodeMid

    Build a useDebounce hook

    hooksperformancetimers

    Write a generic useDebounce<T>(value, delay) hook that returns a debounced copy of value which only updates after the input has been stable for delay milliseconds. A classic use is debouncing a search box before firing a query.

    next: new
  2. CodeSenior

    useInterval without the stale-closure bug

    hooksclosurestimers

    Implement useInterval(callback, delay) that calls callback every delay ms. The naive version captures a stale callback; your version must always run the latest callback, support changing the delay, and pause when delay is null — all without re-subscribing the interval on every callback change.

    next: new
  3. CodeJunior

    usePrevious hook

    hooksrefs

    Write usePrevious<T>(value) that returns the value from the previous render (and undefined on the first render). Useful for detecting transitions, e.g. animating only when a prop actually changed.

    next: new
  4. CodeMid

    Typed generic groupBy<T, K>

    typescriptgenericsutilities

    Write a type-safe groupBy<T, K>(items, getKey) that buckets an array into a Record<K, T[]>, where getKey derives the grouping key (constrained to a valid property-key type) for each item.

    next: new
  5. CodeSenior

    Fix the broken React.memo re-render

    reactperformancere-rendersmemoization

    This <Row> is wrapped in React.memo but still re-renders on every parent render. Explain why and fix it.

    const Row = React.memo(({ item, style, onPress }: RowProps) => { return <Pressable style={style} onPress={onPress}><Text>{item.name}</Text></Pressable>; }); function List({ items }: { items: Item[] }) { return ( <>{items.map((item) => ( <Row key={item.id} item={item} style={{ padding: 8 }} onPress={() => select(item.id)} /> ))}</> ); }
    next: new
  6. CodeSenior

    Map-based LRU cache

    data-structurestypescriptcaching

    Implement an LRUCache<K, V> with a fixed capacity exposing get(key) and set(key, value), both O(1). When over capacity, evict the least-recently-used entry. Any access (get or set) counts as a use.

    next: new
  7. CodeMid

    Implement throttle (and contrast with debounce)

    timersperformanceclosures

    Write a throttle(fn, wait) that invokes fn at most once per wait ms (leading edge), forwarding arguments and preserving this. In one line, state how throttle differs from debounce.

    next: new
  8. CodeSenior

    Retry fetch with exponential backoff + AbortController

    asyncnetworkingabortcontrollerresilience

    Write fetchWithRetry(url, { retries, baseDelay, signal }) that retries failed/non-OK responses with exponential backoff (plus jitter), respects an outer AbortController signal so callers can cancel, and per-attempt times out after a budget. Throw the last error if all attempts fail.

    next: new
  9. CodeJunior

    Normalize an array into a by-id Record

    typescriptdata-modelingutilities

    Write normalizeById<T>(items, getId) that turns T[] into Record<string, T> keyed by each item's id, for O(1) lookups (the shape Redux/normalized caches use). Bonus: also return the ordered list of ids.

    next: new
  10. CodeJunior

    useToggle hook with stable handlers

    hooksstateusecallback

    Write useToggle(initial) returning [value, { toggle, setOn, setOff }] (or a tuple). The handlers must have stable identities across renders so children wrapped in memo don't re-render, and toggle must work correctly even if called multiple times in one tick.

    next: new
  11. DesignArchitect

    Real-time chat for a private-markets app

    real-timewebsocketsofflinesyncchat

    You are architecting the messaging layer of Valt Connect, a private-markets app where deal teams chat about confidential transactions on Twilio Conversations. Threads must feel instant, survive flaky elevator/garage networks, never duplicate or reorder a message, and load months of history smoothly.

    Design the client-side chat system end to end: transport choice, message ordering & dedup, an offline send queue, presence/typing, and history pagination. Walk through what happens to a message sent while the device is fully offline and how it reconciles when the socket reconnects.

    next: new
  12. DesignSenior

    Offline-first feed / news app

    offline-firstsynccachingfeedsqlite

    Design an offline-first news/feed app that must open instantly to fresh-enough content even with no connectivity (subway, plane), let users read, bookmark, and react while offline, and reconcile those actions when they reconnect.

    Cover the local store, the sync strategy (what's fetched eagerly vs lazily), conflict handling for offline writes, and how you keep the cache from growing unbounded. Explain cold-start behavior and how stale content is detected and refreshed.

    next: new
  13. DesignSenior

    Resumable image upload with retry & progress

    uploadsresumableretrybackgroundprogress

    Design a resumable image/file upload pipeline for a mobile app: users attach large photos/PDFs that must upload reliably over flaky cellular, show real progress, survive app backgrounding or being killed, and resume rather than restart.

    Specify the upload protocol (chunking/resume), progress reporting, the retry/backoff policy, and how you guarantee no duplicate or corrupt uploads. Walk through a 40MB upload that loses signal at 70% and the app is then backgrounded.

    next: new
  14. DesignArchitect

    Feature-flag & experiment system

    feature-flagsexperimentsrolloutconfiganalytics

    Design a feature-flag and A/B experiment system for a React Native app: product wants instant kill-switches, gradual rollouts, targeted cohorts, and experiments with stable bucketing — without shipping a new build for each change.

    Specify flag delivery & caching (so the app works on cold start and offline), evaluation (client vs server), bucketing/assignment stability, and exposure logging for analysis. Explain how a flag flips for 1% of users and how you guarantee a user doesn't flip-flop between variants.

    next: new
  15. DesignSenior

    Navigation, deep linking & auth gating

    navigationdeep-linkingauthroutingexpo-router

    Design the navigation, deep-linking, and auth-gating architecture for a React Native app with public, authenticated, and biometric-protected areas. A user can tap a deep link / push / universal link to a protected screen while logged out, mid-session, or with an expired token.

    Specify the navigation structure, how deep links resolve through auth state, how you defer-and-replay an intended destination after login, and how gating interacts with token refresh and biometrics. Walk through a universal link to a deep deal screen when the session is expired.

    next: new
  16. DesignArchitect

    Caching layer: server vs client state + invalidation

    cachinginvalidationserver-statereact-queryversioning

    Design the caching and cache-invalidation layer for a data-heavy RN app. You've previously shipped version-based cache invalidation; the team wants a principled story for what is cached, where, and how it gets invalidated when the backend data or schema changes underneath a long-lived install.

    Define the boundary between server state and client state, the cache layers (memory / persisted / image), the invalidation strategy (TTL vs event vs version), and how a backend schema or data-shape change forces a safe refresh without corrupting old caches. Explain what happens when the server bumps a data version while a user holds a stale persisted cache.

    next: new
  17. DesignArchitect

    Secure auth & token flow with biometrics

    authkeychaintokensbiometricsoauthsecurity

    Design the secure authentication and token-management flow for a regulated RN app, modeled on Valt Connect's FaceID/TouchID + Salesforce OAuth. You need secure token storage, silent refresh, biometric gating, and a clean story for theft/jailbreak and token compromise.

    Specify where tokens live (Keychain/Keystore), the refresh flow and how concurrent requests handle a 401, how biometrics gate access, and your revocation/logout teardown. Walk through app resume after 8 hours with an expired access token and a still-valid refresh token, behind Face ID.

    next: new
  18. DesignSenior

    60fps infinite list / feed

    performanceflashlist60fpsvirtualizationre-renders

    Design a 60fps infinite-scrolling feed with mixed-height cells, images, and interactive elements that must stay smooth on a low-end Android device while continuously fetching pages. Users report jank, blank cells on fast scroll, and dropped frames.

    Specify the list technology & virtualization, cell render budget (memoization, image strategy), pagination & prefetch, and how you keep work off the JS thread. Diagnose what causes blank cells and frame drops and how your design prevents them — including on the worst phone.

    next: new
  19. CodeSenior

    In-browser semantic search ranking

    in-browser-aisemantic-searchembeddingscosine-similaritytypescript

    You are building an offline, privacy-first semantic search over a small set of help articles, entirely in the browser. At build/index time you already produced an embedding for each document using a MiniLM model (Transformers.js, Xenova/all-MiniLM-L6-v2, 384 dimensions). At query time you embed the user's query with the same model and the same pooling/normalization settings.

    Given an array of documents, each with a precomputed embedding, and a single query embedding, write the ranking layer in TypeScript:

    • Implement cosineSimilarity(a, b) over two numeric vectors.
    • Implement a topK ranker that returns the k most relevant documents, each with its similarity score, sorted descending.

    Assume embeddings are produced with { pooling: "mean", normalize: true }. Explain how that assumption affects your similarity math, and call out the edge cases you would guard against.

    next: new
  20. CodeSenior

    Use Chrome's Prompt API with graceful fallback

    in-browser-aiprompt-apigemini-nanofeature-detectiontypescript

    Chrome ships an on-device Prompt API backed by Gemini Nano, exposed as window.LanguageModel. The model may be unavailable, downloadable (needs a one-time download), downloading, or available, and the global may not exist at all in other browsers.

    Write a TypeScript async helper, askOnDevice(prompt), that:

    • Feature-detects window.LanguageModel.
    • Calls availability() and handles each state.
    • Creates a session, wiring a downloadprogress monitor so a multi-megabyte model download can report progress.
    • Prompts the model and returns the text.
    • Throws a clear, typed error (or signals a fallback) when on-device inference is not possible — so the caller can fall back to a cloud API.

    Be explicit about passing the same options to availability() and create(), and about why feature detection matters here.

    next: new
  21. DesignArchitect

    Design a privacy-first on-device AI study tutor

    in-browser-aisystem-designprivacywebgpuweb-workerrag

    Design a privacy-first study tutor that runs AI entirely in the browser. Students upload their own notes (PDFs, pasted text) and then: (1) semantic search over their notes, (2) ask questions and get grounded answers (RAG over their own material), and (3) get summaries / flashcards. A hard requirement: student notes must never leave the device — no server-side inference, works offline after first load, no per-query cost.

    Walk through how you'd architect this with today's browser AI stack (Chrome Built-in AI / Prompt API, Transformers.js, WebLLM, WebGPU, Web Workers, the Cache API). Cover model selection, feature detection and fallback, threading, caching, the privacy model, and the offline/cost tradeoffs. Be explicit about what degrades gracefully and what you tell the user when their device can't run a capability.

    next: new
  22. CodeJunior

    Two Pointers · Pair sum in a sorted array

    two-pointersarrays

    Given an array a sorted in ascending order and a target, return the 1-based indices of the two numbers that add up to target (exactly one solution exists). Use O(1) extra space.

    Example: a = [2, 7, 11, 15], target = 9 → [1, 2].

    next: new
  23. CodeMid

    Sliding Window · Longest substring without repeats

    sliding-windowstringshashing

    Given a string, return the length of the longest substring with no repeating characters.

    Example: "abcabcbb" → 3 ("abc").

    next: new
  24. CodeJunior

    Hashing · Two Sum (unsorted)

    hashingarrays

    Given an unsorted array nums and a target, return the indices of the two numbers that add up to target.

    Example: nums = [3, 2, 4], target = 6 → [1, 2].

    next: new
  25. CodeJunior

    Binary Search · Search insert position

    binary-searcharrays

    Given a sorted array and a target, return the index where target is, or where it would be inserted to keep the array sorted.

    Example: [1, 3, 5, 6], target = 4 → 2.

    next: new
  26. CodeMid

    BFS · Binary tree level-order traversal

    bfstreesqueue

    Return the values of a binary tree grouped by depth, top to bottom, left to right.

    Example: root 3, children 9 and 20, and 20's children 15 and 7 → [[3], [9, 20], [15, 7]].

    next: new
  27. CodeMid

    DFS · Number of islands

    dfsgridflood-fill

    A grid of "1" (land) and "0" (water). Count the islands — groups of land connected horizontally or vertically.

    Example: a grid with two separate land blobs → 2.

    next: new
  28. CodeJunior

    Dynamic Programming · Climbing stairs

    dynamic-programmingfibonacci

    You climb a staircase of n steps, taking 1 or 2 steps at a time. How many distinct ways to reach the top?

    Example: n = 4 → 5.

    next: new
  29. CodeJunior

    Stack · Valid parentheses

    stackstrings

    Given a string of ()[]{}, decide whether every bracket is closed by the correct type in the right order.

    Example: "([]{})" → true, "(]" → false.

    next: new
  30. CodeSenior

    Heap / Top-K · Top K frequent elements

    heapbucket-sorthashing

    Given nums and k, return the k most frequent values.

    Example: nums = [1, 1, 1, 2, 2, 3], k = 2 → [1, 2].

    next: new
  31. CodeMid

    Backtracking · Subsets (power set)

    backtrackingrecursion

    Return every subset (the power set) of a set of distinct integers.

    Example: [1, 2] → [[], [1], [1, 2], [2]].

    next: new
  32. CodeJunior

    Debug renders · useRenderCount hook

    hooksdebuggingperformance

    Write a useRenderCount(label?: string) hook that prints to the console every time a component re-renders, including a running count and the component label. This is a cheap development-only debugging aid to verify that your memoization is actually working before reaching for the profiler.

    Usage:

    const MyComponent = () => { useRenderCount('MyComponent'); return <Text>Hello</Text>; }; // Console: [MyComponent] render #1, #2, …
    next: new
  33. CodeJunior

    Re-render fix · inline object and function props

    performancere-rendersmemoization

    The component below has two performance bugs that cause Card to re-render on every parent update even though its data hasn't changed. Identify and fix both bugs without changing what the UI renders.

    const Feed = ({ items }) => { const [query, setQuery] = useState(''); return items.map(item => ( <Card key={item.id} item={item} style={{ marginBottom: 8 }} onPress={() => console.log(item.id)} /> )); }; const Card = memo(({ item, style, onPress }) => ( <Pressable style={style} onPress={onPress}> <Text>{item.title}</Text> </Pressable> ));
    next: new
  34. CodeJunior

    Hooks · useThrottle

    hookstimersperformance

    Write a useThrottle<T>(value: T, limit: number): T hook that emits the input value at most once per limit milliseconds. Unlike debounce (fires after silence), a throttle fires on the leading edge and then suppresses updates until the interval expires.

    Example use case: throttle a scroll position so expensive layout reads happen at most every 100 ms.

    next: new
  35. CodeJunior

    FlatList · stable keyExtractor + getItemLayout

    listsflatlistperformance

    You have a FlatList of fixed-height user cards (height = 80 dp, separator = 1 dp). Write the correct keyExtractor and getItemLayout props, then explain why each one matters for scroll performance.

    const ITEM_HEIGHT = 80; const SEPARATOR = 1; <FlatList data={users} renderItem={renderUser} // add keyExtractor and getItemLayout here />
    next: new
  36. CodeJunior

    React Compiler · enable in an Expo project

    build-toolsreact-compilerperformance

    Walk through enabling React Compiler in an Expo SDK 55+ project: install the ESLint plugin, install the Babel plugin, and configure Babel. Then show how to use the sources option to adopt it incrementally on just one directory.

    next: new
  37. CodeMid

    Lists · FlatList → FlashList migration

    listsflashlistoptimization

    Migrate this janky FlatList to FlashList. The list renders tweet-like cards with variable heights (approximate average: 120 dp). Add the minimal required props and explain what FlashList does differently under the hood.

    import { FlatList } from 'react-native'; <FlatList data={tweets} keyExtractor={(t) => t.id} renderItem={({ item }) => <TweetCard tweet={item} />} onEndReached={loadMore} onEndReachedThreshold={0.5} />
    next: new
  38. CodeMid

    Concurrent React · useTransition for tab switching

    concurrenthooksperformance

    A tab bar switches between three tabs. The "Analytics" tab renders a heavy chart component that takes ~200 ms to compute. Without optimization, tapping "Analytics" causes the entire UI to freeze while the chart renders, blocking the tab-bar press animation.

    Fix this using useTransition so the tab-bar tap feels instant and a loading indicator appears during the chart computation.

    next: new
  39. CodeMid

    Memory safety · useEventListener hook

    hooksmemoryevent-listeners

    Write a useEventListener(emitter, event, handler) hook that registers a native event emitter listener and guarantees cleanup on unmount, even if the component throws. The handler should always be the latest version (no stale closures).

    next: new
  40. CodeMid

    Reanimated · scroll-driven animated header

    animationreanimatedscroll

    Build a header that fades out as the user scrolls down and fades back in as they scroll up. The animation must run on the UI thread so it stays smooth even when the JS thread is busy processing data. Use Reanimated 3.

    next: new
  41. CodeMid

    Navigation perf · InteractionManager + useFocusEffect

    navigationperformanceinteraction-manager

    A screen loads expensive data inside useFocusEffect. When users navigate to it, the screen-transition animation stutters because the data fetch triggers heavy re-renders that compete with the animation. Fix it using InteractionManager so the expensive work defers until the animation finishes.

    next: new
  42. CodeMid

    Network perf · in-flight request deduplicator

    networkperformancecaching

    Multiple components mount simultaneously and each calls fetchUser(id) for the same user ID. This fires N duplicate network requests. Build a dedupeFetch(url) wrapper that collapses concurrent requests for the same URL into a single in-flight promise, returning the same result to all callers.

    next: new
  43. CodeMid

    Memory debug · find and fix a missing effect cleanup

    debuggingmemoryhooks

    The component below has a memory leak. A timer keeps running after the component unmounts, holding a closure over setCount which retains the component's state. Find the leak, explain what the DevTools timeline would show, and fix it.

    function LiveCounter({ userId }) { const [count, setCount] = useState(0); useEffect(() => { const id = setInterval(() => { fetchCount(userId).then((n) => setCount(n)); }, 5000); // return () => clearInterval(id); // accidentally deleted }, [userId]); return <Text>{count}</Text>; }
    next: new
  44. CodeSenior

    Bundle · diagnose and fix a barrel export

    bundlingtree-shakingperformance

    Your bundle includes the entire @icons/pack library (350 KB) even though you only use HomeIcon. The library has a barrel index.ts. Show: (1) how to confirm this with source-map-explorer, (2) the barrel-import culprit, and (3) the fix.

    next: new
  45. CodeSenior

    TTI · instrument the startup pipeline

    startupTTIperformance-markers

    Add TTI measurement markers to a React Native app using react-native-performance. Place markers at: (a) the JS bundle finishing load, (b) the home screen becoming interactive. Also show how to detect and exclude warm/hot starts from the measurement.

    next: new
  46. CodeSenior

    Atomic state · Jotai atoms + derived selector

    stateatomsperformance

    Convert a Redux-style global store that causes full-tree re-renders into Jotai atoms. The store has filter (string) and todos (array). Add a derived atom for the filtered result so neither the filter nor the todos atom causes unnecessary re-renders in unrelated components.

    next: new
  47. CodeSenior

    View recycling · LegendList with recycleItems

    listslegendlistrecycling

    You have a chat list where messages can contain text, images, or voice notes (three different layouts). Implement it using LegendList with recycleItems enabled. Show how to handle the recycling caveat — components receiving different item types must not carry over stale local state from the previous item.

    next: new
  48. CodeSenior

    Native modules · avoid blocking the JS thread in a TurboModule

    native-modulesturbomodulesthreading

    A TurboModule exposes a synchronous readLargeFile(path) method to JS. In testing, calling it freezes the app for 800 ms. Explain why this happens, and show the pattern to fix it — both the JS spec and the native implementation change needed.

    next: new
  49. CodeSenior

    On-device AI · streaming LLM chat with react-native-executorch

    on-device-aiexecutorchllm

    Build a minimal chat screen using useLLM from react-native-executorch. Requirements: (a) download progress bar before the model is ready, (b) streaming token-by-token response display, (c) a Stop button during generation, (d) safe unmount that prevents a crash when the LLM is generating.

    next: new
  50. CodeSenior

    On-device AI · speech-to-text with Whisper

    on-device-aiexecutorchspeech-to-text

    Build a voice transcription screen using useSpeechToText from react-native-executorch and Whisper Tiny English. The flow: record audio → decode to 16kHz Float32Array → transcribe → display text. Show the key API calls and the audio format requirement.

    next: new
  51. CodeSenior

    On-device AI · real-time object detection with YOLO

    on-device-aiexecutorchcomputer-vision

    Build a screen that uses useObjectDetection from react-native-executorch with YOLO26N to detect objects in a photo. Show: (a) loading and running inference, (b) interpreting the bounding box output, and (c) how to use runOnFrame for real-time VisionCamera integration.

    next: new