Open-source project
STRML/react-router-component avatar
STRML/react-router-component

react-router-component puts the route table in the React tree

Declarative router component for React.

870 stars82 forksJavaScriptMIT

At a glance

What is it?
react-router-component is a small declarative router for React that lets you define routes as children of a Locations component. The idea is still sound, but the package targets React 15 and 16 and its last push was on 2026-04-09.
Who is it for?
react-router-component is a reasonable pick for a React 15 or 16 codebase that wants routes declared inside its own component tree and needs hash routing or server side rendering in the same package. It is the wrong choice for a React 18 or 19 project, since the compatibility table stops at React 16 and the code depends on create-react-class.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Routes are children, not a configuration object

react-router-component solves a routing problem in a specific way. Instead of handing a library a route table, you return a router component from your render method and describe each route as a child element. The README puts it plainly, that routes are defined as part of the component hierarchy.

That choice buys a specific capability: the set of allowed routes can change with application state. The example the documentation gives is returning different locations for anonymous and signed in users, which means access control can be expressed as rendering rather than as a redirect inside a handler. The router also dispatches on location.pathname or, when the browser has no History API, on location.hash, so a deployment without pushState support is not a dead end.

Props reach the handler in two ways. They can be set directly on each Location element, or applied to every route at once through a childProps hash. That is the mechanism to reach for when every page needs the same session, locale or theme value.

url-pattern and urllite do the actual matching

The dependency list shows how little of this is hand rolled. Pattern matching comes from url-pattern at version 1.0.1, URL parsing from urllite at 0.5.0, and query string parsing from qs at 6.11.1. On top of that sit create-react-class 15.7.0, prop-types 15.8.1, object-assign, object.omit and is-equal-shallow.

Two of those entries carry real consequences. create-react-class means the component style predates the class component era being standard, and it is the clearest signal of the generation this package belongs to. prop-types means handlers still receive a runtime check on their props. is-equal-shallow and object.omit point to shallow comparison being used to decide whether a route element needs to re-render, which is the kind of detail that explains why the package can stay small while still avoiding redundant renders.

The README states that the size is about 3.5kb gzipped. The README also lists advanced features including regex matching, full page server side rendering, multiple routers on the same page and contextual routers, so the feature list is longer than the dependency list would suggest.

Installing the package and returning a Locations component

The package is published on npm under its own name, and the install is the standard one:

bash
    % npm install react-router-component

The first use is a router component with Location children, where each Location takes a path and a handler. The README gives this shape:

js
    <Locations>
      <Location path="/" handler={MainPage} />
      <Location path="/users/:username" handler={UserPage} />
      <Location path="/search/*" handler={SearchPage} />
      <Location path={/\/product\/([0-9]*)/} handler={ProductPage} />
    </Locations>

Read the four patterns closely, because they cover the three matching styles the package supports. A static path is a literal, a colon introduces a named parameter such as :username, a trailing asterisk is a wildcard, and a regular expression literal lets you capture a numeric product identifier. The last case is the reason the dependency on url-pattern is worth understanding rather than ignoring: the path prop accepts a pattern object as well as a string, and the documentation links to a page on overriding the URL pattern compiler if the default behaviour does not fit.

Hash routing is a fallback rather than a separate API

Old browsers and static file hosting are the reason the hash routing page exists. The router dispatches on location.pathname when the History API is available and falls back to location.hash otherwise, which means the same component tree serves both cases.

That fallback is not free. A hash based URL changes what the user sees in the address bar, and it changes what a server receives, since the fragment is never sent to the origin. For a full page server side rendering setup this distinction matters, and the documentation keeps server side rendering on its own page rather than folding it into the routing page, which suggests the two paths are not simply interchangeable.

The documentation index lists server side rendering, multiple routers, contextual routers, query string parsing, capturing clicks on anchor elements, a custom Link component, a custom router component, an animated router component written with ES6, and overriding the URL pattern compiler. It is a long index for a small package, and it is worth reading the implementation visualisation page before assuming the routing logic behaves the way you expect.

The build and release tooling is more current than the README

The repository has been modernised in places the README never mentions. There is a .babelrc, a .devcontainer directory, a playwright.config.js, and the dev dependency on @playwright/test at 1.49.1. Browser tests are built with esbuild and run through Playwright, and the Makefile wires them together:

bash
test-e2e: build-e2e
	@./node_modules/.bin/playwright test

The unit and server suites still run through mocha with @babel/register, and the lint target runs eslint over index.js and everything under lib and tests. The Makefile also defines release-patch, release-minor and release-major targets that bump the version in package.json with semver, commit the package.json and CHANGELOG.md, tag the result and push the tag to origin master before running npm publish.

Alongside that modern tooling, the README still shows a Travis CI badge and describes cross browser testing through SauceLabs, and the Makefile contains a .zuul.yml. The project has two testing stories now, one described in the README and one visible in the files, and the files are the current one.

Where the component tree approach beats a route table

The obvious comparison is with a router that keeps its configuration outside React, where a single object lists paths and components and a wrapper element renders the active one. The difference in approach is where the truth lives. A configuration outside the tree has to be imported, and it cannot depend on props or state without extra machinery. A router whose routes are children can be computed on every render, so a set of allowed paths can follow a permission check or a feature flag without a second source of truth.

The other comparison is a hand written switch statement in a root component. That approach is smaller in dependencies and easier to read for three routes, and it also loses every feature this package exists for: parameter extraction, wildcards, regex paths, hash fallback, query string parsing and server side rendering all have to be written by hand.

Where the component approach loses is testability and tooling. There is no static route list to inspect or generate a sitemap from, and a route that only appears when state allows it cannot be discovered without rendering the tree. For a large application with many routes, that trade is worth naming before you commit.

MIT licensed, React 15 and 16, last push on 2026-04-09

The licence is MIT, which is permissive and places no copyleft condition on use in a commercial product. Nothing here is legal advice, and specific compliance questions belong with your own counsel.

The maintenance picture needs stating plainly. The repository is not archived and the last push was on 2026-04-09. The version in package.json is 0.40.0, and the compatibility table in the README maps versions to React releases, with 0.39.0 and above listed against React 15 and 16, 0.32.0 against React 15, 0.27.0 against React 0.14, and older ranges for React 0.13, 0.12, 0.11 and 0.10. The dev dependencies pin react and react-dom at 16.14.0.

The release tags tell a different story from the working tree. The most recent GitHub releases listed are v0.36.3, v0.36.2 and v0.36.1, all dated 2016-12-08, which means the version in package.json is ahead of the newest tag in the repository history. For an application that must stay on React 15 or 16, this package is still a workable dependency. For anything newer, the React compatibility table stops exactly where the ecosystem moved on.

Editorial conclusion

react-router-component is a reasonable pick for a React 15 or 16 codebase that wants routes declared inside its own component tree and needs hash routing or server side rendering in the same package. It is the wrong choice for a React 18 or 19 project, since the compatibility table stops at React 16 and the code depends on create-react-class. Before adopting it, install react-router-component from npm, confirm your React version against the table in the README, and read the implementation notes on strml.viewdocs.io, because the package is at 0.40.0 in package.json while the newest published GitHub release tag is v0.36.3 from 2016.

Frequently asked questions

How do I install react-router-component?

The package is published on npm, and the README gives the install as npm install react-router-component. The repository also has a Makefile with an install target that runs npm install for you.

How do I pass props to a route handler in react-router-component?

Props can be set directly on each Location element, or supplied to every route at once through the childProps hash. The README describes both routes for passing data through the router.

Does react-router-component work without the History API?

Yes. The router dispatches on location.pathname or, when the browser does not support the History API, on location.hash, which is the hash routing behaviour documented on the project's own site.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. STRML/react-router-component on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/strml-react-router-component.svg)](https://hysenlabs.com/projects/strml-react-router-component)

Was this useful?