Skip to content

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Nov 17, 2025

New article related to this PR: TanStack/router#5722

@netlify
Copy link

netlify bot commented Nov 17, 2025

👷 Deploy request for tanstack pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 878670b

@Sheraff
Copy link
Contributor Author

Sheraff commented Nov 17, 2025

Review by Claude

You're right, let me give you more critical feedback. I was being too polite - there are definitely areas that need work.

Major Issues

1. Inconsistent and Confusing Performance Claims

Your numbers are all over the place and don't add up:

  • Title claims "20,000×"
  • Introduction says "20,000×"
  • Then you show "60× for small apps, 10,000× for big apps"
  • Later you admit the 20,000× is cherry-picked
  • The evolution charts show much more modest improvements

This creates confusion. Pick ONE consistent narrative. Either lead with realistic numbers or clearly frame the 20,000× as a best-case scenario from the start.

2. Poor Code Examples

Several code snippets are incomplete or misleading:

// This is useless without showing what matches() does
if (matches(...)) {
    stack.push({/*next frame*/})
}
// This type definition is confusing and incomplete  
type Segment = Uint16Array & {0: SegmentKind, 1: number, 2: number, ... }

The ... in the type definition is particularly bad - it looks like you got lazy with the example.

3. Algorithmic Complexity Explanation is Wrong

Your complexity analysis is misleading:

Old approach: O(N) where N is the number of routes in the tree.
New approach: O(M) where M is the number of segments in the pathname.

This is comparing apples to oranges. The old approach complexity should also factor in pathname segments. A more honest comparison would be:

  • Old: O(N × M) in worst case
  • New: O(M × log N) or O(M) with good branching factor

Your 50% elimination example is overly optimistic and doesn't reflect real-world routing patterns.

4. Technical Errors and Unclear Explanations

In the bitmasking section:

beyond what optional segments will never be considered skipped

This sentence is grammatically broken and technically unclear.

The LRU cache section says it performs "half as well as a regular Object" but doesn't explain why you'd choose it over other caching strategies.

5. Missing Context for Key Decisions

  • Why choose a trie over other data structures?
  • How does this compare to other router implementations?
  • What's the memory overhead of the trie vs the old approach?
  • Why not use a hash map for static routes?

6. Weak Benchmarking Methodology

You mention testing against "production applications" but provide no details about:

  • What constitutes a "small" vs "big" app
  • Hardware/environment specifications
  • How many runs, statistical significance
  • Whether you're measuring cold starts vs warm performance
  • If the benchmarks account for route tree construction time

7. Poor Structure in Implementation Details

The "Fun Implementation Details" section reads like a random collection of optimizations rather than a coherent explanation. The order doesn't make logical sense - you should explain the core trie structure first, then the traversal algorithm, then micro-optimizations.

8. Misleading Conclusion

This wasn't a "let's make it faster" project, it was a "let's make it correct" project

But then you spend the entire article talking about performance numbers. If correctness was the main goal, show examples of incorrect matches that were fixed, not just performance charts.

Specific Technical Issues

Backwards Stack Processing

Your explanation of why you iterate in reverse is convoluted. The real reason is simpler: you want to process higher priority routes first, and array.pop() is more efficient than array.shift().

Bitmasking Limitation

You casually mention the 32-segment limit but don't discuss the implications. What happens when someone exceeds this? Does it fail silently? Throw an error? This is a critical design limitation.

TypeScript Claims

And TypeScript handles this very well, so we don't need to type the buffer

This is wrong. The intersection type Uint16Array & {0: SegmentKind, ...} is not well-supported and will cause issues with type checking. You're making TypeScript do something it's not designed for.

Writing Issues

Tone Inconsistency

You switch between casual ("Let's be honest") and technical throughout. Pick one and stick with it.

Weak Transitions

Many sections just start abruptly without connecting to the previous content. The flow between "Algorithmic Complexity" and "Fun Implementation Details" is particularly jarring.

Unnecessary Hedge Words

"pretty big app", "insane numbers", "feels reasonable" - these undermine the technical authority of the post.

What's Actually Missing

  1. Real correctness examples - show actual routing bugs that were fixed
  2. Memory usage analysis - trie structures use more memory
  3. Comparison to other routers - how does this stack up against React Router, Next.js router, etc.?
  4. Edge cases - what are the limitations of the new approach?
  5. Migration impact - does this change break anything for users?

The post reads more like a performance bragging session than a thorough technical explanation of a significant architectural change.

Copy link

@LeCarbonator LeCarbonator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reads well! I was able to follow along just fine, even though I've never heard of LRU caching before.

I mostly corrected grammar and rephrased some sections. Apply the changes you think are approriate.

Copy link
Contributor

@beaussan beaussan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! :D
Couples of notes:

  • You could explain what is a trie (very quick tldr, not in depth), or at least point to a wikipedia article about it
  • You could also add a bit on the exploration of other routers path mapping to see what is usually correct vs not

An alternative title could be : How we accidentally made route matching more performant by aiming for correctness

@Sheraff Sheraff marked this pull request as ready for review November 18, 2025 11:51
Copy link
Collaborator

@tannerlinsley tannerlinsley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hereby approve this blog post ✅

@LadyBluenotes LadyBluenotes merged commit 2d67dc9 into TanStack:main Nov 19, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants