[HN Gopher] Build Your Own Router with URLPattern()
___________________________________________________________________
Build Your Own Router with URLPattern()
Author : tobr
Score : 54 points
Date : 2025-11-25 07:43 UTC (4 days ago)
(HTM) web link (jschof.dev)
(TXT) w3m dump (jschof.dev)
| teddyh wrote:
| SPA router, not IP router.
| embedding-shape wrote:
| Kind of obvious when a DOM/Web API is mentioned, isn't it?
| Besides, does it really matter? Same ideas you use for building
| a frontend router can be used to build a backend router, and
| vice-versa.
| simon04 wrote:
| Maybe not so much for an Internet Protocol router?
| teddyh wrote:
| The actual title, and the original HN story title, was "Build
| Your Own Router", which, in a general tech context like HN, I
| would assume mean an IP router.
| embedding-shape wrote:
| Sure, but once you open up the article and see browsers
| with green checkmarks next to them, and "this feature works
| across the latest devices and browser versions", then most
| people have to be getting what the coming body text is
| about, right?
| pscanf wrote:
| I've done something similar in a React project I'm working on to
| avoid dealing with the insanity that is react-router.
|
| Call me naive, but _routing in a single page application_ is just
| not that hard of a problem. At the core it 's about having a
| piece of state1 (your active route) which determines which part
| of the app you want to render-something you can do with a switch
| statement2. On top of that, you want to synchronize that state to
| the page URL3.
|
| Doing it yourself requires more boilerplate code, no question
| about it. But it's not that much code tbh (not very complex
| either), and you get back control over that important piece of
| state, which otherwise remains opaque and difficult to work
| with-i.e., its "shape" is pre-determined by the routing library
| you use. For example, react-router doesn't support parallel
| routes.
|
| 1 https://github.com/superegodev/superego/blob/main/packages/a...
|
| 2 https://github.com/superegodev/superego/blob/main/packages/a...
|
| 3 https://github.com/superegodev/superego/blob/main/packages/a...
| sampullman wrote:
| I don't think it's naive, I often do the same in Vue. A pretty
| useful subset of vue-router can be implemented in less than a
| tenth of the bundle size.
| embedding-shape wrote:
| I also basically re-invent a tiny 50 line router for every web
| project. Hardly ever go beyond "Map URL -> Page" and "Map URL +
| Parameters -> Page with properties", and when you do, knowing
| 100% how it works helps a lot.
|
| I also agree it isn't a hard problem, but personally I'd say
| you got the flow the wrong way around. You don't want to
| "synchronize state to the page URL" but rather treat the page
| URL as something you create state from, so it works both when
| you navigate there by pressing anchor tags, or the user
| manually enters the URL, and it gets a bit easier to manage.
|
| Basically, URL is the top-level state, and from there you
| derive what page, then render that page, rather than the other
| way around.
| pscanf wrote:
| Yeah, implementing it with data flowing one-way only from the
| URL to the state is cleaner.
|
| Conceptually, however, I prefer to think of my state being at
| the center of things. I mean, that's where I define (via
| types) what the state is. The URL is just one serialization
| of that state that is convenient to use in a web browser
| (making it work with links, back/forth buttons, etc). Maybe
| in another environment another serialization would be needed.
| Or maybe no serialization could be needed at all (making it a
| memory router).
| simon04 wrote:
| A very tiny router is provided by nanostores:
| https://github.com/nanostores/router
| johnfn wrote:
| If you are just working on a small website and you don't care
| about SEO or supporting more than, I dunno, a thousand users,
| then sure. But if you ever expect to do more than that, I might
| call you naive, yeah. One big thing: what if you want to
| support SSR, which I think is a pretty basic requirement these
| days? I'd submit that supporting SSR will take you a bit more
| than 50 lines.
| pscanf wrote:
| That's why I emphasized _routing in a single page
| application_. If one needs SEO, a client-rendered single page
| application is the wrong choice, regardless of the router.
|
| > One big thing: what if you want to support SSR, which I
| think is a pretty basic requirement these days?
|
| I agree it's a basic requirement for a certain class of apps
| and websites, but there are tons of apps for which SSR is not
| relevant and even detrimental (in the sense that it adds
| complexity that is not offset by the benefits it brings).
| jazzypants wrote:
| Is this really that much easier than matching paths and query
| strings yourself? I'm glad that there is an official API now, but
| this article didn't really show me anything to get excited about
| as someone who has built several client-side routers from
| scratch.
| bob1029 wrote:
| Writing a _fast_ router can be surprisingly difficult if you
| are trying to cover the edges. The state of the art is not
| trivial:
|
| https://github.com/dotnet/aspnetcore/blob/main/src/Http/Rout...
| embedding-shape wrote:
| The thing is, performance in that particular context hardly
| matters, unless you're forcing users to switch pages faster
| than 1 page per second. Even if each resolving takes 0.1
| seconds (which be bad, don't get me wrong), 99% of users
| wouldn't notice a thing, and if you're a small
| agency/shop/company/team, focusing on more general things
| tends to be time spent better.
| recursive wrote:
| I have a hard time imagining how one would implement a
| router that took a full millisecond to resolve a path in a
| typical case.
| embedding-shape wrote:
| Imagine doing a call to a remote authentication service
| to check who has access to what :) Regardless,
| performance is usually not the biggest problem in those
| types of routers.
| jazzypants wrote:
| You're assuming that URLPattern is performant... That doesn't
| seem to be the case currently.
|
| https://adventures.nodeland.dev/archive/you-should-not-
| use-u...
|
| https://github.com/denoland/deno/issues/19861
| embedding-shape wrote:
| > assuming that URLPattern is performant
|
| Whose implementation, specifically? I don't think as
| specified URLPattern has any inherent performance drawbacks
| compared to the alternatives, but it seems like
| V8/NodeJS/Deno definitely didn't thought closely and/or
| clearly about performance when they did theirs.
| jazzypants wrote:
| All three of those use the same implementation. I would
| hope that this will be improved over time, but it's not a
| guarantee by any stretch of the imagination.
| embedding-shape wrote:
| Thanks, I wasn't sure, as I thought Deno used V8 but then
| the issue linked earlier shared "The implementation of
| URLPattern in Deno is super non-performant" so it seemed
| to me like Deno maybe had their own implementation
| instead of using the V8 one.
| spankalee wrote:
| URLPattern can be _plenty_ fast if you use them in a fast
| data structure, like a prefix tree as pointed out in that
| first link. And there 's no reason why URLPattern can't do
| that.
|
| So I went and made an implementation of URLPatternList that
| uses a prefix tree and is 20-30x faster than a linear scan
| for large lists of URLPatterns:
| https://github.com/justinfagnani/url-pattern-list
| tinco wrote:
| This seems really irrelevant to the browser. I wonder why this
| was standardized, JavaScript is easily powerful enough to express
| this. Surely it hasn't been a performance bottleneck for it
| needing a native api?
|
| I agree with the other two comments, surely almost every frontend
| webdev has implemented a router in their career unless they never
| strayed from the major frameworks. It's really not a complicated
| thing to have to build. I'm not one to look a gift horse in the
| mouth but I don't see why we're being given this one.
| embedding-shape wrote:
| Anytime I end up wondering "Why do we have feature X on the
| web?" I tend to up end reading through proposals and I always
| end up finding a suitable answer that makes me wonder no more.
| For this specific feature, there is lots of prior discussions
| about why this is needed in the first place here:
| https://github.com/whatwg/urlpattern
| kemayo wrote:
| Based on
| https://github.com/whatwg/urlpattern/blob/main/explainer.md
| it looks like they _specifically_ wanted it as a way to scope
| service workers so it 's easy to make them only run on
| certain parts of a site, and viewed giving people something
| easy to use for other URL matching as a nice bonus.
| jauntywundrkind wrote:
| I'm really glad we have URLPattern, as it's a fairly mundane task
| that shouldn't need us to bring in special tools. I can't
| imagining argue that the plarform shouldn't come well equipped
| for basic cases like this. Ideally a native implementation will
| be able to use SIMD and be faster too, which is a nice to have.
|
| Unfortunately cases like here in the article are an example of
| why URLPattern had enormous push back during development. It's
| not the worst thing in the world to run three or four patterns
| one after another. But generally, doing a linear search for the
| right pattern doesn't scale well at all! If there's a dozen
| routes, running pattern after pattern is probably not ideal!
|
| We can look at Hono routers, for example. Which has a bunch of
| different examples, most of which will one-shot a bunch of
| patterns at once. RegExpRouter, TrieRouter. There's good write-
| ups for the tradeoffs across them. But they all take a bunch of
| routes up front, and combine them into a single matcher,
| attempting to re-use work across patterns.
| https://hono.dev/docs/concepts/routers
|
| Really good we have URLPattern, but this is the anti-use-case,
| that almost convinced folks not to make URLPattern at all.
| jslakro wrote:
| Page.js is a good alternative for a client-side router
| https://visionmedia.github.io/page.js/
| spankalee wrote:
| As a maintainer of Lit, this statement seems a little off to me:
|
| > Another thing- should we be building a router with web
| components? Eh... maybe not? Lit seems to think (it would be
| helpful and useful)[1]. But there are a lot of considerations you
| have to handle with your own implementation that framework
| routers have already solved. Web components also add another
| level of security you need to be aware of.
|
| The Lit Labs router isn't a web component. It's a Lit reactive
| controller that lets you define a router separately from a
| component, but attach it to a component so that the component
| updates when routes change. So we're saying _don 't_ make your
| router a web component (ie `<my-route path="...">`
|
| Also there isn't another level of security web components.
| They're implemented in script just like a router. Script running
| in a page can do all kinds of things.
|
| [1]: https://www.npmjs.com/package/@lit-labs/router
___________________________________________________________________
(page generated 2025-11-29 23:01 UTC)