diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -372,7 +372,7 @@
 
 The easiest way to build the examples is with the [`nix`](https://nixos.org/nix/) package manager
 ```
-git clone https://github.com/dmjio/miso && cd miso && nix-build -A miso-ghcjs
+git clone https://github.com/dmjio/miso && cd miso && nix-build --arg examples true
 ```
 
 This will build all examples and documentation into a folder named `result`
@@ -450,6 +450,7 @@
 ## Commercial Users
   - [Polimorphic](https://www.polimorphic.com)
   - [LumiGuide](https://lumi.guide/en/)
+  - [Clovyr](https://clovyr.io)
 
 ## Contributing
 
diff --git a/frontend-src/Miso.hs b/frontend-src/Miso.hs
--- a/frontend-src/Miso.hs
+++ b/frontend-src/Miso.hs
@@ -129,7 +129,7 @@
         loop newModel
   loop m
 
--- | Runs an isomorphic miso application
+-- | Runs an isomorphic miso application.
 -- Assumes the pre-rendered DOM is already present
 miso :: Eq model => (URI -> App model action) -> JSM ()
 miso f = do
diff --git a/frontend-src/Miso/Effect.hs b/frontend-src/Miso/Effect.hs
--- a/frontend-src/Miso/Effect.hs
+++ b/frontend-src/Miso/Effect.hs
@@ -6,6 +6,9 @@
 -- Maintainer  :  David M. Johnson <djohnson.m@gmail.com>
 -- Stability   :  experimental
 -- Portability :  non-portable
+--
+-- This module defines `Effect` and `Sub` types, which are used to define
+-- `Miso.Types.update` function and `Miso.Types.subs` field of the `Miso.Types.App`.
 ----------------------------------------------------------------------------
 module Miso.Effect (
   module Miso.Effect.Storage
@@ -37,10 +40,10 @@
 -- | Type synonym for constructing event subscriptions.
 --
 -- The 'Sink' callback is used to dispatch actions which are then fed
--- back to the 'update' function.
+-- back to the 'Miso.Types.update' function.
 type Sub action = Sink action -> JSM ()
 
--- | Function to asynchronously dispatch actions to the 'update' function.
+-- | Function to asynchronously dispatch actions to the 'Miso.Types.update' function.
 type Sink action = action -> IO ()
 
 -- | Turn a subscription that consumes actions of type @a@ into a subscription
@@ -77,7 +80,7 @@
 (#>) :: JSM action -> model -> Effect action model
 (#>) = flip (<#)
 
--- | `Smart constructor for an 'Effect' with multiple actions.
+-- | Smart constructor for an 'Effect' with multiple actions.
 batchEff :: model -> [JSM action] -> Effect action model
 batchEff model actions = Effect model $
   map (\a sink -> liftIO . sink =<< a) actions
diff --git a/frontend-src/Miso/Effect/Storage.hs b/frontend-src/Miso/Effect/Storage.hs
--- a/frontend-src/Miso/Effect/Storage.hs
+++ b/frontend-src/Miso/Effect/Storage.hs
@@ -54,7 +54,7 @@
         Success x -> Right x
         Error y -> Left y
 
--- | Retrieve session storage
+-- | Retrieve a value stored under given key in session storage
 getSessionStorage :: FromJSON model => JSString -> JSM (Either String model)
 getSessionStorage =
   getStorageCommon $ \t -> do
@@ -62,7 +62,7 @@
     r <- Storage.getItem s t
     fromJSVal r
 
--- | Retrieve local storage
+-- | Retrieve a value stored under given key in local storage
 getLocalStorage :: FromJSON model => JSString -> JSM (Either String model)
 getLocalStorage = getStorageCommon $ \t -> do
     s <- Storage.localStorage
diff --git a/frontend-src/Miso/String.hs b/frontend-src/Miso/String.hs
--- a/frontend-src/Miso/String.hs
+++ b/frontend-src/Miso/String.hs
@@ -16,6 +16,8 @@
 ----------------------------------------------------------------------------
 module Miso.String (
     ToMisoString (..)
+  , FromMisoString (..)
+  , fromMisoString
   , MisoString
   , module Data.JSString
   , module Data.Monoid
@@ -24,9 +26,12 @@
 
 #ifndef JSADDLE
 import           Data.Aeson
+import           Data.Char
+
 #endif
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as BL
+import           Data.Char
 import           Data.JSString
 import           Data.JSString.Text
 import           Data.Monoid
@@ -34,13 +39,15 @@
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.Lazy as LT
 import qualified Data.Text.Lazy.Encoding as LT
-
+import           Prelude hiding (foldr)
 import           Miso.FFI
 
 -- | String type swappable based on compiler
 type MisoString = JSString
 
 #ifndef JSADDLE
+
+
 -- | `ToJSON` for `MisoString`
 instance ToJSON MisoString where
   toJSON = String . textFromJSString
@@ -55,39 +62,80 @@
 -- | Convenience class for creating `MisoString` from other string-like types
 class ToMisoString str where
   toMisoString :: str -> MisoString
-  fromMisoString :: MisoString -> str
 
+class FromMisoString t where
+  -- -- | Reads a `MisoString` into an 'a', throws an error when
+  fromMisoStringEither :: MisoString -> Either String t
+
+-- | Reads a `MisoString` into an 'a', throws an error when decoding
+-- fails. Use `fromMisoStringEither` for as a safe alternative.
+fromMisoString :: FromMisoString a => MisoString -> a
+fromMisoString s = case fromMisoStringEither s of
+                     Left err -> error err
+                     Right x  -> x
+
 -- | Convenience function, shorthand for `toMisoString`
 ms :: ToMisoString str => str -> MisoString
 ms = toMisoString
 
 instance ToMisoString MisoString where
   toMisoString = id
-  fromMisoString = id
 instance ToMisoString String where
   toMisoString = pack
-  fromMisoString = unpack
 instance ToMisoString T.Text where
   toMisoString = textToJSString
-  fromMisoString = textFromJSString
 instance ToMisoString LT.Text where
   toMisoString = lazyTextToJSString
-  fromMisoString = lazyTextFromJSString
 instance ToMisoString B.ByteString where
   toMisoString = toMisoString . T.decodeUtf8
-  fromMisoString = T.encodeUtf8 . fromMisoString
 instance ToMisoString BL.ByteString where
   toMisoString = toMisoString . LT.decodeUtf8
-  fromMisoString = LT.encodeUtf8 . fromMisoString
 instance ToMisoString Float where
   toMisoString = realFloatToJSString
-  fromMisoString = realToFrac . jsStringToDouble
 instance ToMisoString Double where
   toMisoString = realFloatToJSString
-  fromMisoString = jsStringToDouble
 instance ToMisoString Int where
   toMisoString = integralToJSString
-  fromMisoString = round . jsStringToDouble
 instance ToMisoString Word where
   toMisoString = integralToJSString
-  fromMisoString = round . jsStringToDouble
+
+instance FromMisoString MisoString where
+  fromMisoStringEither = Right
+instance FromMisoString String where
+  fromMisoStringEither = Right . unpack
+instance FromMisoString T.Text where
+  fromMisoStringEither = Right . textFromJSString
+instance FromMisoString LT.Text where
+  fromMisoStringEither = Right . lazyTextFromJSString
+instance FromMisoString B.ByteString where
+  fromMisoStringEither = fmap T.encodeUtf8 . fromMisoStringEither
+instance FromMisoString BL.ByteString where
+  fromMisoStringEither = fmap LT.encodeUtf8 . fromMisoStringEither
+instance FromMisoString Float where
+  fromMisoStringEither = fmap realToFrac . jsStringToDoubleEither
+instance FromMisoString Double where
+  fromMisoStringEither = jsStringToDoubleEither
+instance FromMisoString Int where
+  fromMisoStringEither = parseInt
+instance FromMisoString Word where
+  fromMisoStringEither = parseWord
+
+jsStringToDoubleEither :: JSString -> Either String Double
+jsStringToDoubleEither s = let d = jsStringToDouble s
+                           in if isNaN d then Left "jsStringToDoubleEither: parse failed"
+                                         else Right d
+
+
+parseWord   :: MisoString -> Either String Word
+parseWord s = case uncons s of
+                Nothing     -> Left "parseWord: parse error"
+                Just (c,s') -> foldl' k (pDigit c) s'
+  where
+    pDigit c | isDigit c = Right . fromIntegral . digitToInt $ c
+             | otherwise = Left "parseWord: parse error"
+    k ea c = (\a x -> 10*a + x) <$> ea <*> pDigit c
+
+parseInt   :: MisoString -> Either String Int
+parseInt s = case uncons s of
+               Just ('-',s') -> ((-1)*) . fromIntegral <$> parseWord s'
+               _             ->           fromIntegral <$> parseWord s
diff --git a/frontend-src/Miso/Subscription/WebSocket.hs b/frontend-src/Miso/Subscription/WebSocket.hs
--- a/frontend-src/Miso/Subscription/WebSocket.hs
+++ b/frontend-src/Miso/Subscription/WebSocket.hs
@@ -4,6 +4,7 @@
 {-# LANGUAGE RankNTypes                 #-}
 {-# LANGUAGE LambdaCase                 #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE CPP                        #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Miso.Subscription.WebSocket
@@ -25,6 +26,7 @@
     -- * Subscription
   , websocketSub
   , send
+  , close
   , connect
   , getSocketState
   ) where
@@ -36,6 +38,7 @@
 import           Data.IORef
 import           Data.Maybe
 import           GHCJS.Marshal
+import           GHCJS.Foreign
 import           GHCJS.Types
 import           Prelude hiding (map)
 import           System.IO.Unsafe
@@ -82,8 +85,18 @@
     liftIO . sink $ f (WebSocketClose code clean reason)
   WS.addEventListener socket "error" $ \v -> do
     liftIO (writeIORef closedCode Nothing)
-    d <- parse =<< WS.data' v
-    liftIO . sink $ f (WebSocketError d)
+    d' <- WS.data' v
+#ifndef __GHCJS__        
+    undef <- ghcjsPure (isUndefined d')
+#else
+    let undef = isUndefined d'
+#endif
+    if undef
+      then do
+         liftIO . sink $ f (WebSocketError mempty)
+      else do
+         Just d <- fromJSVal d'
+         liftIO . sink $ f (WebSocketError d)
   where
     handleReconnect = do
       liftIO (threadDelay (secs 3))
@@ -102,6 +115,13 @@
 send x = do
   Just socket <- liftIO (readIORef websocket)
   sendJson' socket x
+
+-- | Sends message to a websocket server
+close :: JSM ()
+{-# INLINE close #-}
+close =
+  mapM_ WS.close =<<
+    liftIO (readIORef websocket)
 
 -- | Connects to a websocket server
 connect :: URL -> Protocols -> JSM ()
diff --git a/frontend-src/Miso/Types.hs b/frontend-src/Miso/Types.hs
--- a/frontend-src/Miso/Types.hs
+++ b/frontend-src/Miso/Types.hs
@@ -40,18 +40,19 @@
   { model :: model
   -- ^ initial model
   , update :: action -> model -> Effect action model
-  -- ^ Function to update model, optionally provide effects.
+  -- ^ Function to update model, optionally providing effects.
   --   See the 'Transition' monad for succinctly expressing model transitions.
   , view :: model -> View action
   -- ^ Function to draw `View`
   , subs :: [ Sub action ]
   -- ^ List of subscriptions to run during application lifetime
   , events :: M.Map MisoString Bool
-  -- ^ List of delegated events that the body element will listen for
+  -- ^ List of delegated events that the body element will listen for.
+  --   You can start with 'Miso.Event.Types.defaultEvents' and modify as needed.
   , initialAction :: action
   -- ^ Initial action that is run after the application has loaded
   , mountPoint :: Maybe MisoString
-  -- ^ root element for DOM diff
+  -- ^ Id of the root element for DOM diff. If 'Nothing' is provided, the entire document body is used as a mount point.
   }
 
 -- | A monad for succinctly expressing model transitions in the 'update' function.
diff --git a/ghc-src/Miso/String.hs b/ghc-src/Miso/String.hs
--- a/ghc-src/Miso/String.hs
+++ b/ghc-src/Miso/String.hs
@@ -12,6 +12,8 @@
 ----------------------------------------------------------------------------
 module Miso.String
   ( ToMisoString (..)
+  , FromMisoString (..)
+  , fromMisoString
   , MisoString
   , module Data.Monoid
   , module Data.Text
@@ -26,45 +28,65 @@
 import qualified Data.Text.Encoding      as T
 import qualified Data.Text.Lazy          as LT
 import qualified Data.Text.Lazy.Encoding as LT
+import           Text.Read(readEither)
 
+
 -- | String type swappable based on compiler
 type MisoString = Text
 
 -- | Convenience class for creating `MisoString` from other string-like types
 class ToMisoString str where
   toMisoString :: str -> MisoString
-  fromMisoString :: MisoString -> str
 
+class FromMisoString t where
+  -- -- | Reads a `MisoString` into an 'a', throws an error when
+  fromMisoStringEither :: MisoString -> Either String t
+
+-- | Reads a `MisoString` into an 'a', throws an error when decoding
+-- fails. Use `fromMisoStringEither` for as a safe alternative.
+fromMisoString :: FromMisoString a => MisoString -> a
+fromMisoString s = case fromMisoStringEither s of
+                     Left err -> error err
+                     Right x  -> x
+
 -- | Convenience function, shorthand for `toMisoString`
 ms :: ToMisoString str => str -> MisoString
 ms = toMisoString
 
 instance ToMisoString MisoString where
   toMisoString = id
-  fromMisoString = id
 instance ToMisoString String where
   toMisoString = T.pack
-  fromMisoString = T.unpack
 instance ToMisoString LT.Text where
   toMisoString = LT.toStrict
-  fromMisoString = LT.fromStrict
 instance ToMisoString B.ByteString where
   toMisoString = toMisoString . T.decodeUtf8
-  fromMisoString = T.encodeUtf8 . fromMisoString
 instance ToMisoString BL.ByteString where
   toMisoString = toMisoString . LT.decodeUtf8
-  fromMisoString = LT.encodeUtf8 . fromMisoString
 instance ToMisoString Float where
   toMisoString = T.pack . show
-  fromMisoString = read . T.unpack
 instance ToMisoString Double where
   toMisoString = T.pack . show
-  fromMisoString = read . T.unpack
 instance ToMisoString Int where
   toMisoString = T.pack . show
-  -- Replicate frontend behavior
-  fromMisoString = round . (read :: String -> Double) . T.unpack
 instance ToMisoString Word where
   toMisoString = T.pack . show
-  -- Replicate frontend behavior
-  fromMisoString = round . (read :: String -> Double) . T.unpack
+
+instance FromMisoString MisoString where
+  fromMisoStringEither = Right
+instance FromMisoString String where
+  fromMisoStringEither = Right . T.unpack
+instance FromMisoString LT.Text where
+  fromMisoStringEither = Right . LT.fromStrict
+instance FromMisoString B.ByteString where
+  fromMisoStringEither = fmap T.encodeUtf8 . fromMisoStringEither
+instance FromMisoString BL.ByteString where
+  fromMisoStringEither = fmap LT.encodeUtf8 . fromMisoStringEither
+instance FromMisoString Float where
+  fromMisoStringEither = readEither . T.unpack
+instance FromMisoString Double where
+  fromMisoStringEither = readEither . T.unpack
+instance FromMisoString Int where
+  fromMisoStringEither = readEither . T.unpack
+instance FromMisoString Word where
+  fromMisoStringEither = readEither . T.unpack
diff --git a/ghcjs-ffi/Miso/FFI.hs b/ghcjs-ffi/Miso/FFI.hs
--- a/ghcjs-ffi/Miso/FFI.hs
+++ b/ghcjs-ffi/Miso/FFI.hs
@@ -76,6 +76,7 @@
 -- resolves to the `JSM` type defined in `jsaddle`.
 type JSM = IO
 
+-- | Run given `JSM` action asynchronously, in a separate thread.
 forkJSM :: JSM () -> JSM ()
 forkJSM a = () <$ forkIO a
 
@@ -88,6 +89,7 @@
 ghcjsPure :: a -> JSM a
 ghcjsPure = pure
 
+-- | Forces execution of pending asyncronous code
 syncPoint :: JSM ()
 syncPoint = pure ()
 
@@ -95,14 +97,20 @@
 set :: ToJSVal v => JSString -> v -> OI.Object -> IO ()
 set k v obj = toJSVal v >>= \x -> OI.setProp k x obj
 
--- | Adds event listener to window
 foreign import javascript unsafe "$1.addEventListener($2, $3);"
   addEventListener' :: JSVal -> JSString -> Callback (JSVal -> IO ()) -> IO ()
 
-addEventListener :: JSVal -> JSString -> (JSVal -> IO ()) -> IO ()
+-- | Register an event listener on given target.
+addEventListener :: JSVal            -- ^ Event target on which we want to register event listener
+                 -> JSString         -- ^ Type of event to listen to (e.g. "click")
+                 -> (JSVal -> IO ()) -- ^ Callback which will be called when the event occurs. The event is passed as a parameter to it.
+                 -> IO ()
 addEventListener self name cb = addEventListener' self name =<< asyncCallback1 cb
 
-windowAddEventListener :: JSString -> (JSVal -> IO ()) -> IO ()
+-- | Registers an event listener on window
+windowAddEventListener :: JSString           -- ^ Type of event to listen to (e.g. "click")
+                       -> (JSVal -> IO ())  -- ^ Callback which will be called when the event occurs, the event will be passed to it as a parameter.
+                       -> IO ()
 windowAddEventListener name cb = do
   win <- getWindow
   addEventListener win name cb
@@ -119,19 +127,27 @@
   getWindow :: IO JSVal
 
 
--- | Retrieves inner height
+-- | Retrieves the height (in pixels) of the browser window viewport including, if rendered, the horizontal scrollbar.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight>
 foreign import javascript unsafe "$r = window['innerHeight'];"
   windowInnerHeight :: IO Int
 
--- | Retrieves outer height
+-- | Retrieves the width (in pixels) of the browser window viewport including, if rendered, the vertical scrollbar.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth>
 foreign import javascript unsafe "$r = window['innerWidth'];"
   windowInnerWidth :: IO Int
 
--- | Retrieve high performance time stamp
+-- | Retrieve high resolution time stamp
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Performance/now>
 foreign import javascript unsafe "$r = performance.now();"
   now :: IO Double
 
--- | Console-logging
+-- | Outputs a message to the web console
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Console/log>
 foreign import javascript unsafe "console.log($1);"
   consoleLog :: JSString -> IO ()
 
@@ -172,12 +188,21 @@
     -> JSVal -- ^ object with impure references to the DOM
     -> IO JSVal
 
+-- | Retrieves a reference to the document body.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/body>
 foreign import javascript unsafe "$r = document.body;"
   getBody :: IO JSVal
 
+-- | Retrieves a reference to the document.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document>
 foreign import javascript unsafe "$r = document;"
   getDoc :: IO JSVal
 
+-- | Returns an Element object representing the element whose id property matches the specified string.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById>
 foreign import javascript unsafe "$r = document.getElementById($1);"
   getElementById :: JSString -> IO JSVal
 
diff --git a/ghcjs-ffi/Miso/FFI/WebSocket.hs b/ghcjs-ffi/Miso/FFI/WebSocket.hs
--- a/ghcjs-ffi/Miso/FFI/WebSocket.hs
+++ b/ghcjs-ffi/Miso/FFI/WebSocket.hs
@@ -16,6 +16,7 @@
   , create
   , socketState
   , send
+  , close
   , addEventListener
   , data'
   , wasClean
@@ -32,6 +33,9 @@
 
 foreign import javascript unsafe "$r = new WebSocket($1, $2);"
   create :: JSString -> JSVal -> IO Socket
+
+foreign import javascript unsafe "$1.close()"
+  close :: Socket -> IO ()
 
 foreign import javascript unsafe "$r = $1.readyState;"
   socketState :: Socket -> IO Int
diff --git a/jsaddle-ffi/Miso/FFI.hs b/jsaddle-ffi/Miso/FFI.hs
--- a/jsaddle-ffi/Miso/FFI.hs
+++ b/jsaddle-ffi/Miso/FFI.hs
@@ -68,6 +68,7 @@
 import qualified JavaScript.Object.Internal as OI
 import           Language.Javascript.JSaddle hiding (Success, obj, val)
 
+-- | Run given `JSM` action asynchronously, in a separate thread.
 forkJSM :: JSM () -> JSM ()
 forkJSM a = do
   ctx <- askJSM
@@ -92,13 +93,19 @@
   v' <- toJSVal v
   setProp k v' obj
 
-addEventListener :: JSVal -> JSString -> (JSVal -> JSM ()) -> JSM ()
+-- | Register an event listener on given target.
+addEventListener :: JSVal             -- ^ Event target on which we want to register event listener
+                 -> JSString          -- ^ Type of event to listen to (e.g. "click")
+                 -> (JSVal -> JSM ()) -- ^ Callback which will be called when the event occurs, the event will be passed to it as a parameter.
+                 -> JSM ()
 addEventListener self name cb = do
   _ <- self # "addEventListener" $ (name, asyncFunction (\_ _ [a] -> cb a))
   pure ()
 
--- | Adds event listener to window
-windowAddEventListener :: JSString -> (JSVal -> JSM ()) -> JSM ()
+-- | Registers an event listener on window
+windowAddEventListener :: JSString           -- ^ Type of event to listen to (e.g. "click")
+                       -> (JSVal -> JSM ())  -- ^ Callback which will be called when the event occurs, the event will be passed to it as a parameter.
+                       -> JSM ()
 windowAddEventListener name cb = do
   win <- jsg "window"
   addEventListener win name cb
@@ -113,21 +120,29 @@
   _ <- e # "preventDefault" $ ()
   pure ()
 
--- | Retrieves inner height
+-- | Retrieves the height (in pixels) of the browser window viewport including, if rendered, the horizontal scrollbar.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight>
 windowInnerHeight :: JSM Int
 windowInnerHeight =
   fromJSValUnchecked =<< jsg "window" ! "innerHeight"
 
--- | Retrieves outer height
+-- | Retrieves the width (in pixels) of the browser window viewport including, if rendered, the vertical scrollbar.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth>
 windowInnerWidth :: JSM Int
 windowInnerWidth =
   fromJSValUnchecked =<< jsg "window" ! "innerWidth"
 
--- | Retrieve high performance time stamp
+-- | Retrieve high resolution time stamp
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Performance/now>
 now :: JSM Double
 now = fromJSValUnchecked =<< (jsg "performance" # "now" $ ())
 
--- | Console-logging
+-- | Outputs a message to the web console
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Console/log>
 consoleLog :: JSString -> JSM ()
 consoleLog v = do
   _ <- jsg "console" # "log" $ [toJSString v]
@@ -167,12 +182,22 @@
     -> JSM JSVal
 objectToJSON = jsg2 "objectToJSON"
 
+-- | Retrieves a reference to document body.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/body>
 getBody :: JSM JSVal
 getBody = jsg "document" ! "body"
 
+
+-- | Retrieves a reference to the document.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document>
 getDoc :: JSM JSVal
 getDoc = jsg "document"
 
+-- | Returns an Element object representing the element whose id property matches the specified string.
+--
+-- See <https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById>
 getElementById :: JSString -> JSM JSVal
 getElementById e = getDoc # "getElementById" $ [e]
 
diff --git a/jsaddle-ffi/Miso/FFI/WebSocket.hs b/jsaddle-ffi/Miso/FFI/WebSocket.hs
--- a/jsaddle-ffi/Miso/FFI/WebSocket.hs
+++ b/jsaddle-ffi/Miso/FFI/WebSocket.hs
@@ -16,6 +16,7 @@
   , create
   , socketState
   , send
+  , close
   , addEventListener
   , data'
   , wasClean
@@ -42,6 +43,11 @@
 send :: Socket -> JSString -> JSM ()
 send (Socket s) msg = do
   _ <- s # ("send" :: JSString) $ [msg]
+  pure ()
+
+close :: Socket -> JSM ()
+close (Socket s) = do
+  _ <- s # ("close" :: JSString) $ ([] :: [JSString])
   pure ()
 
 addEventListener :: Socket -> JSString -> (JSVal -> JSM ()) -> JSM ()
diff --git a/jsbits/delegate.js b/jsbits/delegate.js
--- a/jsbits/delegate.js
+++ b/jsbits/delegate.js
@@ -44,34 +44,30 @@
 
   /* stack not length 1, recurse */
   else if (stack.length > 1) {
-    if (obj['domRef'] === stack[0]) parentStack.unshift(obj);
+    parentStack.unshift(obj);
     for (var o = 0; o < obj.children.length; o++) {
-      if (obj.children[o]['type'] === 'vtext') continue;
-      delegateEvent ( event
-		    , obj.children[o]
-		    , stack.slice(1)
-		    , parentStack
-		    );
-     }
+      if (obj.children[o]['domRef'] === stack[1]) {
+        delegateEvent( event, obj.children[o], stack.slice(1), parentStack );
+        break;
+      }
+    }
   }
 
   /* stack.length == 1 */
   else {
-    if (obj['domRef'] === stack[0]) {
       var eventObj = obj['events'][event.type];
       if (eventObj) {
 	var options = eventObj.options;
-      if (options['preventDefault'])
-	event.preventDefault();
-      eventObj['runEvent'](event);
-      if (!options['stopPropagation'])
-	window['propogateWhileAble'] (parentStack, event);
+        if (options['preventDefault'])
+  	  event.preventDefault();
+        eventObj['runEvent'](event);
+        if (!options['stopPropagation'])
+ 	  window['propogateWhileAble'] (parentStack, event);
       } else {
 	/* still propagate to parent handlers even if event not defined */
 	window['propogateWhileAble'] (parentStack, event);
       }
-    }
-  }
+   }
 };
 
 window['buildTargetToElement'] = function buildTargetToElement (element, target) {
@@ -109,15 +105,16 @@
   for (var i in at) obj = obj[at[i]];
 
   /* If obj is a list-like object */
+  var newObj;
   if (obj instanceof Array) {
-    var newObj = [];
+    newObj = [];
     for (var i = 0; i < obj.length; i++)
       newObj.push(window['objectToJSON']([], obj[i]));
     return newObj;
   }
 
   /* If obj is a non-list-like object */
-  var newObj = {};
+  newObj = {};
   for (var i in obj){
     /* bug in safari, throws TypeError if the following fields are referenced on a checkbox */
     /* https://stackoverflow.com/a/25569117/453261 */
diff --git a/jsbits/diff.js b/jsbits/diff.js
--- a/jsbits/diff.js
+++ b/jsbits/diff.js
@@ -88,7 +88,7 @@
 };
 
 window['diffProps'] = function diffProps(cProps, nProps, node, isSvg) {
-  var result, newProp;
+  var newProp;
   /* Is current prop in new prop list? */
   for (var c in cProps) {
     newProp = nProps[c];
@@ -221,12 +221,11 @@
        -> [ ] <- new children
     */
     else if (newFirstIndex > newLastIndex) {
-      tmp = oldLastIndex - oldFirstIndex;
-      while (tmp >= 0) {
-        parent.removeChild(os[oldFirstIndex]['domRef']);
-        os.splice(oldFirstIndex, 1);
-        tmp--;
+      tmp = oldLastIndex;
+      while (oldLastIndex >= oldFirstIndex) {
+        parent.removeChild(os[oldLastIndex--]['domRef']);
       }
+      os.splice(oldFirstIndex, tmp - oldFirstIndex + 1);
       break;
     }
     /* happy path, everything aligns, we continue
diff --git a/miso.cabal b/miso.cabal
--- a/miso.cabal
+++ b/miso.cabal
@@ -1,5 +1,5 @@
 name:                miso
-version:             1.4.0.0
+version:             1.5.0.0
 category:            Web, Miso, Data Structures
 license:             BSD3
 license-file:        LICENSE
diff --git a/src/Miso/Event/Decoder.hs b/src/Miso/Event/Decoder.hs
--- a/src/Miso/Event/Decoder.hs
+++ b/src/Miso/Event/Decoder.hs
@@ -28,10 +28,10 @@
 import Miso.Event.Types
 import Miso.String
 
--- | Data type for storing the target when parsing events
+-- | Data type representing path (consisting of field names) within event object, where a decoder should be applied.
 data DecodeTarget
-  = DecodeTarget [MisoString] -- ^ Decode a single object
-  | DecodeTargets [[MisoString]] -- ^ Decode multiple objecjects
+  = DecodeTarget [MisoString] -- ^ Specify single path within Event object, where a decoder should be applied.
+  | DecodeTargets [[MisoString]] -- ^ Specify multiple paths withing Event object, where decoding should be attempted. The first path where decoding suceeds is the one taken.
 
 -- | Decoder data type for parsing events
 data Decoder a = Decoder {
@@ -39,7 +39,7 @@
 , decodeAt :: DecodeTarget -- ^ Location in DOM of where to decode
 }
 
--- | Smart constructor for building
+-- | Smart constructor for building a `Decoder`.
 at :: [MisoString] -> (Value -> Parser a) -> Decoder a
 at decodeAt decoder = Decoder {decodeAt = DecodeTarget decodeAt, ..}
 
