diff --git a/README.md b/README.md
index a328eafa3dbe1a8001bd2b02e4e15892c6d61368..f7eff3be475f325dcd6fd0797054cdbc0f902fdf 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,70 @@
 # redux-reducer
 Even simpler reducers with 0 boilerplate
+
+## Installation
+
+One of the following:
+- `npm i -S @commander-lol/redux-reducer`
+- `yarn add @commander-lol/redux-reducer`
+- `ied i -S @commander-lol/redux-reducer`
+
+## Usage
+
+When you're writing reducers for Redux, you probably have something similar to the following:
+
+```js
+const initialState = {
+  dongles: {},
+}
+
+export default function myReducer(state = initialState, {type, ...action}) {
+  switch(type) {
+    case "ADD_DONGLE": {
+      let { dongles } = state
+      let { dongle } = action
+      dongles = {
+        ...dongles,
+        [dongle.id]: dongle,
+      }
+      
+      return {
+        ...state,
+        dongles,
+      }
+    }
+    default: 
+      return state
+  }
+}
+```
+
+And that's a pattern that will appear in pretty much every one of your reducers. Instead, using the `redux-reducer` library
+turns that into the following: 
+
+```js
+const reducer = require('@commander-lol/redux-reducer')
+
+const initialState = {
+  dongles: {},
+}
+
+export default reducer(initialState, {
+  ADD_DONGLE: ({ dongles, ...state }, { dongle }) => {
+    return {
+      ...state,
+      dongles: {
+        ...dongles,
+        [dongle.id] = dongle,
+      },
+    }
+  }
+})
+```
+
+## API
+
+The library exports a single function that returns a redux-compatible reducer function;
+
+``` reducer(initial: Object, handlers: Map<string, Handler>) ```
+
+Where initial is the `initial` router state and `handlers` is a string -> function map of action types to action reducers. Each handler is passed `state` and `action` as parameters, which correspond to the assigned reducer state and the current action (without the `type` property) and should return the new version of state after resolving the action. Simple as that.