diff --git a/.travis.yml b/.travis.yml
index fb0b4ac..343e041 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,4 @@
language: node_js
node_js:
- 7
+ - 8
diff --git a/doc/api.md b/doc/api.md
deleted file mode 100644
index 4b4ccf0..0000000
--- a/doc/api.md
+++ /dev/null
@@ -1,72 +0,0 @@
-## API Reference
-
-
-* [local-web-server](#module_local-web-server)
- * [LocalWebServer](#exp_module_local-web-server--LocalWebServer) ⇐ module:middleware-stack ⏏
- * [new LocalWebServer([options])](#new_module_local-web-server--LocalWebServer_new)
- * _instance_
- * [.features](#module_local-web-server--LocalWebServer.LocalWebServer+features) : Array.<Feature>
- * [.options](#module_local-web-server--LocalWebServer.LocalWebServer+options) : object
- * [.view](#module_local-web-server--LocalWebServer.LocalWebServer+view) : View
- * [.server](#module_local-web-server--LocalWebServer.LocalWebServer+server) : Server
- * [.getApplication()](#module_local-web-server--LocalWebServer+getApplication) ⇒ function
- * [.getServer()](#module_local-web-server--LocalWebServer+getServer) ⇒ Server
- * _inner_
- * [~loadStack()](#module_local-web-server--LocalWebServer..loadStack) ⇒ object
-
-
-
-### LocalWebServer ⇐ module:middleware-stack ⏏
-**Kind**: Exported class
-**Extends:** module:middleware-stack
-
-
-#### new LocalWebServer([options])
-**Params**
-
-- [options] object - Server options
- - .port} number - Port
- - .stack} Array.<string> | Array.<Features> - Port
-
-
-
-#### localWebServer.features : Array.<Feature>
-Loaded feature modules
-
-**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
-
-#### localWebServer.options : object
-Config
-
-**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
-
-#### localWebServer.view : View
-Current view.
-
-**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
-
-#### localWebServer.server : Server
-Node.js server
-
-**Kind**: instance property of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
-
-#### localWebServer.getApplication() ⇒ function
-Returns a middleware application suitable for passing to `http.createServer`. The application is a function with three args (req, res and next) which can be created by express, Koa or hand-rolled.
-
-**Kind**: instance method of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
-
-#### localWebServer.getServer() ⇒ Server
-Returns a listening server which processes requests using the middleware supplied.
-
-**Kind**: instance method of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
-
-
-#### LocalWebServer~loadStack() ⇒ object
-Loads a module by either path or name.
-
-**Kind**: inner method of [LocalWebServer](#exp_module_local-web-server--LocalWebServer)
diff --git a/doc/blacklist.md b/doc/blacklist.md
deleted file mode 100644
index 23a4d52..0000000
--- a/doc/blacklist.md
+++ /dev/null
@@ -1,9 +0,0 @@
-## Access Control
-
-By default, access to all files is allowed (including dot files). Use `--forbid` to establish a blacklist:
-```sh
-$ ws --forbid '*.json' '*.yml'
-serving at http://localhost:8000
-```
-
-[Example](https://github.com/lwsjs/local-web-server/tree/master/example/forbid).
diff --git a/doc/distribute.md b/doc/distribute.md
deleted file mode 100644
index 08ca8d3..0000000
--- a/doc/distribute.md
+++ /dev/null
@@ -1,32 +0,0 @@
-## Distribute with your project
-The standard convention with client-server applications is to add an `npm start` command to launch the server component.
-
-1\. Install the server as a dev dependency
-
-```sh
-$ npm install local-web-server --save-dev
-```
-
-2\. Add a `start` command to your `package.json`:
-
-```json
-{
- "name": "example",
- "version": "1.0.0",
- "local-web-server": {
- "port": 8100,
- "forbid": "*.json"
- },
- "scripts": {
- "start": "ws"
- }
-}
-```
-
-3\. Document how to build and launch your site
-
-```sh
-$ npm install
-$ npm start
-serving at http://localhost:8100
-```
diff --git a/doc/https.md b/doc/https.md
deleted file mode 100644
index 5867f0a..0000000
--- a/doc/https.md
+++ /dev/null
@@ -1,59 +0,0 @@
-## HTTPS Server
-
-Some modern techs (ServiceWorker, any `MediaDevices.getUserMedia()` request etc.) *must* be served from a secure origin (HTTPS). To launch an HTTPS server, supply a `--key` and `--cert` to local-web-server, for example:
-
-```
-$ ws --key localhost.key --cert localhost.crt
-```
-
-If you don't have a key and certificate it's trivial to create them. You do not need third-party verification (Verisign etc.) for development purposes. To get the green padlock in the browser, the certificate..
-
-* must have a `Common Name` value matching the FQDN of the server
-* must be verified by a Certificate Authority (but we can overrule this - see below)
-
-First create a certificate:
-
-1. Install openssl.
-
- `$ brew install openssl`
-
-2. Generate a RSA private key.
-
- `$ openssl genrsa -des3 -passout pass:x -out ws.pass.key 2048`
-
-3. Create RSA key.
-
- ```
- $ openssl rsa -passin pass:x -in ws.pass.key -out ws.key
- ```
-
-4. Create certificate request. The command below will ask a series of questions about the certificate owner. The most imporant answer to give is for `Common Name`, you can accept the default values for the others. **Important**: you **must** input your server's correct FQDN (`dev-server.local`, `laptop.home` etc.) into the `Common Name` field. The cert is only valid for the domain specified here. You can find out your computers host name by running the command `hostname`. For example, mine is `mba3.home`.
-
- `$ openssl req -new -key ws.key -out ws.csr`
-
-5. Generate self-signed certificate.
-
- `$ openssl x509 -req -days 365 -in ws.csr -signkey ws.key -out ws.crt`
-
-6. Clean up files we're finished with
-
- `$ rm ws.pass.key ws.csr`
-
-7. Launch HTTPS server. In iTerm, control-click the first URL (with the hostname matching `Common Name`) to launch your browser.
-
- ```
- $ ws --key ws.key --cert ws.crt
- serving at https://mba3.home:8010, https://127.0.0.1:8010, https://192.168.1.203:8010
- ```
-
-Chrome and Firefox will still complain your certificate has not been verified by a Certificate Authority. Firefox will offer you an `Add an exception` option, allowing you to ignore the warning and manually mark the certificate as trusted. In Chrome on Mac, you can manually trust the certificate another way:
-
-1. Open Keychain
-2. Click File -> Import. Select the `.crt` file you created.
-3. In the `Certificates` category, double-click the cert you imported.
-4. In the `trust` section, underneath `when using this certificate`, select `Always Trust`.
-
-Now you have a valid, trusted certificate for development.
-
-### Built-in certificate
-As a quick win, you can run `ws` with the `https` flag. This will launch an HTTPS server using a [built-in certificate](https://github.com/lwsjs/local-web-server/tree/master/ssl) registered to the domain 127.0.0.1.
diff --git a/doc/img/logstagia.gif b/doc/img/logstagia.gif
deleted file mode 100644
index 22415e0..0000000
Binary files a/doc/img/logstagia.gif and /dev/null differ
diff --git a/doc/logging.md b/doc/logging.md
deleted file mode 100644
index 3883d7b..0000000
--- a/doc/logging.md
+++ /dev/null
@@ -1,69 +0,0 @@
-# Logging
-By default, local-web-server outputs a simple, dynamic statistics view. To see traditional web server logs, use `--log.format`:
-
-```sh
-$ ws --log.format combined
-serving at http://localhost:8000
-::1 - - [16/Nov/2015:11:16:52 +0000] "GET / HTTP/1.1" 200 12290 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2562.0 Safari/537.36"
-```
-
-The format value supplied is passed directly to [morgan](https://github.com/expressjs/morgan). The exception is `--log.format none` which disables all output.
-
-# Visualisation
-
-## Goaccess
-To get live statistics in [goaccess](http://goaccess.io/), first create this config file at `~/.goaccessrc`:
-
-```
-time-format %T
-date-format %d/%b/%Y
-log.format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"
-```
-
-Then, start the server, outputting `combined` format logs to disk:
-
-```sh
-$ ws -f combined > web.log
-```
-
-In a separate tab, point goaccess at `web.log` and it will display statistics in real time:
-
-```
-$ goaccess -p ~/.goaccessrc -f web.log
-```
-
-## Logstalgia
-local-web-server is compatible with [logstalgia](http://code.google.com/p/logstalgia/).
-
-### Install Logstalgia
-On MacOSX, install with [homebrew](http://brew.sh):
-```sh
-$ brew install logstalgia
-```
-
-Alternatively, [download a release for your system from github](https://github.com/acaudwell/Logstalgia/releases/latest).
-
-Then pipe the `logstalgia` output format directly into logstalgia for real-time visualisation:
-```sh
-$ ws -f logstalgia | logstalgia -
-```
-
-![local-web-server with logstalgia](https://raw.githubusercontent.com/lwsjs/local-web-server/master/doc/img/logstagia.gif)
-
-## glTail
-To use with [glTail](http://www.fudgie.org), write your log to disk using the "default" format:
-```sh
-$ ws -f default > web.log
-```
-
-Then specify this file in your glTail config:
-
-```yaml
-servers:
- dev:
- host: localhost
- source: local
- files: /Users/Lloyd/Documents/MySite/web.log
- parser: apache
- color: 0.2, 0.2, 1.0, 1.0
-```
diff --git a/doc/mime-types.md b/doc/mime-types.md
deleted file mode 100644
index 03d78fe..0000000
--- a/doc/mime-types.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## mime-types
-You can set additional mime-type/extension mappings, or override the defaults by setting a `mime` value in the stored config. This value is passed directly to [mime.define()](https://github.com/broofa/node-mime#mimedefine). Example:
-
-```json
-{
- "mime": {
- "text/plain": [ "php", "pl" ]
- }
-}
-```
-
-[Example](https://github.com/lwsjs/local-web-server/tree/master/example/mime-override).
diff --git a/doc/mock-response.md b/doc/mock-response.md
deleted file mode 100644
index a6fdc4d..0000000
--- a/doc/mock-response.md
+++ /dev/null
@@ -1,241 +0,0 @@
-## Mock Responses
-
-Mocks give you full control over the response headers and body returned to the client. They can be used to return anything from a simple html string to a resourceful REST API. Typically, they're used to mock services but can be used for anything.
-
-In the config, define an array called `mocks`. Each mock definition maps a [route](http://expressjs.com/guide/routing.html#route-paths) to a `response`. A simple home page:
-```json
-{
- "mocks": [
- {
- "route": "/",
- "response": {
- "body": "
Welcome to the Mock Responses example
"
- }
- }
- ]
-}
-```
-
-Under the hood, the property values from the `response` object are written onto the underlying [koa response object](https://github.com/koajs/koa/blob/master/docs/api/response.md). You can set any valid koa response properies, for example [type](https://github.com/koajs/koa/blob/master/docs/api/response.md#responsetype-1):
-```json
-{
- "mocks": [
- {
- "route": "/",
- "response": {
- "type": "text/plain",
- "body": "
Welcome to the Mock Responses example
"
- }
- }
- ]
-}
-```
-
-### Conditional Response
-
-To define a conditional response, set a `request` object on the mock definition. The `request` value acts as a query - the response defined will only be returned if each property of the `request` query matches. For example, return an XML response *only* if the request headers include `accept: application/xml`, else return 404 Not Found.
-
-```json
-{
- "mocks": [
- {
- "route": "/two",
- "request": { "accepts": "xml" },
- "response": {
- "body": ""
- }
- }
- ]
-}
-```
-
-### Multiple Potential Responses
-
-To specify multiple potential responses, set an array of mock definitions to the `responses` property. The first response with a matching request query will be sent. In this example, the client will get one of two responses depending on the request method:
-
-```json
-{
- "mocks": [
- {
- "route": "/three",
- "responses": [
- {
- "request": { "method": "GET" },
- "response": {
- "body": "
Mock response for 'GET' request on /three
"
- }
- },
- {
- "request": { "method": "POST" },
- "response": {
- "status": 400,
- "body": { "message": "That method is not allowed." }
- }
- }
- ]
- }
- ]
-}
-```
-
-### Dynamic Response
-
-The examples above all returned static data. To define a dynamic response, create a mock module. Specify its path in the `module` property:
-```json
-{
- "mocks": [
- {
- "route": "/four",
- "module": "/mocks/stream-self.js"
- }
- ]
-}
-```
-
-Here's what the `stream-self` module looks like. The module should export a mock definition (an object, or array of objects, each with a `response` and optional `request`). In this example, the module simply streams itself to the response but you could set `body` to *any* [valid value](https://github.com/koajs/koa/blob/master/docs/api/response.md#responsebody-1).
-```js
-const fs = require('fs')
-
-module.exports = {
- response: {
- body: fs.createReadStream(__filename)
- }
-}
-```
-
-### Response function
-
-For more power, define the response as a function. It will receive the [koa context](https://github.com/koajs/koa/blob/master/docs/api/context.md) as its first argument. Now you have full programmatic control over the response returned.
-```js
-module.exports = {
- response: function (ctx) {
- ctx.body = '
I can do anything i want.
'
- }
-}
-```
-
-If the route contains tokens, their values are passed to the response. For example, with this mock...
-```json
-{
- "mocks": [
- {
- "route": "/players/:id",
- "module": "/mocks/players.js"
- }
- ]
-}
-```
-
-...the `id` value is passed to the `response` function. For example, a path of `/players/10?name=Lionel` would pass `10` to the response function. Additional, the value `Lionel` would be available on `ctx.query.name`:
-```js
-module.exports = {
- response: function (ctx, id) {
- ctx.body = `
id: ${id}, name: ${ctx.query.name}
`
- }
-}
-```
-
-### RESTful Resource example
-
-Here's an example of a REST collection (users). We'll create two routes, one for actions on the resource collection, one for individual resource actions.
-
-```json
-{
- "mocks": [
- { "route": "/users", "module": "/mocks/users.js" },
- { "route": "/users/:id", "module": "/mocks/user.js" }
- ]
-}
-```
-
-Define a module (`users.json`) defining seed data:
-
-```json
-[
- { "id": 1, "name": "Lloyd", "age": 40, "nationality": "English" },
- { "id": 2, "name": "Mona", "age": 34, "nationality": "Palestinian" },
- { "id": 3, "name": "Francesco", "age": 24, "nationality": "Italian" }
-]
-```
-
-The collection module:
-
-```js
-const users = require('./users.json')
-
-/* responses for /users */
-const mockResponses = [
- /* Respond with 400 Bad Request for PUT and DELETE - inappropriate on a collection */
- { request: { method: 'PUT' }, response: { status: 400 } },
- { request: { method: 'DELETE' }, response: { status: 400 } },
- {
- /* for GET requests return a subset of data, optionally filtered on 'minAge' and 'nationality' */
- request: { method: 'GET' },
- response: function (ctx) {
- ctx.body = users.filter(user => {
- const meetsMinAge = (user.age || 1000) >= (Number(ctx.query.minAge) || 0)
- const requiredNationality = user.nationality === (ctx.query.nationality || user.nationality)
- return meetsMinAge && requiredNationality
- })
- }
- },
- {
- /* for POST requests, create a new user and return the path to the new resource */
- request: { method: 'POST' },
- response: function (ctx) {
- const newUser = ctx.request.body
- users.push(newUser)
- newUser.id = users.length
- ctx.status = 201
- ctx.response.set('Location', `/users/${newUser.id}`)
- }
- }
-]
-
-module.exports = mockResponses
-```
-
-The individual resource module:
-
-```js
-const users = require('./users.json')
-
-/* responses for /users/:id */
-const mockResponses = [
- /* don't support POST here */
- { request: { method: 'POST' }, response: { status: 400 } },
-
- /* for GET requests, return a particular user */
- {
- request: { method: 'GET' },
- response: function (ctx, id) {
- ctx.body = users.find(user => user.id === Number(id))
- }
- },
-
- /* for PUT requests, update the record */
- {
- request: { method: 'PUT' },
- response: function (ctx, id) {
- const updatedUser = ctx.request.body
- const existingUserIndex = users.findIndex(user => user.id === Number(id))
- users.splice(existingUserIndex, 1, updatedUser)
- ctx.status = 200
- }
- },
-
- /* DELETE request: remove the record */
- {
- request: { method: 'DELETE' },
- response: function (ctx, id) {
- const existingUserIndex = users.findIndex(user => user.id === Number(id))
- users.splice(existingUserIndex, 1)
- ctx.status = 200
- }
- }
-]
-
-module.exports = mockResponses
-```
-
-[Example](https://github.com/lwsjs/local-web-server/tree/master/example/mock).
\ No newline at end of file
diff --git a/doc/rewrite.md b/doc/rewrite.md
deleted file mode 100644
index 1120a92..0000000
--- a/doc/rewrite.md
+++ /dev/null
@@ -1,37 +0,0 @@
-## URL rewriting
-
-Your application requested `/css/style.css` but it's stored at `/build/css/style.css`. To avoid a 404 you need a rewrite rule:
-
-```sh
-$ ws --rewrite '/css/style.css -> /build/css/style.css'
-```
-
-Or, more generally (matching any stylesheet under `/css`):
-
-```sh
-$ ws --rewrite '/css/:stylesheet -> /build/css/:stylesheet'
-```
-
-With a deep CSS directory structure it may be easier to mount the entire contents of `/build/css` to the `/css` path:
-
-```sh
-$ ws --rewrite '/css/* -> /build/css/$1'
-```
-
-this rewrites `/css/a` as `/build/css/a`, `/css/a/b/c` as `/build/css/a/b/c` etc.
-
-### Proxied requests
-
-If the `to` URL contains a remote host, local-web-server will act as a proxy - fetching and responding with the remote resource.
-
-Mount the npm registry locally:
-```sh
-$ ws --rewrite '/npm/* -> http://registry.npmjs.org/$1'
-```
-
-Map local requests for repo data to the Github API:
-```sh
-$ ws --rewrite '/:user/repos/:name -> https://api.github.com/repos/:user/:name'
-```
-
-[Example](https://github.com/lwsjs/local-web-server/tree/master/example/rewrite).
diff --git a/doc/spa.md b/doc/spa.md
deleted file mode 100644
index 1a05b6e..0000000
--- a/doc/spa.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## Single Page Application
-
-You're building a web app with client-side routing, so mark `index.html` as the SPA.
-```sh
-$ ws --spa index.html
-```
-
-By default, typical SPA paths (e.g. `/user/1`, `/login`) would return `404 Not Found` as a file does not exist with that path. By marking `index.html` as the SPA you create this rule:
-
-*If a static file at the requested path exists (e.g. `/css/style.css`) then serve it, if it does not (e.g. `/login`) then serve the specified SPA and handle the route client-side.*
-
-[Example](https://github.com/lwsjs/local-web-server/tree/master/example/spa).
diff --git a/doc/stored-config.md b/doc/stored-config.md
deleted file mode 100644
index 3a63ec3..0000000
--- a/doc/stored-config.md
+++ /dev/null
@@ -1,28 +0,0 @@
-## Stored config
-
-Use the same options every time? Persist then to `package.json`:
-```json
-{
- "name": "example",
- "version": "1.0.0",
- "local-web-server": {
- "port": 8100,
- "forbid": "*.json"
- }
-}
-```
-
-or `.local-web-server.json`
-```json
-{
- "port": 8100,
- "forbid": "*.json"
-}
-```
-
-local-web-server will merge and use all config found, searching from the current directory upward. In the case both `package.json` and `.local-web-server.json` config is found in the same directory, `.local-web-server.json` will take precedence. Options set on the command line take precedence over all.
-
-To inspect stored config, run:
-```sh
-$ ws --config
-```
\ No newline at end of file
diff --git a/doc/visualisation.md b/doc/visualisation.md
deleted file mode 100644
index 2ca61d9..0000000
--- a/doc/visualisation.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## Goaccess
-To get live statistics in [goaccess](http://goaccess.io/), first create this config file at `~/.goaccessrc`:
-
-```
-time-format %T
-date-format %d/%b/%Y
-log.format %h %^[%d:%t %^] "%r" %s %b "%R" "%u"
-```
-
-Then, start the server, outputting `combined` format logs to disk:
-
-```sh
-$ ws -f combined > web.log
-```
-
-In a separate terminal, point goaccess at `web.log` and it will display statistics in real time:
-
-```
-$ goaccess -p ~/.goaccessrc -f web.log
-```
-
-## Logstalgia
-local-web-server is compatible with [logstalgia](http://code.google.com/p/logstalgia/).
-
-### Install Logstalgia
-On MacOSX, install with [homebrew](http://brew.sh):
-```sh
-$ brew install logstalgia
-```
-
-Alternatively, [download a release for your system from github](https://github.com/acaudwell/Logstalgia/releases/latest).
-
-Then pipe the `logstalgia` output format directly into logstalgia for real-time visualisation:
-```sh
-$ ws -f logstalgia | logstalgia -
-```
-
-![local-web-server with logstalgia](https://raw.githubusercontent.com/lwsjs/local-web-server/master/doc/img/logstagia.gif)
-
-## glTail
-To use with [glTail](http://www.fudgie.org), write your log to disk using the "default" format:
-```sh
-$ ws -f default > web.log
-```
-
-Then specify this file in your glTail config:
-
-```yaml
-servers:
- dev:
- host: localhost
- source: local
- files: /Users/Lloyd/Documents/MySite/web.log
- parser: apache
- color: 0.2, 0.2, 1.0, 1.0
-```
diff --git a/example/built-in/forbid/.local-web-server.json b/example/built-in/forbid/.local-web-server.json
deleted file mode 100644
index dd8124a..0000000
--- a/example/built-in/forbid/.local-web-server.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "forbid": [
- "/admin/*", "*.php"
- ]
-}
diff --git a/example/built-in/forbid/admin/blocked.html b/example/built-in/forbid/admin/blocked.html
deleted file mode 100644
index f51dbee..0000000
--- a/example/built-in/forbid/admin/blocked.html
+++ /dev/null
@@ -1 +0,0 @@
-