Swizec Teller - a geek with a hatswizec.com

Senior Mindset Book

Get promoted, earn a bigger salary, work for top companies

Senior Engineer Mindset cover
Learn more

    Tips from 8 months of TanStack/Router in production

    On my last day at Tia I wrote a master vision doc for our TanStack Router app. Here are the parts I can share.

    These are battle-tested patterns and lessons learned from using TanStack Router in production since before v1. They worked well for us to iterate quickly, work as a team, and have shockingly few bugs. I can't know how they'll evolve in the future.

    TanStack Router 101

    If you need a refresher, TanStack Router is the modern React for the rest of us. It combines the best parts of Remix and NextJS for a wonderful type-safe routing experience with all the features you expect:

    • type safe routing, you'll get squiggly lines when linking to a path that doesn't exist
    • router coordinated data loading, you show 1 loading spinner for everything
    • suspense-first design, no more {isLoading ? ...} in your UI components
    • optional file-based routing, your code structure can follow your app structure
    • nested routes, your URLs can control specific portions of the UI

    UX vision for the app

    Our app is based on the principles of multi-page apps. An important nuance makes it different to the multi page apps of yore – we aim to use a unique URL for every significant UI state, but we avoid full-page reloads and round-trips to the server.

    This is where TanStack Router shines.

    Goals:

    • enable multi-tasking
    • support easy context sharing
    • empower unguided navigation through the app

    We're building for power users: they don't need us to hold their hands, they need us to get out of the way. This is the mental image I like to use for what we're building 👇

    tack Sjpg bg38c6

    Guiding principles:

    • URL for every significant UI state
    • every URL is independent
      • cross-page app state is for performance
      • a page should always rebuild itself on Cmd+R
      • if you share the link with someone, they should see the same thing you did
    • reduce clicks
      • autofocus first field of forms
      • support keyboarding through common tasks
      • auto-navigate to next logical place on form submit
    • prefer information density
    • maintain mental context across operations

    Code organization

    The app follows a file-based routing setup from TanStack Router.

    That means the file structure closely follows the URL structure, which makes things easy to find and fairly easy to collocate.

    We try to organize code into vertical modules or components – every page folder should contain everything it needs to work. And every component or function should live at the nearest shared space in the hierarchy.

    ../../../ imports are the main code smell to look out for.

    Horizontal concerns

    We've identified a few horizontal concerns like aspects of loading shared data and certain UI atoms that don't belong to any particular page.

    We try to treat those like libraries.

    There is a shared /data/ and /pages/-components directory for these which have a path alias for easier imports. This smells a lot like a custom SDK or ORM + component library and should be split off when it matures. Avoid leaking page-specific concerns into these.

    Data patterns

    TanStack Router supports data loaders at the router level and implements first-party Suspense support.

    In practice that means your components don't need to deal with their own loading and error states. You can build your components to focus on the happy path, then let the router handle loading and error states.

    A few rules of thumb we’ve developed over time:

    • use loaders for data that's required by the whole page
    • use suspense queries for data used by a single component
      • this lets the router handle coordination but keeps data scoped to your component
      • you don't need to handle loading/error states
    • use queries for data that depends on interaction
      • you have to implement loading/error states
      • good for typeaheads and such
    • use queries for deferable data used by a single component
      • you have to implement loading/error states
      • makes app feel faster
      • good for supplemental data
    • share code between loaders and queries
      • it makes life easier when you have a query function that works for both useQuery and loader
      • helps you ensure consistent cache keys
      • helps ensure consistent data access patterns for trickier things
    • yes this starts to look a lot like we're building an SDK or ORM

    Go gardening

    We like to take a sit-back-and-observe approach. Avoid generalizing code until you've been repeating the same thing and it def looks like a pattern. This makes it easier to keep code flexible and making the abstractions we do build feeling more natural.

    Hope this helps. It's a pile of app design guidelines I plan to keep in the next thing I touch.

    Cheers,
    ~Swizec

    Published on August 14th, 2024 in React, Suspense, Frontend, TanStack

    Did you enjoy this article?

    Continue reading about Tips from 8 months of TanStack/Router in production

    Semantically similar articles hand-picked by GPT-4

    Senior Mindset Book

    Get promoted, earn a bigger salary, work for top companies

    Learn more

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️