Network Performance Monitor

    TypeScript icon, indicating that this package has built-in type declarations

    6.1.1 • Public • Published


    Standard Router Driver for Motorcycle.js

    A driver built on top of @motorcycle/history and switch-path to ease the pain of routing. Works server-side and in browsers!

    Let me have it!

    npm install --save @motorcycle/router

    Basic Usage

    import { run } from '@motorcycle/run';
    import { makeDomComponent, div, h1 } from '@motorcycle/dom';
    import { History } from '@motorcycle/history';
    import { Router } from '@motorcycle/router';
    import { of } from 'most';
    function Main(sources) {
      const match$ = sources.router.define({
        '/': HomeComponent,
        '/other': OtherComponent
      const page$ = match$.map(({path, value}) => {
        return value({...sources, router: sources.router.path(path)});
      return {
        dom: page$.map(c => c.dom).switch(),
        router: page$.map(c => c.route$).switch().startWith('/'),
    const Dom = makeDomComponent(document.querySelector('#app')));
    function Effects(sinks) {
      const { dom } = Dom(sinks);
      const { router } = Router(History(sinks));
    run(main, Effects)
    function HomeComponent() {
      const route$ = ... // left as a user exercise
      return {
        dom: of(div([h1('home')])),
    function OtherComponent() {
      const route$ = ... // left as a user exercise
      return {
        dom: of(div([h1('other')])),


    For all types not defined here, please refer to @motorcycle/history's type documentation here

    Router(sinks: HistorySources): RouterSources

    This is the main API of this driver. This function simply wraps @motorcycle/history and returns a source object containing methods instead of a stream.

    RouterComponent: RouterHOC

    A convenience function, to more declaratively define your routes to Components. It returns a stream of your currently matched Component. When using the router driver directly there is more flexibility. With the Router function, you must use routes to match to Components.

    function main(sources: Sources): Sinks {
      const sinks$: Stream<Sinks> =
          '/': HomeComponent, // HomeComponent :: (sources: Sources) => Sinks;
          '/profile: {
            '/': ProfileComponent,
            '/:id': (id: number) => (sources: Sources) => ProfileId({...sources, id}),
        }, sources);
      return {
        DOM: sinks$.map(sinks => sinks.dom).switch(),
        router: sinks$.map(sinks => sinks.route$).switch()



    This is a type representation of the object passed into your main function.

    export interface RouterSource {
      history(): Stream<Location>;
      path(pathname: Pathname): RouterSource;
      define(routes: RouteDefinitions): Stream<DefineReturn>;
      createHref(path: Pathname): Pathname;

    history(): Stream<Location> - This method allows you to reach the underlying stream provided by @motorcycle/history.

    path(pathname: Pathname): RouterSource - This method allows you to created nested router instances, very much like creates a new place in the DOM tree to look for elements and events, this allows dynamically created routes that can be matched that are decoupled from any parent routes.

    define(routes: RouteDefinitions): Stream<DefineReturn> - This method takes an object (anything supported by switch-path) of keys that represent your routes and returns a stream with an object that repesents any matches.

    createHref(path: Pathname): Pathname - This method allows you to create Hrefs that are namespaced at any RouterSource instance.

    const nestedRouter = sources.router.path('/some').path('/path')
    const href = nestedRouter.createHref('/unaware/of/nesting')
    console.log(href) '/some/path/unaware/of/nesting')


    export interface DefineReturn {
      location: Location;
      createHref: (path: Pathname) => Pathname;
      path: string | null;
      value: any | null;


    export interface RouteDefinitions {
      [key: Pathname]: any;


    export interface RouterHOC {
      <Sources, Sinks>(definitions: RouterDefinitions<Sources, Sinks>,
        sources: RouterSources<Sources>): Stream<Sinks>;
      <Sources, Sinks>(definitions: RouterDefinitions<Sources, Sinks>): 
        (sources: RouterSources<Sources>) => Stream<Sinks>;


    npm i @motorcycle/router

    DownloadsWeekly Downloads






    Last publish


    • avatar
    • avatar
    • avatar