diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,177 @@
 [![Hackage](https://img.shields.io/hackage/v/glazier-react.svg)](https://hackage.haskell.org/package/glazier-react)
+[`Glazier.React`](https://github.com/louispan/glazier-react) contains efficient haskell bindings to React JS where render will only be called for the react components with changed states.
 
-See https://github.com/louispan/glazier-react-examples for a example apps, include a fully-featured TodoMVC.
+It uses the haskell [glazier](https://github.com/louispan/glazier) library to enable composable windows
 
-See https://github.com/louispan/glazier-react-widget for reusable widget library.
+# Features
+
+## Efficient rendering
+Using `React.PureComponent` and react `render` will only be called for component who's state actually changed, instead of requiring react to diff the entire DOM.
+
+## Composable widgets
+[`Glazier`](https://github.com/louispan/glazier) allows disciplined and lawful ways of creating composable widgets. Larger  can be created out of other widgets without modifying existing widget code, or manual ["lifting state"](https://facebook.github.io/react/docs/lifting-state-up.html) into larger widgets.
+
+For example, [List Widget](https://github.com/louispan/glazier-react-widget/blob/master/src/Glazier/React/Widgets/List.hs) creates a list of any other widget.
+
+## Isolation of IO
+The  stateful effects are pure and do not involve IO. This has the benefit of allowing better testing of the intention of gadgets; increasing confidence of the behaviour of the gadget,  reducing the surface area of IO misbehaviour.
+
+There are only two places where IO is allowed:
+1. in the gadget `Command` interpreter,
+2. in the event callback handlers, due to the need to read properties from `javascript` and dispatching `Actions`. Besides dispatching `Actions`, it is bad practice to create any other observable side effects in event handlers.
+
+## Combine multiple concurrent stateful effects
+AFAIK, Haskell is the only language where you can [combine multiple concurrent stateful effects consistently.](https://github.com/louispan/glazier#combine-multiple-concurrent-stateful-effects)
+
+## Compile using GHC as well as GHCJS
+`Glazier.React` uses [ghcjs-base-stub](https://github.com/louispan/ghcjs-base-stub) allows compiling GHCJS projects using GHC, which means you can develop using intero.
+
+## Easier management of GHCJS callbacks
+`Glazier.React` uses [disposable](https://github.com/louispan/disposable) to ease cleanup of GHCJS callbacks. It also uses a Free Monad [`Maker`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Maker.hs) DSL to ease creation of callbacks for widgets.
+
+## blaze/lucid style do notation
+React elements can be coded using blaze/lucid-style `do` notation using [`ReactMlT`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Markup.hs)
+
+## Haskell-driven rendering
+All state and processing is in Haskell, meaning only a simple shim `React.Component` is required. This  reduces the amount of `javascript` required and reduces the need for complex stateful integration with `React`.
+
+# Examples
+
+## TodoMVC
+This is a fully featured TodoMVC in in Haskell and ReactJS using the [glazier-react](https://github.com/louispan/glazier-react) library.
+
+For a live demo, see https://louispan.github.io/glazier-react-examples/
+
+For more details, see the [todo example README.md](https://github.com/louispan/glazier-react-examples/tree/master/examples/todo)
+
+# Documentation
+
+## React
+* Please refer to [react docs](https://facebook.github.io/react/docs). You only need to read up to [handling events](https://facebook.github.io/react/docs/handling-events.html).
+* Also read [Lists and Keys](https://facebook.github.io/react/docs/lists-and-keys.html), and [Refs and the DOM](https://facebook.github.io/react/docs/refs-and-the-dom.html).
+* Ignore controlled input in [Forms](https://facebook.github.io/react/docs/forms.html). In my experience, controlled input is error-prone and it is better to use it uncontrolled.
+    * Using uncontrolled input doesn't stop you from subscribing to onChange and obtaining the latest value of the input. Just do not force a render with react[`setState`](https://facebook.github.io/react/docs/react-component.html#setstate).
+
+## Glazier
+Please read the [README.md](https://github.com/louispan/glazier) for a brief overview of glazier.
+
+## Markup
+[`Glazier.React.Markup`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Markup.hs) is a StateT monad that enables blaze/lucid style `do` notation to markup React elements to render.
+
+```
+bh (strJS "footer") [("className", strJS "footer")] $ do
+    bh (strJS "span") [ ("className", strJS "todo-count")
+                      , ("key", strJS "todo-count")] $ do
+            bh (strJS "strong") [("key", strJS "items")]
+                (s ^. activeCount . to (txt . pack . show))
+            txt " items left"
+```
+
+## Event handling
+React re-uses SyntheticEvent from a pool, which means it may no longer be valid if we lazily parse it. However, we still want lazy parsing so we don't parse unnecessary fields.
+
+Additionally, we don't want to block during the event handling.The reason this is a problem is because Javascript is single threaded, but Haskell is lazy.
+Therefore GHCJS threads are a strange mixture of synchronous and asynchronous threads, where a synchronous thread might be converted to an asynchronous thread if a "black hole" is encountered.
+See https://github.com/ghcjs/ghcjs-base/blob/master/GHCJS/Concurrent.hs
+
+[`Glazier.React.Event`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Event.hs) uses the event handling idea from the haskell [`react-flux`](https://hackage.haskell.org/package/react-flux/docs/React-Flux-PropertiesAndEvents.html) library to allow lazy parsing of event safely.
+
+Event handling should only be done via [`eventHandler` or `eventHandlerM`](https://github.com/louispan/glazier-react/blob/33f4e244cff1a3e98ee1845f9ae2392818b9e512/src/Glazier/React/Event.hs#L90).
+
+```
+eventHandlerM :: (Monad m, NFData a) => (evt -> m a) -> (a -> m b) -> (evt -> m b)
+```
+
+This safe interface requires two input functions:
+1. a function to reduce SyntheticEvent to a NFData. The mkEventCallback will ensure that the NFData is forced which will ensure all the required fields from Synthetic event has been parsed. This function must not block.
+2. a second function that uses the NFData. This function is allowed to block.
+
+ mkEventHandler results in a function that you can safely pass into 'GHC.Foreign.Callback.syncCallback1' with 'GHCJS.Foreign.Callback.ContinueAsync'.
+
+## Simple and efficient React.Component integration
+`Glazier.React` only uses `ReactJS` as a thin layer for rendering and registering event handlers.  All state and event processing are performed in Haskell, which means only a simple shim `React.PureComponent` is required.
+
+Only [one shim React component](https://github.com/louispan/glazier-react/blob/master/jsbits/react.js) is ever used and the only methods are required are  [`setState`](https://facebook.github.io/react/docs/react-component.html#setstate),  [`render`](https://facebook.github.io/react/docs/react-component.html#render) and [`componentDidUpdate`](https://facebook.github.io/react/docs/react-component.html#componentdidupdate),
+
+The shim component only has one thing in it's state, a sequence number. This sequence number is only changed with [`setState`](https://facebook.github.io/react/docs/react-component.html#setstate) when the `Glazier.Gadget` determined that there is a need for re-rendering. This is easy and efficient to determine since `Gadget` is the `StateT` responsible for changing the state in the first place.
+
+This has the benefits of:
+* Only the react shim components with changed haskell state will be re-rendered.
+* React is able to efficiently determine if state has changed (just a single integer comparison)
+* The shim React component is very simple.
+
+## Modelling
+[`Glazier.React.Model`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Model.hs) contain many nuanced concepts of Model.
+
+### Model
+The `Model` is the pure data used for rendering and stateful logic (the nouns).
+It may contain `SuperModel` (see below) of other widgets.
+
+### Plan
+The `Plan` contains the callbacks for integrating with React (the verbs). It also contains a javascript reference to the instance of shim component used for the widget. This reference is used to trigger rendering with  [`setState`](https://facebook.github.io/react/docs/react-component.html#setstate).
+
+### Design
+`Design` is basically a tuple of `Model` and `Plan`. It is a separate data type in order to generate convenient lenses to the fields.
+`Design` is all that a `Window` needs to purely generate rendering instructions.
+
+### Frame
+`Frame` is a type synonym of `MVar Design`. It is a mutable holder of a copy of `Design`. This is so how the official state from Haskell is communicated to the React [`render`](https://facebook.github.io/react/docs/react-component.html#render) callback. The [`render`](https://facebook.github.io/react/docs/react-component.html#render) callback will read the latest copy of `Design` from the `MVar` and pass it to the widget `Window` for rendering.
+
+### SuperModel
+`SuperModel` is basically a tuple of `Design` and `Frame`. It is a separate data type in order to generate convenient lenses to the fields.
+This contains everything a widget needs for rendering and state processing.
+Most state processing is performed using the pure `Design`. The `Frame` is only used for the `RenderCommand`, to copy the latest `Design` into the `Frame` when re-rendering is required.
+
+## Maker
+`MVars` for `Frame`s and `Callback`s for `Plan`s may only be created in IO.  Using Free Monads, [`Glazier.React.Maker`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Maker.hs) provides a safe way to create them without allowing other arbitrary IO.
+
+The `Maker` can also be used create the initial `SuperModel` state for the widgets.
+The `Maker` DSL has an `action` type parameter which indicated the type of action that is dispatched by the widget.
+The `action` type can be mapped and hoisted to a larger `action` type, allow for embedding the smaller widget action in larger widget actions.
+
+For example, the [TodoMVC application](https://github.com/louispan/glazier-react-examples/blob/32b5b077faa499e7501cb8e5417105b340de9ad3/examples/todo/haskell/app/Main.hs#L44) uses `Maker` to create the initial application `SuperModel` which involves making and hoisting the `SuperModel` of the input, list of todos widget, and footer widget.
+
+## Disposable
+GHCJS `Callback`s has resources that are not automatically collected by the garbage collector. `Callback`s need to be released manually. The [disposable](https://github.com/louispan/disposable) library provides a safe and easy way to convert the `Callback` into a storable `SomeDisposable` that can be queued up to be released after the next rendering frame.
+
+[disposable](https://github.com/louispan/disposable) allows generic instances of `Disposing` to be easily created, which make it easy to create instances of `Disposing`
+for a `Plan` of `Callback`s,  and therefore the parent container`Design`, `SuperModel`, and `Model` (which may contain other widget `SuperModel`s)
+
+The [`List` widget](https://github.com/louispan/glazier-react-widget/blob/54a771f492b864ff422e31949284ea4b23aa02c6/src/Glazier/React/Widgets/List.hs#L181) shows how the disposables can be queued for destruction after the next rendered frame.
+
+## Widget
+A [`Glazier.React.Widget`](https://github.com/louispan/glazier-react/blob/master/src/Glazier/React/Widget.hs) is the combination of:
+
+The `Maker` instruction on how to create the `Plan` of that widget:
+```
+mkPlan :: Frame Model Plan -> F (Maker Action) Plan
+```
+The rendering instructions for that widget:
+```
+window:: WindowT (Design Model Plan) (ReactMlT Identity) ()
+```
+The state changes from `Action` events:
+```
+gadget :: GadgetT Action (SuperModel Model Plan) Identity (DList Command)
+```
+This is everything you need in order to create, render and interact with a widget.
+
+`Glazier.React.IsWidget` is a typeclass that provides handy XXXOf type functions to get to the type of `Command`, `Action`, `Model`, `Plan` of the Widget. It also ensures that the `Model` and `Plan` is an instance of `Disposing`.
+
+```
+instance (CD.Disposing m, CD.Disposing p) =>
+         IsWidget (Widget c a m p) where
+    type CommandOf (Widget c a m p) = c
+    type ActionOf (Widget c a m p) = a
+    type ModelOf (Widget c a m p) = m
+    type PlanOf (Widget c a m p) = p
+    mkPlan (Widget f _ _) = f
+    window (Widget _ f _) = f
+    gadget (Widget _ _ f) = f
+```
+
+This is useful for creating widgets that is composed of other Widgets. For example:
+The [List widget](https://github.com/louispan/glazier-react-widget/blob/54a771f492b864ff422e31949284ea4b23aa02c6/src/Glazier/React/Widgets/List.hs#L122) uses the IsWidget typeclass in order to ensure that the `itemWidget` can be disposed.
+
+## Widget best practices
+Please refer to [`glazier-react-widget`](https://github.com/louispan/glazier-react-widget) for documentation on the best practices for creating `Glazier.React.Widgets`
diff --git a/glazier-react.cabal b/glazier-react.cabal
--- a/glazier-react.cabal
+++ b/glazier-react.cabal
@@ -1,5 +1,5 @@
 name:                glazier-react
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            ReactJS binding using Glazier and Pipes.Fluid
 description:         ReactJS binding using Glazier and Pipes.Fluid, which is
                      more functional and composable than Elm/Flux.
@@ -26,6 +26,7 @@
                        Glazier.React.Maker
                        Glazier.React.Maker.Run
                        Glazier.React.Markup
+                       Glazier.React.Model
                        Glazier.React.ReactDOM
                        Glazier.React.Widget
   build-depends:       base >= 4.7 && < 5
diff --git a/jsbits/registry.js b/jsbits/registry.js
--- a/jsbits/registry.js
+++ b/jsbits/registry.js
@@ -29,10 +29,10 @@
         if (!handlers[name])
             handlers[name] = { nextIndex: 0, listeners: {} };
 
-        var i = handlers[name].nextIndex;
+        const i = handlers[name].nextIndex;
         handlers[name].nextIndex += 1;
         handlers[name].listeners[i] = listener;
-        var unregister = function() {
+        const unregister = function() {
             handlers[name] = omit(handlers[name], i);
         };
         return unregister;
@@ -45,7 +45,7 @@
         if (handlers[name]) {
             // iterate using copy of keys to safeguard against listeners added/removed
             // during callbacks.
-            for (const key of Object.keys(handlers[name].listeners)) {
+            for (var key of Object.keys(handlers[name].listeners)) {
                 const listener = handlers[name].listeners[key];
                 if (listener) {
                     ret.push(listener(data));
diff --git a/src/Glazier/React/Command/Run.hs b/src/Glazier/React/Command/Run.hs
--- a/src/Glazier/React/Command/Run.hs
+++ b/src/Glazier/React/Command/Run.hs
@@ -10,15 +10,15 @@
 import Control.Lens
 import Control.Monad
 import qualified GHCJS.Types as J
-import qualified Glazier.React.Widget as R
+import qualified Glazier.React.Model as R
 import qualified JavaScript.Extras as JE
 import qualified JavaScript.Object as JO
 
 componentSetState :: R.HasSuperModel sm mdl pln => sm -> [JE.Property] -> J.JSVal -> IO ()
 componentSetState sm props j = do
     let dsn = sm ^. R.design
-        rep = sm ^. R.replica
-    void $ swapMVar rep dsn
+        frm = sm ^. R.frame
+    void $ swapMVar frm dsn
     js_componentSetState (JE.fromProperties props) j
 
 #ifdef __GHCJS__
diff --git a/src/Glazier/React/Event.hs b/src/Glazier/React/Event.hs
--- a/src/Glazier/React/Event.hs
+++ b/src/Glazier/React/Event.hs
@@ -71,6 +71,11 @@
 -- | Using the NFData idea from React/Flux/PropertiesAndEvents.hs
 -- React re-uses SyntheticEvent from a pool, which means it may no longer be valid if we lazily
 -- parse it. However, we still want lazy parsing so we don't parse unnecessary fields.
+-- Additionally, we don't want to block during the event handling.The reason this is a problem is
+-- because Javascript is single threaded, but Haskell is lazy.
+-- Therefore GHCJS threads are a strange mixture of synchronous and asynchronous threads,
+-- where a synchronous thread might be converted to an asynchronous thread if a "black hole" is encountered.
+-- See https://github.com/ghcjs/ghcjs-base/blob/master/GHCJS/Concurrent.hs
 -- This safe interface requires two input functions:
 -- 1. a function to reduce SyntheticEvent to a NFData. The mkEventCallback will ensure that the
 -- NFData is forced which will ensure all the required fields from Synthetic event has been parsed.
@@ -78,10 +83,6 @@
 -- 2. a second function that uses the NFData. This function is allowed to block.
 -- mkEventHandler results in a function that you can safely pass into 'GHC.Foreign.Callback.syncCallback1'
 -- with 'GHCJS.Foreign.Callback.ContinueAsync'.
--- The reason of this is because Javascript is single threaded, but Haskell is lazy.
--- Therefore GHCJS threads are a strange mixture of synchronous and asynchronous threads,
--- where a synchronous thread might be converted to an asynchronous thread if a "black hole" is encountered.
--- See https://github.com/ghcjs/ghcjs-base/blob/master/GHCJS/Concurrent.hs
 eventHandler :: NFData a => (evt -> a) -> (a -> b) -> (evt -> b)
 eventHandler goStrict goLazy evt = goLazy $!! goStrict evt
 
diff --git a/src/Glazier/React/Maker.hs b/src/Glazier/React/Maker.hs
--- a/src/Glazier/React/Maker.hs
+++ b/src/Glazier/React/Maker.hs
@@ -15,7 +15,7 @@
 import qualified Glazier as G
 import qualified Glazier.React.Component as R
 import qualified Glazier.React.Markup as R
-import qualified Glazier.React.Widget as R
+import qualified Glazier.React.Model as R
 
 -- | DSL for IO effects required during making widget models and callbacks
 -- 'Maker' remembers the action type to allow 'mapAction' for changing the action type by parent widgets.
@@ -25,16 +25,16 @@
         :: (J.JSVal -> MaybeT IO [act])
         -> (J.Callback (J.JSVal -> IO ()) -> nxt)
         -> Maker act nxt
-    MkEmptyReplica
-        :: (R.Replica mdl pln -> nxt)
+    MkEmptyFrame
+        :: (R.Frame mdl pln -> nxt)
         -> Maker act nxt
     MkRenderer
-        :: R.Replica mdl pln
-        -> (J.JSVal -> G.WindowT (R.Design mdl pln) (R.ReactMl) ())
+        :: R.Frame mdl pln
+        -> (J.JSVal -> G.WindowT (R.Design mdl pln) R.ReactMl ())
         -> (J.Callback (J.JSVal -> IO J.JSVal) -> nxt)
         -> Maker act nxt
-    PutReplica
-        :: R.Replica mdl pln
+    PutFrame
+        :: R.Frame mdl pln
         -> R.Design mdl pln
         -> nxt
         -> Maker act nxt
@@ -44,9 +44,9 @@
 
 instance Functor (Maker act) where
   fmap f (MkHandler handler g) = MkHandler handler (f . g)
-  fmap f (MkEmptyReplica g) = MkEmptyReplica (f . g)
+  fmap f (MkEmptyFrame g) = MkEmptyFrame (f . g)
   fmap f (MkRenderer ms render g) = MkRenderer ms render (f . g)
-  fmap f (PutReplica rep dsn x) = PutReplica rep dsn (f x)
+  fmap f (PutFrame frm dsn x) = PutFrame frm dsn (f x)
   fmap f (GetComponent g) = GetComponent (f . g)
 
 makeFree ''Maker
@@ -54,19 +54,7 @@
 -- | Allows changing the action type of Maker
 mapAction :: (act -> act') -> Maker act a -> Maker act' a
 mapAction f (MkHandler handler g) = MkHandler (\v -> fmap f <$> handler v) g
-mapAction _ (MkEmptyReplica g) = MkEmptyReplica g
+mapAction _ (MkEmptyFrame g) = MkEmptyFrame g
 mapAction _ (MkRenderer ms render g) = MkRenderer ms render g
-mapAction _ (PutReplica ms s x) = PutReplica ms s x
+mapAction _ (PutFrame frm dsn x) = PutFrame frm dsn x
 mapAction _ (GetComponent g) = GetComponent g
-
-mkSuperModel
-    :: MonadFree (Maker act) m
-    => (R.Replica mdl pln -> m pln)
-    -> (pln -> R.Design mdl pln)
-    -> m (R.SuperModel mdl pln)
-mkSuperModel makePlan toDesign = do
-    rep <- mkEmptyReplica
-    pln <- makePlan rep
-    let dsn = toDesign pln
-    putReplica rep dsn
-    pure (R.SuperModel dsn rep)
diff --git a/src/Glazier/React/Maker/Run.hs b/src/Glazier/React/Maker/Run.hs
--- a/src/Glazier/React/Maker/Run.hs
+++ b/src/Glazier/React/Maker/Run.hs
@@ -35,12 +35,12 @@
 run :: R.ReactComponent -> PC.Output act -> R.Maker act (IO a) -> IO a
 run _ output (R.MkHandler handler g) = mkActionCallback output handler >>= g
 
-run _ _ (R.MkEmptyReplica g) = newEmptyMVar >>= g
+run _ _ (R.MkEmptyFrame g) = newEmptyMVar >>= g
 
 run _ _ (R.MkRenderer ms render g) = J.syncCallback1' (onRender ms render') >>= g
   where
     render' v = hoist (hoist generalize) (render v)
 
-run _ _ (R.PutReplica rep dsn g) = putMVar rep dsn >> g
+run _ _ (R.PutFrame frm dsn g) = putMVar frm dsn >> g
 
 run component _ (R.GetComponent g) = g component
diff --git a/src/Glazier/React/Model.hs b/src/Glazier/React/Model.hs
new file mode 100644
--- /dev/null
+++ b/src/Glazier/React/Model.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Glazier.React.Model where
+
+import Control.Concurrent.MVar
+import qualified Control.Disposable as CD
+import Control.Lens
+import qualified GHC.Generics as G
+
+-- | Lens to the callbacks and interactions with React
+class HasPlan c pln | c -> pln where
+    plan :: Lens' c pln
+
+-- | Lens to the pure model for state and rendering.
+class HasModel c mdl | c -> mdl where
+    model :: Lens' c mdl
+
+-- | A record of Model and Plan
+data Design mdl pln = Design
+    { _model :: mdl
+    , _plan :: pln
+    } deriving (G.Generic)
+
+-- | All designs should be disposable to make it easier for cleanup of callbacks.
+instance (CD.Disposing pln, CD.Disposing mdl) => CD.Disposing (Design mdl pln)
+
+instance HasPlan (Design mdl pln) pln where
+    plan f (Design mdl pln) = fmap (\pln' -> Design mdl pln') (f pln)
+    {-# INLINE plan #-}
+
+instance HasModel (Design mdl pln) mdl where
+    model f (Design mdl pln) = fmap (\mdl' -> Design mdl' pln) (f mdl)
+    {-# INLINE model #-}
+
+class HasDesign c mdl pln | c -> mdl pln where
+    design :: Lens' c (Design mdl pln)
+
+instance HasDesign (Design mdl pln) mdl pln where
+    design = id
+
+-- | Frame is a Mvar of Design. React rendering callback uses this MVar for rendering.
+type Frame mdl pln = MVar (Design mdl pln)
+
+class HasFrame c mdl pln | c -> mdl pln where
+    frame :: Lens' c (Frame mdl pln)
+
+instance HasFrame (Frame mdl pln) mdl pln where
+    frame = id
+
+-- | A record of Design and Frame.
+data SuperModel mdl pln = SuperModel
+    { _design :: Design mdl pln
+    , _frame :: Frame mdl pln
+    } deriving (G.Generic)
+
+-- Undecidableinstances!
+instance CD.Disposing (Design mdl pln) => CD.Disposing (SuperModel mdl pln) where
+    disposing s = CD.disposing $ s ^. design
+
+class (HasDesign c mdl pln, HasFrame c mdl pln) => HasSuperModel c mdl pln | c -> mdl pln where
+    superModel :: Lens' c (SuperModel mdl pln)
+
+instance HasSuperModel (SuperModel mdl pln) mdl pln where
+    superModel = id
+
+instance HasFrame (SuperModel mdl pln) mdl pln where
+    frame f (SuperModel dsn frm) = fmap (\frm' -> SuperModel dsn frm') (f frm)
+    {-# INLINE frame #-}
+
+instance HasDesign (SuperModel mdl pln) mdl pln where
+    design f (SuperModel dsn frm) = fmap (\dsn' -> SuperModel dsn' frm) (f dsn)
+    {-# INLINE design #-}
+
+instance HasPlan (SuperModel mdl pln) pln where
+    plan = design . plan
+
+instance HasModel (SuperModel mdl pln) mdl where
+    model = design . model
diff --git a/src/Glazier/React/Widget.hs b/src/Glazier/React/Widget.hs
--- a/src/Glazier/React/Widget.hs
+++ b/src/Glazier/React/Widget.hs
@@ -1,6 +1,5 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -8,81 +7,55 @@
 
 module Glazier.React.Widget where
 
-import Control.Concurrent.MVar
 import qualified Control.Disposable as CD
 import Control.Lens
-import qualified GHC.Generics as G
-
-class HasWidgetPlan c pln | c -> pln where
-    widgetPlan :: Lens' c pln
-
-class HasWidgetModel c mdl | c -> mdl where
-    widgetModel :: Lens' c mdl
-
-data Design mdl pln = Design
-    { _widgetModel :: mdl
-    , _widgetPlan :: pln
-    } deriving (G.Generic)
-
-instance (CD.Disposing pln, CD.Disposing mdl) => CD.Disposing (Design mdl pln)
-
-instance HasWidgetPlan (Design mdl pln) pln where
-    widgetPlan f (Design mdl pln) = fmap (\pln' -> Design mdl pln') (f pln)
-    {-# INLINE widgetPlan #-}
-
-instance HasWidgetModel (Design mdl pln) mdl where
-    widgetModel f (Design mdl pln) = fmap (\mdl' -> Design mdl' pln) (f mdl)
-    {-# INLINE widgetModel #-}
-
-class HasDesign c mdl pln | c -> mdl pln where
-    design :: Lens' c (Design mdl pln)
-
-instance HasDesign (Design mdl pln) mdl pln where
-    design = id
-
-type Replica mdl pln = MVar (Design mdl pln)
-
-class HasReplica c mdl pln | c -> mdl pln where
-    replica :: Lens' c (Replica mdl pln)
-
-instance HasReplica (Replica mdl pln) mdl pln where
-    replica = id
-
-data SuperModel mdl pln = SuperModel
-    { _design :: Design mdl pln
-    , _replica :: Replica mdl pln
-    } deriving (G.Generic)
-
-instance CD.Disposing (Design mdl pln) => CD.Disposing (SuperModel mdl pln) where
-    disposing s = CD.disposing $ s ^. design
-
-class (HasDesign c mdl pln, HasReplica c mdl pln) => HasSuperModel c mdl pln | c -> mdl pln where
-    superModel :: Lens' c (SuperModel mdl pln)
-
-instance HasSuperModel (SuperModel mdl pln) mdl pln where
-    superModel = id
+import Control.Monad.Free.Church
+import qualified Data.DList as D
+import qualified Glazier as G
+import qualified Glazier.React.Maker as R
+import qualified Glazier.React.Markup as R
+import qualified Glazier.React.Model as R
 
-instance HasReplica (SuperModel mdl pln) mdl pln where
-    replica f (SuperModel dsn rep) = fmap (\rep' -> SuperModel dsn rep') (f rep)
-    {-# INLINE replica #-}
+class (CD.Disposing (ModelOf w)
+      , CD.Disposing (PlanOf w)) => IsWidget w where
+    -- | The pure model for state and rendering
+    type CommandOf w :: *
+    type ActionOf w :: *
+    type ModelOf w :: *
+    type PlanOf w :: *
+    mkPlan :: w -> R.Frame (ModelOf w) (PlanOf w) -> F (R.Maker (ActionOf w)) (PlanOf w)
+    window :: w -> G.WindowT (R.Design (ModelOf w) (PlanOf w)) (R.ReactMlT Identity) ()
+    gadget :: w -> G.GadgetT (ActionOf w) (R.SuperModel (ModelOf w) (PlanOf w)) Identity (D.DList (CommandOf w))
 
-instance HasDesign (SuperModel mdl pln) mdl pln where
-    design f (SuperModel dsn rep) = fmap (\dsn' -> SuperModel dsn' rep) (f dsn)
-    {-# INLINE design #-}
+type family DesignOf w where
+    DesignOf w = R.Design (ModelOf w) (PlanOf w)
 
-class IsWidget w where
-    -- The input to Gadget
-    type WidgetAction w :: *
+type family FrameOf w where
+    FrameOf w = R.Frame (ModelOf w) (PlanOf w)
 
-    -- The output of Gadget
-    type WidgetCommand w :: *
+type family SuperModelOf w where
+    SuperModelOf w = R.SuperModel (ModelOf w) (PlanOf w)
 
-    -- The pure model for state and rendering
-    type WidgetModel w :: *
+-- | Contains everything you need to make the model,
+-- render, and run the event processing.
+data Widget c a m p = Widget
+    (R.Frame m p -> F (R.Maker a) p)
+    (G.WindowT (R.Design m p) (R.ReactMlT Identity) ())
+    (G.GadgetT a (R.SuperModel m p) Identity (D.DList c))
 
-    -- Callbacks and data required for interfacing with react.
-    type WidgetPlan w :: *
+instance (CD.Disposing m, CD.Disposing p) =>
+         IsWidget (Widget c a m p) where
+    type CommandOf (Widget c a m p) = c
+    type ActionOf (Widget c a m p) = a
+    type ModelOf (Widget c a m p) = m
+    type PlanOf (Widget c a m p) = p
+    mkPlan (Widget f _ _) = f
+    window (Widget _ f _) = f
+    gadget (Widget _ _ f) = f
 
-type WidgetDesign w = Design (WidgetModel w) (WidgetPlan w)
-type WidgetReplica w = Replica (WidgetModel w) (WidgetPlan w)
-type WidgetSuperModel w = SuperModel (WidgetModel w) (WidgetPlan w) 
+mkSuperModel :: IsWidget w => w -> ModelOf w -> F (R.Maker (ActionOf w)) (R.SuperModel (ModelOf w) (PlanOf w))
+mkSuperModel w mdl = do
+    frm <- R.mkEmptyFrame
+    dsn <- R.Design mdl <$> mkPlan w frm
+    R.putFrame frm dsn
+    pure (R.SuperModel dsn frm)
