diff --git a/jsaddle-dom.cabal b/jsaddle-dom.cabal
--- a/jsaddle-dom.cabal
+++ b/jsaddle-dom.cabal
@@ -1,5 +1,5 @@
 name: jsaddle-dom
-version: 0.2.0.0
+version: 0.2.0.1
 cabal-version: >=1.22
 build-type: Simple
 license: MIT
diff --git a/src/JSDOM.hs b/src/JSDOM.hs
--- a/src/JSDOM.hs
+++ b/src/JSDOM.hs
@@ -5,6 +5,8 @@
 , WebView
 , runWebGUI
 , enableInspector
+, postGUISync
+, postGUIAsync
 ) where
 
 import qualified Data.Text as T
@@ -45,9 +47,9 @@
        (yield, threadDelay, takeMVar, newEmptyMVar)
 import System.Environment (getArgs)
 import Data.List (isSuffixOf)
-import Language.Javascript.JSaddle (runJSaddle, JSM, jsg)
+import Language.Javascript.JSaddle (runJSaddle, JSM, jsg, postGUIAsyncJS, postGUISyncJS)
 import JSDOM.Types
-       (FromJSVal(..), MonadDOM(..), MonadDOM, Document(..), Window(..))
+       (DOM, FromJSVal(..), MonadDOM(..), MonadDOM, Document(..), Window(..))
 import Control.Monad.IO.Class (MonadIO)
 
 #ifdef ghcjs_HOST_OS
@@ -56,6 +58,12 @@
 
 data WebView = WebView
 #endif
+
+postGUIAsync :: DOM () -> DOM ()
+postGUIAsync = postGUIAsyncJS
+
+postGUISync :: DOM a -> DOM a
+postGUISync = postGUISyncJS
 
 currentWindow :: MonadDOM m => m (Maybe Window)
 currentWindow = liftDOM $ jsg ("window" :: String) >>= fromJSVal
diff --git a/src/JSDOM/EventM.hs b/src/JSDOM/EventM.hs
--- a/src/JSDOM/EventM.hs
+++ b/src/JSDOM/EventM.hs
@@ -76,42 +76,52 @@
 import           JSDOM.Generated.EventTarget
 import           JSDOM.EventTargetClosures
 import           Data.Word (Word)
-import           Language.Javascript.JSaddle (JSM)
+import           Data.Foldable (forM_)
 
-type EventM t e = ReaderT e JSM
+type EventM t e = ReaderT e DOM
 
-instance MonadDOM (ReaderT e JSM) where
+instance MonadDOM (ReaderT e DOM) where
     liftDOM = lift
 
-newListener :: (IsEvent e) => EventM t e () -> JSM (SaferEventListener t e)
+newListener :: (IsEvent e) => EventM t e () -> DOM (SaferEventListener t e)
 newListener f = eventListenerNew (runReaderT f)
 
-newListenerSync :: (IsEvent e) => EventM t e () -> JSM (SaferEventListener t e)
+newListenerSync :: (IsEvent e) => EventM t e () -> DOM (SaferEventListener t e)
 newListenerSync f = eventListenerNewSync (runReaderT f)
 
-newListenerAsync :: (IsEvent e) => EventM t e () -> JSM (SaferEventListener t e)
+newListenerAsync :: (IsEvent e) => EventM t e () -> DOM (SaferEventListener t e)
 newListenerAsync f = eventListenerNewAsync (runReaderT f)
 
-addListener :: (IsEventTarget t, IsEvent e) => t -> EventName t e -> SaferEventListener t e -> Bool -> JSM ()
+addListener :: (IsEventTarget t, IsEvent e) => t -> EventName t e -> SaferEventListener t e -> Bool -> DOM ()
 addListener target (EventName eventName) l useCapture = do
     raw <- EventListener <$> toJSVal l
     addEventListener target eventName (Just raw) useCapture
 
-removeListener :: (IsEventTarget t, IsEvent e) => t -> EventName t e -> SaferEventListener t e -> Bool -> JSM ()
+removeListener :: (IsEventTarget t, IsEvent e) => t -> EventName t e -> SaferEventListener t e -> Bool -> DOM ()
 removeListener target (EventName eventName) l useCapture = do
     raw <- EventListener <$> toJSVal l
     removeEventListener target eventName (Just raw) useCapture
 
-releaseListener :: (IsEventTarget t, IsEvent e) => SaferEventListener t e -> JSM ()
+releaseListener :: (IsEventTarget t, IsEvent e) => SaferEventListener t e -> DOM ()
 releaseListener = eventListenerRelease
 
-on :: (IsEventTarget t, IsEvent e) => t -> EventName t e -> EventM t e () -> JSM (JSM ())
+on :: (IsEventTarget t, IsEvent e) => t -> EventName t e -> EventM t e () -> DOM (DOM ())
 on target eventName callback = do
     l <- newListener callback
     addListener target eventName l False
     return $ do
         removeListener target eventName l False
         releaseListener l
+
+onThese :: (IsEventTarget t, IsEvent e) => [(t, EventName t e)] -> EventM t e () -> DOM (DOM ())
+onThese targetsAndEventNames callback = do
+    l <- newListener callback
+    forM_ targetsAndEventNames $ \(target, eventName) ->
+        addListener target eventName l False
+    return (do
+        forM_ targetsAndEventNames (\(target, eventName) ->
+            removeListener target eventName l False)
+        releaseListener l)
 
 event :: EventM t e e
 event = ask
