Describe what's incorrect/missing in the documentation
The instrumentation API here appears to formalize a third routing representation that neither aligns with the route definition graph nor the runtime match graph, and I’m struggling to understand how this can be made coherent long‑term.
Today, React Router already maintains two distinct but related structures:
the declarative route tree (patterns, nesting, loaders/actions)
the runtime match graph (params, resolved matches, data dependencies)
This PR introduces a third: an instrumentation graph that is derived from the declarative tree but consumed alongside runtime match data. The problem is that this third graph has no lifecycle guarantees, no synchronization contract, and no stated invariants.
For example: instrumentation receives pattern‑level metadata before route normalization, but loader/action instrumentation receives match‑level metadata after normalization. These two representations can diverge in subtle but meaningful ways (e.g., splat resolution, index route promotion, pathless layout collapsing).
If instrumentation consumers cannot rely on a single canonical routing representation, then what exactly is the contract of this API?
More importantly: what prevents future internal refactors (e.g., match resolution changes, nested data APIs, partial hydration) from breaking instrumentation consumers who have implicitly bound themselves to whichever representation happens to be exposed here?
Before this API can be considered viable, I think the project needs to answer a more fundamental architectural question:
Is React Router willing to define a canonical, stable routing model that instrumentation can depend on, or is instrumentation expected to track internal router behavior that may change across releases?
Without a clear answer, this API risks becoming an unstable observation layer that leaks internal implementation details rather than a principled instrumentation surface.
Describe what's incorrect/missing in the documentation
The instrumentation API here appears to formalize a third routing representation that neither aligns with the route definition graph nor the runtime match graph, and I’m struggling to understand how this can be made coherent long‑term.
Today, React Router already maintains two distinct but related structures:
the declarative route tree (patterns, nesting, loaders/actions)
the runtime match graph (params, resolved matches, data dependencies)
This PR introduces a third: an instrumentation graph that is derived from the declarative tree but consumed alongside runtime match data. The problem is that this third graph has no lifecycle guarantees, no synchronization contract, and no stated invariants.
For example: instrumentation receives pattern‑level metadata before route normalization, but loader/action instrumentation receives match‑level metadata after normalization. These two representations can diverge in subtle but meaningful ways (e.g., splat resolution, index route promotion, pathless layout collapsing).
If instrumentation consumers cannot rely on a single canonical routing representation, then what exactly is the contract of this API?
More importantly: what prevents future internal refactors (e.g., match resolution changes, nested data APIs, partial hydration) from breaking instrumentation consumers who have implicitly bound themselves to whichever representation happens to be exposed here?
Before this API can be considered viable, I think the project needs to answer a more fundamental architectural question:
Is React Router willing to define a canonical, stable routing model that instrumentation can depend on, or is instrumentation expected to track internal router behavior that may change across releases?
Without a clear answer, this API risks becoming an unstable observation layer that leaks internal implementation details rather than a principled instrumentation surface.