**Show HN: Schema First React Router**

As a developer, have you ever found yourself staring at a string of characters in your URL bar, wondering what it could possibly represent? A constant annoyance for many of us is the mismatch between our database's data types and the stringy props we receive from `useParams()`. It's time to take a step back and ask: does it have to be this hard?

Let's revisit the concept of treating APIs as Types, à la Servant. In this framework, you define your API's structure as a Type, which serves as a contract for your implementation. If you change the type, the compiler screams at you until you fix the implementation. This inspired me to wonder: why can't we have that in React?

**The Birth of Schema First React Router**

After some hacking and late-night staring at `infer` keywords, I arrived at a solution: defining routes as schemas. Instead of using weak strings like `/users/:id`, I wanted to specify the exact structure of my URL segments. This led me to create a system where TypeScript can infer the types of props passed to components without any code generation or build steps.

Here's an example of what this schema-based routing looks like:

```html const routes = [ { path: '/users/:id', schema: [number, string] }, { path: '/posts/:slug', schema: [string] } ]; ```

**The Magic Happens**

When you create the router, it takes your config and enforces the types specified in the schema. If someone tries to access `/users/banana`, the router blocks it at the door, preventing runtime errors that should have been compile-time errors.

**How It Works**

1. **Define Your Schema**: Specify the structure of your routes as an array of tuples, where each tuple represents a segment in the URL. 2. **Implement the Router**: Create the router using the `createRouter` function, which takes your config and enforces the types specified in the schema.

**Tuples vs. Named Parameters**

One benefit of using tuples is instant type inference without any build steps. If you swap the order of segments in your schema, TypeScript will flag every usage of `params[0]` in your component, ensuring that the correct types are used.

**Links Are Type-Safe Too**

No more broken links because of renamed routes or forgotten query parameters! With this approach, every link updates automatically when you rename a route or add/remove parameters.

**This is a Proof of Concept (PoC)**

This is an experiment in "What if?" and is currently running in my personal workspace. It's not on GitHub yet, but I plan to open source it properly once I've ironed out the kinks and written some actual documentation.