Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

rill

rill-js462MIT7.0.4TypeScript support: included

Universal router for web applications.

api, app, application, framework, http, isomorphic, marko, middleware, react, rill, router, svelte, universal, web

readme

Rill Logo
API stability TypeScript NPM version Build status Test Coverage Downloads Browser Bundle Size (Gzipped) Gitter Chat Sauce Test Status

Expressive router for nodejs and the browser. Rill brings cascading middleware to the browser and enables a familiar routing solution for web applications.

Rill provides the minimum for abstractions over nodejs and the browser enabling things like routing (with redirecting, refreshes and more), cookies, and middleware with the same api.

It supports many view engines including Marko, React, Svelte and even html only template engines such as Pug.

Installation

npm install rill

Browser support

All modern browsers are supported including IE10 and above. Older browsers will need to polyfill the Promise API, checkout es6-promise for a good polyfill, babel-polyfill also covers this.

Community

Articles

Why Rill?

Rill is the answer to a simple question; Can I run my Express style router in the browser? Turns out you can and it works awesome.

It brings a common interface to many typical app like features in both the browser and nodejs. Many isomorphic frameworks and routers have crazy abstractions and learning curves but with Rill, if you understand Express or Koa, you already know how the routing works! In Rill you get to program much of your application logic using the same api (client or server) including routing, rendering, data fetching and more are easily shared.

Rill also works perfectly as a stand alone router for nodejs or in the browser. This allows for easy progressive enhancement. If all is well the browser can handle much of your application logic and if JavaScript fails for any reason your server knows exactly what to do.

How does this thing work?

If you look at the source for Rill here you will quickly notice there is ZERO browser specific code. This is all thanks to @rill/http which is node's HTTP.createServer ported to the browser.

In the browser it works by listening for internal link clicks, form submissions and browser history changes. It will then create a Rill Context for each of these events and emit it through the router, similar to how receiving a request works in nodejs.

It supports everything you'd expect from a client side nodejs server. This includes redirects, refreshes, cookies, scrolling and url updates using the History API.

Example

Create an app

/**
 * The following code can run 100% in the browser or in nodejs.
 * Examples use es2015/2016 with Babel and JSX but this is optional.
 */

import Rill from 'rill'
const app = new Rill() // You can call Rill without new, but autocomplete will not work.

Setup middleware

// Universal form data parsing middleware.
import bodyParser from '@rill/body'
app.use(bodyParser())

// Universal react rendering middleware.
import reactRenderer from '@rill/react'
app.use(reactRenderer())

// Example Logger
app.use(async ({ req }, next)=> {
  const start = Date.now()

  // Rill uses promises for control flow.
  // ES2016 async functions work great as well!
  await next()

  const ms = Date.now() - start
  console.log(`${req.method} ${req.url} - ${ms}`)
})

Setup a page

// Respond to a GET request.
app.get('/todos', async ({ res })=> {
  // Fetch a todolist from some service.
  const todolist = await MyTodoListService.getAllTodos()

  // Directly set React virtual dom to the body thanks to @rill/react.
  // (Checkout @rill/html for universal html diffing).
  res.body = (
    <html>
      <head>
        <title>My App</title>
        <meta name="description" content="Rill Application">
      </head>
      <body>
        <form action="/add-todo" method="POST">
          <h1>Just a plain old form</h1>
          <input type="text" name="todo"/>
          <button type="submit">Add Todo</button>
        </form>

        {todolist.length
          ? todolist.map(renderTodo)
          : 'No todos to display.'
        }
        <script src="/app.js"/>
      </body>
    </html>
  )
})

Handle a form submission

// Respond to a POST request.
app.post('/add-todo', async ({ req, res })=> {
  // We handle form submissions with Rill the same way one would express or koa.
  // Here we are simply adding the todo via some service.
  await MyTodoListService.addTodo({ text: req.body.todo })
  // And then we redirect back (same as res.redirect('/todos'))
  res.redirect('back')
})

Start app

// Start a regular http server.
// In the browser any form submissions or link clicks will intercepted by @rill/http.
app.listen({ port: 80 })

See Also

  • isbrowser - A browserify transform to remove server-side code.
  • isomorphic-fetch - Universal http requests using WHATWG fetch.
  • isomorphic-form-data - Send multipart form data universally (able to send files and works with fetch).
  • scroll-behavior - @rill/http will automatically try to use the "smooth" scroll-behavior when scrolling to targets on link clicks. This will polyfill that across modern browsers.
  • submit-form - Manually trigger Rill navigation in the browser.

Prior Art

  • koa-client - Koa clone that runs in the browser, inspired this package.
  • monorouter - Another isomorphic router that partially inspired this package.

Contributions

  • Use npm test to build and run tests.

License

MIT

changelog

Change Log

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

7.0.3, 7.0.4 - 2018-02-27

  • Add type definitions for params, querystring, cookies and cookie serialization options.
  • Add type definitions for TLS options.
  • Updated dev dependencies.
  • Update license dates.

7.0.1, 7.0.2 - 2017-11-18

  • Update links to todomvc examples in readme.
  • Fix bad URL for size badge and update size in readme.

7.0.0 - 2017-11-17

  • Changes to handling URLS with a hash in @rill/http.
    • No longer intercept hash changes (allows for default browser action).
    • No longer add hash to req.url or req.headers.referer for consistency with server side http.
    • Removes built in smooth scrolling on urls with a hash.
  • res.status now starts as undefined instead of 404. (Will still default to 404 if no body set during response).
  • ctx.fail and ctx.assert no longer set res.status or res.message if the error was caught.
  • Drop official support for IE9.
  • Remove official bower support.
  • No longer provide prebuilt bundle.
  • Fully convert project to typescript. (Autocomplete for VSCode!)
  • Setup tslint and prettier for formatting.

6.0.0, 6.0.1, 6.0.2 - 2017-10-10

  • Upgraded @rill/http to 6.0.0
  • Better support for typescript with improved JSDoc.
  • Sets booleans by default instead of undefined for res.finished, res.end and res.respond.

5.0.13, 5.0.14 - 2017-08-03

  • Remove obsolete version field from bowser.json.
  • Add related airbnb article to readme.
  • Updated dev dependencies.

5.0.10, 5.0.11, 5.0.12 - 2017-07-30

  • Updated middleware list url in readme.
  • Add benchmarks folder for comparisons with Koa/Express.
  • Switch uglifyjs back to dev dependency.

5.0.7, 5.0.8, 5.0.9 - 2017-07-27

  • Switch to white listing files in package.json.
  • Added survivejs interview.
  • Added bundle size analyzer script for future improvements.
  • Update dependencies.
  • Update license year.
  • Update bower version.

5.0.6 - 2017-07-19

  • Switched logo to SVG.

5.0.4, 5.0.5 - 2017-06-13

  • Added new article.
  • Switch mocha tests to use promises.

5.0.1, 5.0.2, 5.0.3 - 2017-06-06

  • Update dependencies.
  • No longer relies on process.browser, instead uses browser field to attach to document.

5.0.0 - 2017-05-18

  • Upgraded @rill/http which has a breaking change. (This change will only be breaking for those who rely on @rill/http directly)

4.3.4, 4.3.5 - 2017-04-23

  • Update dependencies.
  • Misc documentation cleanup.

4.3.2, 4.3.3 - 2017-03-28

  • Update dependencies. (Fixes issue in mini-url where the base URL was not optional in some browsers).

4.3.1 - 2017-03-23

  • Fix download link in readme.

4.3.0 - 2017-03-23

  • Ensure all requests in the browser are async.

4.2.0, 4.2.1 - 2017-03-23

  • Update @rill/http which added new options to the browser adapter's 'fetch' method. Also a url string is now allowed as the first argument.

4.1.5 - 2017-03-23

  • Fix regression with parsing querystrings on GET forms.

4.1.3, 4.1.4 - 2017-03-21

  • Update logo link for npmjs.com.
  • More JSDoc improvements.

4.1.2 - 2017-03-17

  • Fixed regression where referrer header was no longer the full href.

4.1.1 - 2017-03-14

  • Improve inline JSDoc comments.

4.1.0 - 2017-03-11

  • Removed need for fetch api polyfill. (Promise polyfill still needed for older browsers).
  • Optimized Rill's file size in several ways.
    • Switched to events-light from browserify events shim.
    • Switch to mini-url and mini-querystring from browserify url and querystring shims.
    • Removed unused methods from @rill/http.
    • Removed Buffer dependency in the browser, now uses Blobs.

3.0.0 - 2016-11-01

2.5.2 - 2016-11-08

  • Add node 7.0.0 to travis build.

2.5.0, 2.5.1 - 2016-11-08

  • Fix for breaking change in HttpServer#listen in node 7.0.0.

2.4.0 - 2016-10-12

  • Updated @rill/http. This fixes an issue in safari where named submit buttons were not being parsed on form submissions.
  • Updated pathToRegexp. This allows for better hostname matching support (previously some issues existed for splat host names such as 'mysite.:something+.com'), this should now be fixed.

2.3.0 - 2016-10-01

  • Exposes ctx.req.matchPath and ctx.req.matchHost which allow users to check what the current path and host being matched are.
  • Splat paths (such as /test/*) will now properly make trailing slashes optional. In this case /test is now treated as valid where before only /test/ would have been valid.

2.1.8 - 2016-09-28

  • Updated @rill/error which now has two new methods (fail and assert).

2.1.7 - 2016-09-24

  • Added another isomorphic article to README.
  • Updated dev dependencies.

2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6 - 2016-09-17

  • Link rill logo to rill website.
  • Changed readme logo to use SVG from rill website.
  • Updated any references to docs to the rill website.
  • Move some NPM scripts to makefile.
  • Remove duplicate info in docs.
  • Remove some unneeded files when installing with bower.

    Added

  • Added docs back to package.json files for use on the docs website.

2.1.1 - 2016-09-14

  • Added node_modules caching to travis.
  • Added make file (replaces gulp).
  • Added sourcemap to dist.

Removed

  • gulpfile.js (replaced by makefile).

2.1.0 - 2016-09-14

  • Added "files" field to package json and now only "src" files are uploaded to npm.

2.0.1 - 2016-09-13

2.0.0 - 2016-09-9

  • Upgraded @rill/http@2.0.0 this has two (potentially breaking) fixes.
    • req.headers.referrer will now be a full href instead of a pathname.
    • Smooth scroll (with hash targets) will now only run when navigating from a page with the same path.

1.1.2 - 2016-09-2

Added

  • Much more tests (100% coverage!)
  • Travis CI
  • Coverage and build badges.

  • Updated dependencies.

  • Added code coverage and testing utilities.
  • Cleaned up code while testing.

1.0.0 - 2016-09-2

Added

  • CHANGELOG.md

  • Updated dependencies.

  • Marked as version 1.0.0 (STABLE).