diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -16,9 +16,6 @@
   <a href="https://haskell.org">
     <img src="https://img.shields.io/badge/language-Haskell-green.svg?style=flat-square" alt="Haskell">
   </a>
-  <a href="https://img.shields.io/hackage-deps/v/miso.svg">
-    <img src="https://img.shields.io/hackage-deps/v/miso.svg?style=flat-square" alt="Hackage">
-  </a>
   <a href="https://github.com/dmjio/miso/blob/master/LICENSE">
     <img src="http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat-square" alt="LICENSE">
   </a>
@@ -61,6 +58,7 @@
   - [GHCJS](#ghcjs)
 - [Sample Application](#sample-application)
 - [Building examples](#building-examples)
+- [Isomorphic](#isomorphic)
 - [Pinning nixpkgs](#pinning-nixpkgs)
 - [Binary cache](#binary-cache)
 - [Benchmarks](#benchmarks)
@@ -74,7 +72,7 @@
 All source code depicted below for the quick start app is available [here](https://github.com/dmjio/miso/tree/master/sample-app).
 
 ### Begin
-We recommend using `nix` when working with `miso`, but it is just as fine to use `stack`. 
+We recommend using `nix` when working with `miso`, but it is just as fine to use `stack`.
 To build the sample-app with `nix`, execute the command below:
 
 ```bash
@@ -94,6 +92,16 @@
 git clone https://github.com/dmjio/miso && cd miso/sample-app && stack setup && stack build
 ```
 
+Note: It's important to ensure that you don't have a global `cabal-install` present on your system. This could cause build problems. If you see an error like this (below), try deleting your global `cabal-install`.
+
+```bash
+exit status: 1                                
+stderr: solver must be one of: modular        
+CallStack (from HasCallStack):                
+  error, called at libraries/Cabal/Cabal/Distribution/ReadE.hs:46:24 in Cabal-2.0.1.0:Distribution.ReadE
+```
+
+
 For more information on using `stack` w/ `miso`, see the [`stack` section below](#stack)
 
 
@@ -257,8 +265,8 @@
   result = import (pkgs.fetchFromGitHub {
     owner = "dmjio";
     repo = "miso";
-    sha256 = "03w1gffzw0qry6q5may5miyjf36574kx12pviywjddpckp62p8h3";
-    rev = "2a42c67ef1f876b2f81dbcf18bcc18269d0f6876";
+    sha256 = "1l1gwzzqlvvcmg70jjrwc5ijv1vb6y5ljqkh7rxxq7hkyxpjyx9q";
+    rev = "95f6bc9b1ae6230b110358a82b6a573806f272c2";
   }) {};
 in pkgs.haskell.packages.ghcjs.callPackage ./app.nix {
   miso = result.miso-ghcjs;
@@ -404,12 +412,12 @@
 main = startApp App {..}
   where
     initialAction = SayHelloWorld -- initial action to be executed on application load
-    model  = 0                    -- initial model
-    update = updateModel          -- update function
-    view   = viewModel            -- view function
-    events = defaultEvents        -- default delegated events
-    mountPoint = Nothing          -- mount point for miso on DOM, defaults to body
-    subs   = []                   -- empty subscription list
+    model         = 0             -- initial model
+    update        = updateModel   -- update function
+    view          = viewModel     -- view function
+    events        = defaultEvents -- default delegated events
+    subs          = []            -- empty subscription list
+    mountPoint    = Nothing       -- mount point for application (Nothing defaults to 'body')
 
 -- | Updates model, optionally introduces side effects
 updateModel :: Action -> Model -> Effect Action Model
@@ -423,7 +431,7 @@
 viewModel :: Model -> View Action
 viewModel x = div_ [] [
    button_ [ onClick AddOne ] [ text "+" ]
- , text (ms (show x))
+ , text (ms x)
  , button_ [ onClick SubtractOne ] [ text "-" ]
  ]
 ```
@@ -467,6 +475,14 @@
 cd result/examples/todo-mvc.jsexe && python -m SimpleHTTPServer
 Serving HTTP on 0.0.0.0 port 8000 ...
 ```
+
+## Isomorphic
+
+Isomorphic javascript is a technique for increased SEO, code-sharing and perceived page load times. It works in two parts. First, the server sends a pre-rendered HTML body to the client's browser. Second, after the client javascript application loads, the pointers of the pre-rendered DOM are copied into the virtual DOM, and the application proceeds as normal. All subsequent page navigation is handled locally by the client, avoiding full-page postbacks as necessary.
+
+The `miso` function is used to perform the pointer-copying behavior client-side.
+
+For more information on how `miso` handles isomorphic javascript, we recommend [this tutorial](https://github.com/FPtje/miso-isomorphic-example).
 
 ## Pinning nixpkgs
 
diff --git a/examples/compose-update/Main.hs b/examples/compose-update/Main.hs
--- a/examples/compose-update/Main.hs
+++ b/examples/compose-update/Main.hs
@@ -103,6 +103,6 @@
   div_
     []
     [ button_ [onClick Increment] [text "+"]
-    , text (ms (show x) <> " | " <> ms (show y))
+    , text (ms x <> " | " <> ms y)
     , button_ [onClick Decrement] [text "-"]
     ]
diff --git a/examples/file-reader/Main.hs b/examples/file-reader/Main.hs
--- a/examples/file-reader/Main.hs
+++ b/examples/file-reader/Main.hs
@@ -65,7 +65,7 @@
         "FileReader API example"
       , input_ [ id_ "fileReader"
              , type_ "file"
-             , onChange ReadFile
+             , onChange (const ReadFile)
              ] []
       , div_ [] [ text info ]
       ]
@@ -90,6 +90,3 @@
 
 foreign import javascript unsafe "$1.readAsText($2);"
   readText :: JSVal -> JSVal -> IO ()
-
-onChange :: action -> Attribute action
-onChange r = on "change" emptyDecoder (const r)
diff --git a/examples/mario/Main.hs b/examples/mario/Main.hs
--- a/examples/mario/Main.hs
+++ b/examples/mario/Main.hs
@@ -117,8 +117,8 @@
     (h,w) = window
     groundY = 62 - (fromIntegral (fst window) / 2)
     marioImage =
-      div_ [ height_ $ pack (show h)
-           , width_ $ pack (show w)
+      div_ [ height_ $ ms h
+           , width_ $ ms w
            ] [ div_ [ style_ (marioStyle m groundY) ] [] ]
 
 marioStyle :: Model -> Double -> M.Map MisoString MisoString
@@ -142,7 +142,7 @@
   "matrix("
      <> (if dir == L then "-1" else "1")
      <> ",0,0,1,"
-     <> pack (show x)
+     <> ms x
      <> ","
-     <> pack (show y)
+     <> ms y
      <> ")"
diff --git a/examples/svg/Main.hs b/examples/svg/Main.hs
--- a/examples/svg/Main.hs
+++ b/examples/svg/Main.hs
@@ -60,15 +60,15 @@
          , onTouchMove HandleTouch
        ] [
      g_ [] [
-     ellipse_ [ cx_ $ pack $ show x
-              , cy_ $ pack $ show y
+     ellipse_ [ cx_ $ ms x
+              , cy_ $ ms y
               , style_ svgStyle
               , rx_ "100"
               , ry_ "100"
               ] [ ]
      ]
-     , text_ [ x_ $ pack $ show x
-             , y_ $ pack $ show y
+     , text_ [ x_ $ ms x
+             , y_ $ ms y
              ] [ text $ ms $ show (x,y) ]
    ]
  ]
diff --git a/examples/todo-mvc/Main.hs b/examples/todo-mvc/Main.hs
--- a/examples/todo-mvc/Main.hs
+++ b/examples/todo-mvc/Main.hs
@@ -220,7 +220,7 @@
         [ class_ "edit"
         , value_ description
         , name_ "title"
-        , id_ $ "todo-" <> S.pack (show eid)
+        , id_ $ "todo-" <> S.ms eid
         , onInput $ UpdateEntry eid
         , onBlur $ EditingEntry eid False
         , onEnter $ EditingEntry eid False
@@ -244,7 +244,7 @@
 viewControlsCount :: Int -> View Msg
 viewControlsCount entriesLeft =
   span_ [ class_ "todo-count" ]
-     [ strong_ [] [ text $ S.pack (show entriesLeft) ]
+     [ strong_ [] [ text $ S.ms entriesLeft ]
      , text (item_ <> " left")
      ]
   where
@@ -277,7 +277,7 @@
     , prop "hidden" (entriesCompleted == 0)
     , onClick DeleteComplete
     ]
-    [ text $ "Clear completed (" <> S.pack (show entriesCompleted) <> ")" ]
+    [ text $ "Clear completed (" <> S.ms entriesCompleted <> ")" ]
 
 viewInput :: Model -> MisoString -> View Msg
 viewInput _ task =
diff --git a/ghcjs-src/Miso/Html/Internal.hs b/ghcjs-src/Miso/Html/Internal.hs
--- a/ghcjs-src/Miso/Html/Internal.hs
+++ b/ghcjs-src/Miso/Html/Internal.hs
@@ -55,7 +55,6 @@
 import           Control.Monad
 import           Data.Aeson.Types           (parseEither)
 import           Data.JSString
-import           Data.JSString.Text
 import qualified Data.Map                   as M
 import           Data.Monoid
 import           Data.Proxy
@@ -188,17 +187,17 @@
 -- | Convert `MisoString` to `Key`
 instance ToKey MisoString where toKey = Key
 -- | Convert `Text` to `Key`
-instance ToKey T.Text where toKey = Key . textToJSString
+instance ToKey T.Text where toKey = Key . toMisoString
 -- | Convert `String` to `Key`
-instance ToKey String where toKey = Key . pack
+instance ToKey String where toKey = Key . toMisoString
 -- | Convert `Int` to `Key`
-instance ToKey Int where toKey = Key . pack . show
+instance ToKey Int where toKey = Key . toMisoString
 -- | Convert `Double` to `Key`
-instance ToKey Double where toKey = Key . pack . show
+instance ToKey Double where toKey = Key . toMisoString
 -- | Convert `Float` to `Key`
-instance ToKey Float where toKey = Key . pack . show
+instance ToKey Float where toKey = Key . toMisoString
 -- | Convert `Word` to `Key`
-instance ToKey Word where toKey = Key . pack . show
+instance ToKey Word where toKey = Key . toMisoString
 
 -- | Attribute of a vnode in a `View`.
 --
diff --git a/ghcjs-src/Miso/String.hs b/ghcjs-src/Miso/String.hs
--- a/ghcjs-src/Miso/String.hs
+++ b/ghcjs-src/Miso/String.hs
@@ -25,12 +25,16 @@
 import qualified Data.ByteString         as B
 import qualified Data.ByteString.Lazy    as BL
 import           Data.JSString
+import           Data.JSString.Int
+import           Data.JSString.RealFloat
 import           Data.JSString.Text
 import           Data.Monoid
 import qualified Data.Text               as T
 import qualified Data.Text.Encoding      as T
 import qualified Data.Text.Lazy          as LT
 import qualified Data.Text.Lazy.Encoding as LT
+import           GHCJS.Marshal.Pure
+import           GHCJS.Types
 
 -- | String type swappable based on compiler
 type MisoString = JSString
@@ -72,3 +76,18 @@
 instance ToMisoString BL.ByteString where
   toMisoString = toMisoString . LT.decodeUtf8
   fromMisoString = LT.encodeUtf8 . fromMisoString
+instance ToMisoString Float where
+  toMisoString = realFloat
+  fromMisoString = pFromJSVal . toJSNumber
+instance ToMisoString Double where
+  toMisoString = realFloat
+  fromMisoString = pFromJSVal . toJSNumber
+instance ToMisoString Int where
+  toMisoString = decimal
+  fromMisoString = pFromJSVal . toJSNumber
+instance ToMisoString Word where
+  toMisoString = decimal
+  fromMisoString = pFromJSVal . toJSNumber
+
+foreign import javascript unsafe "$r = Number($1);"
+  toJSNumber :: JSString -> JSVal
diff --git a/ghcjs-src/Miso/Util.hs b/ghcjs-src/Miso/Util.hs
--- a/ghcjs-src/Miso/Util.hs
+++ b/ghcjs-src/Miso/Util.hs
@@ -14,6 +14,32 @@
   , windowAddEventListener
   , stringify
   , parse
+
+  , withFoldable
+  , conditionalViews
   ) where
 
 import Miso.FFI
+import Miso.Html.Internal
+import Data.Foldable
+
+-- | Generic @map@ function, useful for creating @View@s from the elements of
+-- some @Foldable@. Particularly handy for @Maybe@, as shown in the example
+-- below.
+--
+-- @
+-- view model =
+--     div_ [] $
+--      withFoldable (model ^. mSomeMaybeVal) $ \someVal ->
+--         p_ [] [ text $ "Hey, look at this value: " <> ms (show someVal) ]
+-- @
+withFoldable :: Foldable t => t a -> (a -> b) -> [b]
+withFoldable ta f = map f (toList ta)
+
+-- | Hides the @View@s the condition is False. Shows them when the condition
+-- is True.
+conditionalViews :: Bool -> [View action] -> [View action]
+conditionalViews condition views =
+    if condition
+    then views
+    else []
diff --git a/jsbits/delegate.js b/jsbits/delegate.js
--- a/jsbits/delegate.js
+++ b/jsbits/delegate.js
@@ -70,7 +70,8 @@
   }
 }
 
-/* Convert event to JSON at a specific location in the DOM tree*/
+/* Walks down obj following the path described by `at`, then filters primitive
+ values (string, numbers and booleans)*/
 function objectToJSON (at, obj) {
   /* If at is of type [[MisoString]] */
   if (typeof at[0] == "object") {
@@ -83,7 +84,7 @@
   for (var i in at) obj = obj[at[i]];
 
   /* If obj is a list-like object */
-  if ("length" in obj) {
+  if (obj instanceof Array) {
     var newObj = [];
     for (var i = 0; i < obj.length; i++)
       newObj.push(objectToJSON([], obj[i]));
diff --git a/miso.cabal b/miso.cabal
--- a/miso.cabal
+++ b/miso.cabal
@@ -1,5 +1,5 @@
 name:                miso
-version:             0.12.0.0
+version:             0.13.0.0
 category:            Web, Miso, Data Structures
 license:             BSD3
 license-file:        LICENSE
diff --git a/src/Miso/Html/Event.hs b/src/Miso/Html/Event.hs
--- a/src/Miso/Html/Event.hs
+++ b/src/Miso/Html/Event.hs
@@ -40,6 +40,7 @@
   , onKeyUp
   -- * Form events
   , onInput
+  , onChange
   , onChecked
   , onSubmit
   -- * Focus events
@@ -86,6 +87,10 @@
 -- | https://developer.mozilla.org/en-US/docs/Web/Events/input
 onInput :: (MisoString -> action) -> Attribute action
 onInput = on "input" valueDecoder
+
+-- | https://developer.mozilla.org/en-US/docs/Web/Events/change
+onChange :: (MisoString -> action) -> Attribute action
+onChange = on "change" valueDecoder
 
 -- | https://developer.mozilla.org/en-US/docs/Web/Events/keydown
 onKeyDown :: (KeyCode -> action) -> Attribute action
