diff --git a/README.md b/README.md
index b2538ce483561ca5ad82d64ceed2f5dd42a4309d..e370eb1d335b4a19199a2fecc59732513bce5ce1 100644
--- a/README.md
+++ b/README.md
@@ -117,7 +117,7 @@ export interface GameConfig {
 
 The next task I would suggest is just creating this object and rendering it to a little UI using your chosen framework. That'll let you fiddle around with the layout.
 
-Then, wire up the functionality. Note that you'll probably need to change `life`. At the moment, it's a constant in that file. You will probably want it to be a variable that can be set by calling a function.
+Then, wire up the functionality. Note that you'll probably need to change `life`. At the moment, it's a constant in the render file. You will probably want it to be a variable that can be set by calling a function.
 
 ## Solving this with Vue
 
@@ -270,7 +270,7 @@ template: `
         <input type="number" v-model:value="config.w" />
 
         Rows:
-        <input type="number" v-model:value="config.w" />
+        <input type="number" v-model:value="config.h" />
       </div>
     `,
 ```
@@ -301,7 +301,7 @@ Reload and check that logs to the browser console when you hit the button (and t
 
 We need to let our component actually configure our `Life` instance.
 
-First, in `life.ts`, let's turn `life` into a variable, and also add a create function that accepts a `GameConfig` and a function for getting the value of life.
+First, in `render.ts`, let's turn `life` into a variable, and also add a create function that accepts a `GameConfig` and a function for getting the value of life.
 
 ```ts
 import { GameConfig } from "./gameConfig"
@@ -388,3 +388,298 @@ Period:
 ```
 
 Notice this button is bound so it's disabled until we've created the game. It's onClick is bound to the `toggleTimer` method, and the text changes from Start to Stop depending on whether the timer is already started.
+
+
+## Solving this tutorial with React
+
+There's a worked solution to this tutorial using React.js on the `react-solution` branch. But let's talk you through it.
+
+### Some config changes
+
+First, there's some config changes we'll make to make things easier. By default, React won't give you nice error messages -- it left them out of the library to save space. So make the HTML load the development scripts from our node_modules directory:
+
+```html
+<script src="./node_modules/react/umd/react.development.js"></script>
+<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
+```
+
+And tell webpack not to put React itself into bundle.js (because we're loading its development scripts separately). In webpack.config.js, inside `module.exports`:
+
+```js
+externals: {
+  "react": "React",
+  "react-dom": "ReactDOM"
+}
+```
+
+We're also going to want to use TSX, so let's update compilerOptions in `tsconfig.json`:
+
+```js
+    "jsx": "react"
+```
+
+And let's also rename `index.ts` to `index.tsx`, and then update `webpack.congfig.js` to tell it about the new entry point:
+
+```js
+  entry: './src/index.tsx',
+```
+
+### Getting React on-screen
+
+Let's get React rendering something, even if just Hello World. 
+
+In index.html, create a div that Vue can render to. Let's put this above the svg for the game:
+
+```html
+<div id="app"></div>
+```
+
+And inside index.tsx, let's import React and ReactDOM, and something to that div
+
+```ts
+import * as React from "react";
+import * as ReactDOM from "react-dom";
+```
+
+and now for our first bit of TSX:
+
+```ts
+ReactDOM.render(
+    <div>Hello React</div>,
+    document.getElementById("app")
+);
+```
+
+Set webpack watching the files:
+
+```sh
+npm run build -- --watch
+```
+
+Reload index.html in the browser, and check we get "Hello Vue" appearing. If so, good -- React is working and we can progress.
+
+### Creating a ConfigView component
+
+Let's create a file called `gameConfig.tsx'. 
+
+First, let's import react:
+
+```tsx
+import * as React from "react"
+import * as ReactDOM from "react-dom"
+```
+
+Then let's define two types -- one for the config's definable properties, and another that has some additional state:
+
+```tsx
+export interface ConfigProps {
+    w:number
+    h:number
+}
+```
+
+```tsx
+export interface ConfigState extends ConfigProps {
+    created:boolean
+    period:number
+    intervalId?: number
+}
+```
+
+intervalId is optional -- hence the `?`
+
+And then let's define a React component:
+
+```tsx
+export class ConfigView extends React.Component<ConfigProps, ConfigState> {
+    render() {
+        return <div>This will render some game config</div>
+    }
+
+    constructor(props:ConfigProps) {
+        super(props)
+        this.state = {
+            ...props,
+            created: false,
+            period: 500
+        }
+    }
+
+}
+```
+
+Notice that in the angle brackets, we've said this component's properties are defined by the ConfigProps interface -- so, it has properties for `w` and`h`.
+And we've said its state is defined by the `ConfigState` interface.
+
+In the constructor, we've also taken the component's properties, and augmented them with the missing compulsory variables. `...props` is the "spread" operator that sets all the name-value pairs from
+`props` on the new object we're creating.
+
+Let's go back to `index.tsx` and use our component.
+
+First, we need to import `ConfigView`:
+
+```tsx
+import { ConfigView } from "./gameConfig"
+```
+
+and then let's alter our React call to use it:
+
+```tsx
+ReactDOM.render(
+    <ConfigView w={40} h={20}></ConfigView>,
+    document.querySelector("#app")
+);
+```
+
+Notice that we've been able to set the `w` and `h` properties as attributes on the component. This sets them in the `props` object.
+
+Reload and see if the message is in the UI.
+
+### Render some controls
+
+It's time to get our ConfigView to render some real controls. Let's alter `gameConfig.tsx`.
+
+```tsx
+    render() {
+        return <div>
+          Cols: <input type="number" value={this.state.w} onChange={(e) => this.setW(+e.target.value)} />
+          Rows: <input type="number" value={this.state.h} onChange={(e) => this.setH(+e.target.value)} />
+          <button onClick={(e) => this.create()}>Create</button>  
+        </div>
+    }
+```
+
+In this, we've bound the input fields to render the `w` and `h` fields from the current state.
+
+We've then needed to bind an `onChange` handler for each field. This takes a lambda function.
+The parameter `(e)` is the event that has happened. And we're getting `e.target.value` from it to get the number out
+of the input field. This comes out as a string, even though the input field is for numbers. So in order to convert it
+to a number, we use `+e.target.value`. This then needs to get passed to `this.setW` and `this.setH` -- methods on our class. So we'd better write those!
+
+Likewise, we've boud the button's click handler to `this.create()`.
+
+Let's write `setW` and `setH`, which are methods on the `ConfigView` class:
+
+```tsx
+    setW(w:number) {
+        this.setState((state:ConfigState) => {
+            state.w = w
+            return state
+        })
+    }
+
+    setH(h:number) {
+        this.setState((state:ConfigState) => {
+            state.h = h
+            return state
+        })
+    }
+```
+
+In both cases, we call `setState`, which is a method from the React API (remember, `ConfigView` inherits from `React.Component`). `setState` gives you the current state, and asks you to return the new state. It will then automatically trigger re-rendering the component.
+
+Now let's write `create` method, and just get it to log to the console:
+
+```tsx
+    create() {
+        console.log("I was clicked")
+    }
+```
+
+Reload the page, and check the code so far works
+
+### Making it create the Life game
+
+Let's alter `render.ts`.
+
+First, import the ConfigProps interface
+
+```ts
+import { ConfigProps } from "./gameConfig"
+```
+
+and now let's make `life` a variable instead of a constant. We'll initialise it to a zero-sized game so it won't be null but won't be visible on the screen. And we'll define a `create` method that takes ConfigProps.
+
+```ts
+let life = new Life(0, 0)
+```
+
+```ts
+function create(config:ConfigProps) {
+    life = new Life(config.w, config.h)
+}
+```
+
+We'd best make sure those are exported:
+
+```ts
+export {
+    life as life,
+    render as render,
+    create as create
+}
+```
+
+Now let's go back to `gameConfig.tsx` and make it set up the game by altering what happens when we click the button
+
+First, let's import the functions from render.ts
+
+```tsx
+import { life, create, render} from "./render"
+```
+
+Then let's alter the `create` method on `ConfigView`:
+
+```tsx
+    create() {
+        create(this.state) // note this calls the function imported from render.ts
+        render()  // note this calls the function imported from render.ts
+    }
+```
+
+Reload, and check it works
+
+
+### Setting up the timer
+
+The last part we'll do is setting up the timer. In `gameConfig.tsx`, let's alter the render() method for our component:
+
+```tsx
+    render() {
+        return <div>
+          Cols: <input type="number" value={this.state.w} onChange={(e) => this.setW(+e.target.value)} /> 
+          Rows: <input type="number" value={this.state.h} onChange={(e) => this.setH(+e.target.value)} />   
+          <button onClick={(e) => this.create()}>Create</button>  
+
+          Period: <input type="number" value={this.state.period} onChange={(e) => this.setPeriod(+e.target.value)} />
+          <button onClick={(e) => this.toggleTimer()}>{ this.state.intervalId ? "Stop" : "Start" }</button>  
+        </div>
+```
+
+We've added an input field, very similar to the ones for `w` and `h` but operating on `period`.
+
+We've also added a button that will call `toggleTimer`, which we need to define. Its text is set by a ternary expression on whether `intervalId` in the component's state is defined.
+
+`toggleTimer` can work as another call to `setState`. Only this time, the call is also going to either start or cancel a JavaScript timer. We need to use `window.setInterval` because in Node setInterval has a different return type than in the browser -- calling `window.setInterval` makes sure TypeScript uses the browser's version.
+
+```ts
+    toggleTimer() {
+        this.setState((state:ConfigState) => {
+
+            if (state.intervalId) {
+                clearInterval(state.intervalId)
+                state.intervalId = undefined
+                return state
+            } else {
+                state.intervalId = window.setInterval(() => {
+                    life.stepGame()
+                    render()
+                }, this.state.period)
+                return state
+            }
+
+        })
+    }
+```
+
+Reload, and see if it all works!
\ No newline at end of file