diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Revision history for reflex-dom-core
 
+## 0.7.0.0
+
+* Breaking change: Remove HasJSContext and MonadJS. This change also removes the `js` type parameter from `Prerender`. Change `Prerender js t m` to `Prerender t m`.
+  * `Reflex.Dom.WebSocket.Foreign.newWebSocket` takes one fewer argument: the first argument used to be a js context
+
 ## 0.6.3.0
 
 * Remove calls to `eval` in Reflex.Dom.Builder.Immediate when compiling with ghcjs
diff --git a/reflex-dom-core.cabal b/reflex-dom-core.cabal
--- a/reflex-dom-core.cabal
+++ b/reflex-dom-core.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.24
 Name: reflex-dom-core
-Version: 0.6.3.0
+Version: 0.7.0.0
 Synopsis: Functional Reactive Web Apps with Reflex
 Description:
   Web applications without callbacks or side-effects.
diff --git a/src/Foreign/JavaScript/TH.hs b/src/Foreign/JavaScript/TH.hs
--- a/src/Foreign/JavaScript/TH.hs
+++ b/src/Foreign/JavaScript/TH.hs
@@ -1,18 +1,13 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE StandaloneDeriving #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
-#ifdef USE_TEMPLATE_HASKELL
-{-# LANGUAGE TemplateHaskell #-}
-#endif
 #ifdef ghcjs_HOST_OS
 {-# LANGUAGE ForeignFunctionInterface #-}
 {-# LANGUAGE JavaScriptFFI #-}
@@ -27,20 +22,14 @@
 import Prelude hiding ((!!))
 import Reflex.Class
 import Reflex.Adjustable.Class
-import Reflex.DynamicWriter.Base
-import Reflex.EventWriter.Base
 import Reflex.Host.Class
-import Reflex.PerformEvent.Base
 import Reflex.PerformEvent.Class
-import Reflex.PostBuild.Base
-import Reflex.Requester.Base
-import Reflex.Query.Base (QueryT (..))
 
 #ifdef USE_TEMPLATE_HASKELL
 import Language.Haskell.TH
 #endif
 
-import GHCJS.DOM.Types (JSContextRef, Node (..), askJSM)
+import GHCJS.DOM.Types (JSContextRef, askJSM)
 #ifdef ghcjs_HOST_OS
 import qualified GHCJS.Buffer as JS
 import GHCJS.DOM.Types (MonadJSM)
@@ -60,75 +49,18 @@
 import Foreign.Ptr
 import Text.Encoding.Z
 #else
-import Control.Lens.Operators ((^.))
-import Data.Word (Word8)
-import GHCJS.DOM.Types (JSVal, MonadJSM (..), liftJSM, runJSM, toJSString, toJSVal)
-import Language.Javascript.JSaddle (Function (..), array, eval, freeFunction, function, js, js1, jss, valBool,
-                                    valIsNull, valIsUndefined, valMakeNumber, valMakeString, valToBool,
-                                    valToNumber, valToText, valUndefined, (!!))
+import GHCJS.DOM.Types (MonadJSM (..), runJSM)
 #endif
 
-import Control.Concurrent
-import Control.Monad
 import Control.Monad.Exception
 import Control.Monad.Fix
 import Control.Monad.IO.Class
 import Control.Monad.Primitive
 import Control.Monad.Reader
 import Control.Monad.Ref
-import Control.Monad.State
-import qualified Control.Monad.State.Strict as Strict
 import Control.Monad.Trans.Control
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as BS
 import Data.Coerce (coerce)
-import Data.Monoid
-import Data.Text (Text)
-import qualified Data.Text as T
 
-class Monad m => HasJSContext m where
-  type JSContextPhantom m :: *
-  askJSContext :: m (JSContextSingleton (JSContextPhantom m))
-
-type HasWebView = HasJSContext
--- Not sure if we should deprecate this {-# DEPRECATED HasWebView "Use HasJSContext" #-}
-
-instance HasJSContext m => HasJSContext (ReaderT r m) where
-  type JSContextPhantom (ReaderT r m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJSContext m => HasJSContext (StateT r m) where
-  type JSContextPhantom (StateT r m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJSContext m => HasJSContext (Strict.StateT r m) where
-  type JSContextPhantom (Strict.StateT r m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJSContext m => HasJSContext (PostBuildT t m) where
-  type JSContextPhantom (PostBuildT t m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance (ReflexHost t, HasJSContext (HostFrame t)) => HasJSContext (PerformEventT t m) where
-  type JSContextPhantom (PerformEventT t m) = JSContextPhantom (HostFrame t)
-  askJSContext = PerformEventT $ lift askJSContext
-
-instance HasJSContext m => HasJSContext (EventWriterT t w m) where
-  type JSContextPhantom (EventWriterT t w m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJSContext m => HasJSContext (DynamicWriterT t w m) where
-  type JSContextPhantom (DynamicWriterT t w m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJSContext m => HasJSContext (RequesterT t request response m) where
-  type JSContextPhantom (RequesterT t request response m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJSContext m => HasJSContext (QueryT t q m) where
-  type JSContextPhantom (QueryT t q m) = JSContextPhantom m
-  askJSContext = QueryT askJSContext
-
 newtype WithJSContextSingleton x m a = WithJSContextSingleton { unWithJSContextSingleton :: ReaderT (JSContextSingleton x) m a } deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadTrans, MonadException, MonadAsyncException)
 
 instance PrimMonad m => PrimMonad (WithJSContextSingleton x m) where
@@ -191,10 +123,6 @@
 runWithJSContextSingleton :: WithJSContextSingleton x m a -> JSContextSingleton x -> m a
 runWithJSContextSingleton = runReaderT . unWithJSContextSingleton
 
-instance (Monad m) => HasJSContext (WithJSContextSingleton x m) where
-  type JSContextPhantom (WithJSContextSingleton x m) = x
-  askJSContext = WithJSContextSingleton ask
-
 instance MonadRef m => MonadRef (WithJSContextSingleton x m) where
   type Ref (WithJSContextSingleton x m) = Ref m
   newRef = lift . newRef
@@ -214,368 +142,9 @@
 -- | A singleton type for a given JSContext; we use this to statically guarantee that different JSContexts don't get mixed up
 newtype JSContextSingleton x = JSContextSingleton { unJSContextSingleton :: JSContextRef }
 
-#ifdef ghcjs_HOST_OS
-type JSFFI_Internal = JS.MutableJSArray -> IO JS.JSVal
-newtype JSFFI = JSFFI JSFFI_Internal
-#else
-newtype JSFFI = JSFFI String
-#endif
-
-data JSFun x = JSFun { unJSFun :: JSRef x
 #ifndef ghcjs_HOST_OS
-    , unJSFunction :: Function
-#endif
-    }
-
-instance ToJS x (JSFun x) where
-  withJS r f = f (unJSFun r)
-
-class IsJSContext x where
-  data JSRef x
-
-class (Monad m, MonadJSM (JSX m), MonadFix (JSX m), MonadJS x (JSX m)) => HasJS x m | m -> x where
-  type JSX m :: * -> *
-  liftJS :: JSX m a -> m a
-
-instance HasJS x m => HasJS x (ReaderT r m) where
-  type JSX (ReaderT r m) = JSX m
-  liftJS = lift . liftJS
-
-instance HasJS x m => HasJS x (PostBuildT t m) where
-  type JSX (PostBuildT t m) = JSX m
-  liftJS = lift . liftJS
-
-instance (HasJS x (HostFrame t), ReflexHost t) => HasJS x (PerformEventT t m) where
-  type JSX (PerformEventT t m) = JSX (HostFrame t)
-  liftJS = PerformEventT . lift . liftJS
-
-instance HasJS x m => HasJS x (DynamicWriterT t w m) where
-  type JSX (DynamicWriterT t w m) = JSX m
-  liftJS = lift . liftJS
-
-instance HasJS x m => HasJS x (EventWriterT t w m) where
-  type JSX (EventWriterT t w m) = JSX m
-  liftJS = lift . liftJS
-
-instance HasJS x m => HasJS x (RequesterT t request response m) where
-  type JSX (RequesterT t request response m) = JSX m
-  liftJS = lift . liftJS
-
-instance HasJS x m => HasJS x (QueryT t q m) where
-  type JSX (QueryT t q m) = JSX m
-  liftJS = lift . liftJS
-
--- | A Monad that is capable of executing JavaScript
-class Monad m => MonadJS x m | m -> x where
-  runJS :: JSFFI -> [JSRef x] -> m (JSRef x)
-  forkJS :: m () -> m ThreadId
-  mkJSUndefined :: m (JSRef x)
-  isJSNull :: JSRef x -> m Bool
-  isJSUndefined :: JSRef x -> m Bool
-  fromJSBool :: JSRef x -> m Bool
-  fromJSString :: JSRef x -> m String
-  fromJSArray :: JSRef x -> m [JSRef x]
-  fromJSUint8Array :: JSRef x -> m ByteString
-  fromJSNumber :: JSRef x -> m Double
-  withJSBool :: Bool -> (JSRef x -> m r) -> m r
-  withJSString :: String -> (JSRef x -> m r) -> m r
-  withJSNumber :: Double -> (JSRef x -> m r) -> m r
-  withJSArray :: [JSRef x] -> (JSRef x -> m r) -> m r
-  withJSUint8Array :: ByteString -> (JSUint8Array x -> m r) -> m r
-  -- | Create a JSFun with zero arguments; should be equilvant to `syncCallback AlwaysRetain True` in GHCJS
-  mkJSFun :: ([JSRef x] -> m (JSRef x)) -> m (JSFun x) --TODO: Support 'this', exceptions
-  freeJSFun :: JSFun x -> m ()
-  setJSProp :: String -> JSRef x -> JSRef x -> m ()
-  getJSProp :: String -> JSRef x -> m (JSRef x)
-  withJSNode :: Node -> (JSRef x -> m r) -> m r
-
-#ifdef ghcjs_HOST_OS
-
-data JSCtx_IO
-type JS' = JSCtx_IO
-
-instance MonadIO m => HasJS JSCtx_IO (WithJSContextSingleton x m) where
-  type JSX (WithJSContextSingleton x m) = IO
-  liftJS = liftIO
-
-instance IsJSContext JSCtx_IO where
-  newtype JSRef JSCtx_IO = JSRef_IO { unJSRef_IO :: JS.JSVal }
-
-instance MonadJS JSCtx_IO IO where
-  runJS (JSFFI f) l = fmap JSRef_IO . f =<< JS.fromListIO (coerce l)
-  forkJS = forkIO
-  mkJSUndefined = return $ JSRef_IO JS.jsUndefined
-  isJSNull (JSRef_IO r) = return $ JS.isNull r
-  isJSUndefined (JSRef_IO r) = return $ JS.isUndefined r
-  fromJSBool (JSRef_IO r) = return $ JS.fromJSBool r
-  fromJSString (JSRef_IO r) = return $ JS.fromJSString $ JS.pFromJSVal r
-  fromJSArray (JSRef_IO r) = fmap coerce $ JS.toListIO $ coerce r
-  fromJSUint8Array (JSRef_IO r) = fmap (JS.toByteString 0 Nothing . JS.createFromArrayBuffer) $ JSArrayBuffer.unsafeFreeze $ JS.pFromJSVal r --TODO: Assert that this is immutable
-  fromJSNumber (JSRef_IO r) = JS.fromJSValUnchecked r
-  withJSBool b f = f $ JSRef_IO $ JS.toJSBool b
-  withJSString s f = f $ JSRef_IO $ JS.pToJSVal $ JS.toJSString s
-  withJSNumber n f = do
-    r <- JS.toJSVal n
-    f $ JSRef_IO r
-  withJSArray l f = do
-    r <- JS.fromListIO $ coerce l
-    f $ JSRef_IO $ coerce r
-  withJSUint8Array payload f = BS.useAsCString payload $ \cStr -> do
-    ba <- extractByteArray cStr $ BS.length payload
-    f $ JSUint8Array $ JSRef_IO ba
-  mkJSFun f = do
-    cb <- JS.syncCallback1' $ \args -> do
-      l <- JS.toListIO $ coerce args
-      JSRef_IO result <- f $ coerce l
-      return result
-    fmap (JSFun . JSRef_IO) $ funWithArguments $ coerce cb
-  freeJSFun (JSFun (JSRef_IO r)) = JS.releaseCallback $ coerce r
-  setJSProp s (JSRef_IO v) (JSRef_IO o) = JS.setProp (JS.toJSString s) v $ coerce o
-  getJSProp s (JSRef_IO o) = do
-    r <- JS.getProp (JS.toJSString s) $ coerce o
-    return $ JSRef_IO r
-  withJSNode n f = f $ JSRef_IO $ unNode n
-
-foreign import javascript unsafe "new Uint8Array($1_1.buf, $1_2, $2)" extractByteArray :: Ptr CChar -> Int -> IO JS.JSVal
-
-foreign import javascript unsafe "function(){ return $1(arguments); }" funWithArguments :: JS.Callback (JS.MutableJSArray -> IO a) -> IO JS.JSVal
-
-#else
-
-data JSCtx_JavaScriptCore x
-type JS' = JSCtx_JavaScriptCore ()
-
-instance IsJSContext (JSCtx_JavaScriptCore x) where
-  newtype JSRef (JSCtx_JavaScriptCore x) = JSRef_JavaScriptCore { unJSRef_JavaScriptCore :: JSVal }
-
-instance MonadIO m => HasJS (JSCtx_JavaScriptCore x) (WithJSContextSingleton x m) where
-  type JSX (WithJSContextSingleton x m) = WithJSContextSingleton x IO
-  liftJS a = do
-    wv <- askJSContext
-    liftIO $ runWithJSContextSingleton a wv
-
-newtype WithJSContext x m a = WithJSContext { unWithJSContext :: ReaderT JSContextRef m a } deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadTrans, MonadException, MonadAsyncException)
-
-runWithJSContext :: WithJSContext x m a -> JSContextRef -> m a
-runWithJSContext = runReaderT . unWithJSContext
-
 instance MonadIO m => MonadJSM (WithJSContextSingleton x m) where
   liftJSM' f = do
-    wv <- askJSContext
+    wv <- WithJSContextSingleton ask
     runJSM f $ unJSContextSingleton wv
-
-instance MonadIO m => MonadJSM (WithJSContext x m) where
-  liftJSM' f =
-    runJSM f =<< WithJSContext ask
-
-lowerWithJSContext :: MonadJSM m => WithJSContext x IO a -> m a
-lowerWithJSContext a = do
-  c <- askJSM
-  liftIO $ runWithJSContext a c
-
-liftWithJSContextSingletonThroughWithJSContext :: (HasJSContext m, MonadJSM m, MonadTrans t, Monad m1)
-                                    => ((t1 -> t m1 a) -> WithJSContext x IO b)
-                                    -> (t1 -> WithJSContextSingleton (JSContextPhantom m) m1 a)
-                                    -> m b
-liftWithJSContextSingletonThroughWithJSContext f a = do
-  wv <- askJSContext
-  lowerWithJSContext $ f $ \b' -> lift $ runWithJSContextSingleton (a b') wv
-
-instance MonadJS (JSCtx_JavaScriptCore x) (WithJSContextSingleton x IO) where
-  forkJS a = do
-    wv <- askJSContext
-    liftIO $ forkIO $ runWithJSContextSingleton a wv
-  mkJSFun a = do
-    wv <- askJSContext
-    lowerWithJSContext $ mkJSFun $ \args -> lift $ runWithJSContextSingleton (a args) wv
-  runJS expr args = lowerWithJSContext $ runJS expr args
-  mkJSUndefined = lowerWithJSContext mkJSUndefined
-  isJSNull = lowerWithJSContext . isJSNull
-  isJSUndefined = lowerWithJSContext . isJSUndefined
-  fromJSBool = lowerWithJSContext . fromJSBool
-  fromJSString = lowerWithJSContext . fromJSString
-  fromJSArray = lowerWithJSContext . fromJSArray
-  fromJSUint8Array = lowerWithJSContext . fromJSUint8Array
-  fromJSNumber = lowerWithJSContext . fromJSNumber
-  freeJSFun = lowerWithJSContext . freeJSFun
-  withJSBool = liftWithJSContextSingletonThroughWithJSContext . withJSBool
-  withJSString = liftWithJSContextSingletonThroughWithJSContext . withJSString
-  withJSNumber = liftWithJSContextSingletonThroughWithJSContext . withJSNumber
-  withJSArray = liftWithJSContextSingletonThroughWithJSContext . withJSArray
-  withJSUint8Array = liftWithJSContextSingletonThroughWithJSContext . withJSUint8Array
-  withJSNode = liftWithJSContextSingletonThroughWithJSContext . withJSNode
-  setJSProp propName valRef objRef = lowerWithJSContext $ setJSProp propName valRef objRef
-  getJSProp propName objRef = lowerWithJSContext $ getJSProp propName objRef
-
-instance MonadJS (JSCtx_JavaScriptCore x) (WithJSContext x IO) where
-  runJS (JSFFI body) args =
-    withJSArray args $ \(JSRef_JavaScriptCore this) -> do
-      result <- liftJSM $ eval ("(function(){ return (" <> body <> "); })") ^. js1 "apply" this
-      return $ JSRef_JavaScriptCore result
-  forkJS a = do
-    c <- askJSM
-    liftIO . forkIO $ runWithJSContext a c
-  mkJSUndefined = return $ JSRef_JavaScriptCore valUndefined
-  isJSNull (JSRef_JavaScriptCore r) = liftJSM $ valIsNull r
-  isJSUndefined (JSRef_JavaScriptCore r) = liftJSM $ valIsUndefined r
-  fromJSBool (JSRef_JavaScriptCore r) = liftJSM $ valToBool r
-  fromJSString (JSRef_JavaScriptCore r) = liftJSM (T.unpack <$> valToText r)
-  withJSBool b a = a $ JSRef_JavaScriptCore (valBool b)
-  withJSString str a = a . JSRef_JavaScriptCore =<< liftJSM (valMakeString $ toJSString str)
-  withJSNumber n a = a . JSRef_JavaScriptCore =<< liftJSM (valMakeNumber n)
-  withJSArray elems a = a . JSRef_JavaScriptCore =<< liftJSM
-    (toJSVal =<< array (map (\(JSRef_JavaScriptCore r) -> r) elems))
-  withJSUint8Array payload f = withJSArrayFromList (BS.unpack payload) $ \x -> do
-    payloadRef <- runJS (JSFFI "new Uint8Array(this[0])") [x]
-    f $ JSUint8Array payloadRef
-  fromJSArray (JSRef_JavaScriptCore a) = liftJSM $ do
-    len <- round <$> (valToNumber =<< (a ^. js "length"))
-    forM [0..len-1] $ fmap JSRef_JavaScriptCore . (a !!)
-  fromJSUint8Array a = do
-    vals <- fromJSArray a
-    doubles <- mapM fromJSNumber vals
-    return $ BS.pack $ map round doubles
-  fromJSNumber (JSRef_JavaScriptCore val) = liftJSM $ valToNumber val
-  mkJSFun a = liftJSM $ do
-    ctx <- askJSM
-    f <- function $ \_ _ args -> liftIO $ void $ runWithJSContext (a $ map JSRef_JavaScriptCore args) ctx
-    fRef <- toJSVal f
-    return $ JSFun (JSRef_JavaScriptCore fRef) f
-  freeJSFun (JSFun _ f) = liftJSM $ freeFunction f
-  setJSProp propName (JSRef_JavaScriptCore valRef) (JSRef_JavaScriptCore objRef) =
-    liftJSM $ objRef ^. jss propName valRef
-  getJSProp propName (JSRef_JavaScriptCore objRef) =
-    JSRef_JavaScriptCore <$> liftJSM (objRef ^. js propName)
-  withJSNode n f = f . JSRef_JavaScriptCore =<< liftJSM (toJSVal n)
-
-#endif
-
-class FromJS x a where
-  fromJS :: MonadJS x m => JSRef x -> m a
-
-instance FromJS x () where
-  fromJS _ = return () --TODO: Should this do some kind of checking for the js value?
-
-instance FromJS x Bool where
-  fromJS = fromJSBool
-
-instance ToJS x Bool where
-  withJS = withJSBool
-
-instance FromJS x String where
-  fromJS = fromJSString
-
-instance FromJS x Text where
-  fromJS s = T.pack <$> fromJSString s
-
-instance FromJS x a => FromJS x (Maybe a) where
-  fromJS x = do
-    n <- isJSNull x
-    if n then return Nothing else Just <$> fromJS x
-
-class ToJS x a where
-  withJS :: MonadJS x m => a -> (JSRef x -> m r) -> m r
-
-instance ToJS x (JSRef x) where
-  withJS r = ($ r)
-
-instance FromJS x (JSRef x) where
-  fromJS = return
-
-instance ToJS x String where
-  withJS = withJSString
-
-instance ToJS x Text where
-  withJS = withJSString . T.unpack
-
-newtype JSArray a = JSArray { unJSArray :: [a] }
-
-instance ToJS x a => ToJS x (JSArray a) where
-  withJS = withJSArrayFromList . unJSArray
-
-instance FromJS x a => FromJS x (JSArray a) where
-  fromJS = fmap JSArray . mapM fromJS <=< fromJSArray
-
-withJSArrayFromList :: (ToJS x a, MonadJS x m) => [a] -> (JSRef x -> m r) -> m r
-withJSArrayFromList as f = go as []
-  where go [] jsRefs = withJSArray (reverse jsRefs) f
-        go (h:t) jsRefs = withJS h $ \hRef -> go t (hRef : jsRefs)
-
-newtype JSUint8Array x = JSUint8Array { unJSUint8Array :: JSRef x }
-
-instance ToJS x (JSUint8Array x) where
-  withJS (JSUint8Array r) = ($ r)
-
-instance FromJS x (JSUint8Array x) where
-  fromJS = return . JSUint8Array
-
-instance ToJS x Word8 where
-  withJS n = withJSNumber $ fromIntegral n --TODO: Check things; throw exceptions
-
-instance ToJS x Int where
-  withJS n = withJSNumber $ fromIntegral n --TODO: Check things; throw exceptions
-
-instance FromJS x Int where
-  fromJS = fmap round . fromJSNumber --TODO: Check things; throw exceptions
-
-instance ToJS x Double where
-  withJS = withJSNumber
-
-instance FromJS x Double where
-  fromJS = fromJSNumber
-
-instance ToJS x Node where
-  withJS = withJSNode
-
-
-#ifdef USE_TEMPLATE_HASKELL
-
-importJS :: Safety -> String -> String -> Q Type -> Q [Dec]
-importJS safety body name qt = do
-  t <- qt
-  let (argTypes, _) = parseType t
-  argNames <- forM argTypes $ \_ -> do
-    arg <- newName "arg"
-    argRef <- newName "argRef"
-    return (arg, argRef)
-  (jsffiDecs, jsffiExp) <- mkJSFFI safety body
-  let go [] = [| runJS $(return jsffiExp) $(listE $ map (varE . snd) argNames) >>= fromJS
-               |]
-      go ((arg, argRef) : args) = [| withJS $(varE arg) $ $(lamE [varP argRef] $ go args) |]
-  e <- lamE (map (varP. fst) argNames) $ go argNames
-  let n = mkName name
-  return $ jsffiDecs ++
-    [ SigD n t
-    , ValD (VarP n) (NormalB e) []
-    ]
-
-mkJSFFI :: Safety -> String -> Q ([Dec], Exp)
-#ifdef ghcjs_HOST_OS
-mkJSFFI safety body = do
-  -- n <- newName "jsffi" --TODO: Should use newName, but that doesn't seem to work with ghcjs
-  l <- location
-  n <- newName $ "jsffi_" <> zEncodeString (loc_package l <> ":" <> loc_module l) <> "_" <> show (abs (hash (show safety, body)))
-  t <- [t| JSFFI_Internal |]
-  let wrappedBody = "(function(){ return (" <> body <> "); }).apply($1)"
-  let decs = [ForeignD $ ImportF JavaScript safety wrappedBody n t]
-  e <- [| JSFFI $(varE n) |]
-  return (decs, e)
-#else
-mkJSFFI _ body = do
-  e <- [| JSFFI body |]
-  return ([], e)
-#endif
-
-parseType :: Type -> ([Type], Type)
-parseType (ForallT _ [AppT (AppT (ConT monadJs) (VarT _)) (VarT m)] funType)
-  | monadJs == ''MonadJS = go funType
-  where go t = case t of
-          AppT (AppT ArrowT arg) t' ->
-            let (args, result) = go t'
-            in (arg : args, result)
-          AppT (VarT m') result
-            | m' == m -> ([], result)
-          _ -> error $ "parseType: can't parse type " <> show t
-parseType t = error $ "parseType: can't parse type " <> show t
-
 #endif
diff --git a/src/Reflex/Dom/Builder/Hydratable.hs b/src/Reflex/Dom/Builder/Hydratable.hs
--- a/src/Reflex/Dom/Builder/Hydratable.hs
+++ b/src/Reflex/Dom/Builder/Hydratable.hs
@@ -15,7 +15,6 @@
 import Control.Monad.Trans.Control
 import Data.Coerce
 import qualified Data.Map as Map
-import Foreign.JavaScript.TH
 #ifndef ghcjs_HOST_OS
 import GHCJS.DOM.Types (MonadJSM (..))
 #endif
@@ -101,14 +100,6 @@
     lift $ selectElement cfg' $ runHydratableT child
 
 instance HasDocument m => HasDocument (HydratableT m)
-
-instance HasJSContext m => HasJSContext (HydratableT m) where
-  type JSContextPhantom (HydratableT m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJS js m => HasJS js (HydratableT m) where
-  type JSX (HydratableT m) = JSX m
-  liftJS = lift . liftJS
 
 instance DomRenderHook t m => DomRenderHook t (HydratableT m) where
   withRenderHook f = HydratableT . withRenderHook f . runHydratableT
diff --git a/src/Reflex/Dom/Builder/Immediate.hs b/src/Reflex/Dom/Builder/Immediate.hs
--- a/src/Reflex/Dom/Builder/Immediate.hs
+++ b/src/Reflex/Dom/Builder/Immediate.hs
@@ -141,7 +141,6 @@
 import Data.Maybe
 import Data.Monoid ((<>))
 import Data.Some (Some(..))
-import Data.GADT.Compare (GCompare)
 import Data.String (IsString)
 import Data.Text (Text)
 import Foreign.JavaScript.Internal.Utils
@@ -2207,10 +2206,6 @@
   {-# INLINABLE newEventWithLazyTriggerWithOnComplete #-}
   newEventWithLazyTriggerWithOnComplete f = DomRenderHookT . lift $ newEventWithLazyTriggerWithOnComplete f
 
-instance HasJSContext m => HasJSContext (HydrationDomBuilderT s t m) where
-  type JSContextPhantom (HydrationDomBuilderT s t m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
 instance MonadRef m => MonadRef (HydrationDomBuilderT s t m) where
   type Ref (HydrationDomBuilderT s t m) = Ref m
   {-# INLINABLE newRef #-}
@@ -2223,10 +2218,6 @@
 instance MonadAtomicRef m => MonadAtomicRef (HydrationDomBuilderT s t m) where
   {-# INLINABLE atomicModifyRef #-}
   atomicModifyRef r = lift . atomicModifyRef r
-
-instance (HasJS x m, ReflexHost t) => HasJS x (HydrationDomBuilderT s t m) where
-  type JSX (HydrationDomBuilderT s t m) = JSX m
-  liftJS = lift . liftJS
 
 type family EventType en where
   EventType 'AbortTag = UIEvent
diff --git a/src/Reflex/Dom/Builder/InputDisabled.hs b/src/Reflex/Dom/Builder/InputDisabled.hs
--- a/src/Reflex/Dom/Builder/InputDisabled.hs
+++ b/src/Reflex/Dom/Builder/InputDisabled.hs
@@ -15,7 +15,6 @@
 import Control.Monad.Trans.Control
 import Data.Coerce
 import qualified Data.Map as Map
-import Foreign.JavaScript.TH
 #ifndef ghcjs_HOST_OS
 import GHCJS.DOM.Types (MonadJSM (..))
 #endif
@@ -101,14 +100,6 @@
     lift $ selectElement cfg' $ runInputDisabledT child
 
 instance HasDocument m => HasDocument (InputDisabledT m)
-
-instance HasJSContext m => HasJSContext (InputDisabledT m) where
-  type JSContextPhantom (InputDisabledT m) = JSContextPhantom m
-  askJSContext = lift askJSContext
-
-instance HasJS js m => HasJS js (InputDisabledT m) where
-  type JSX (InputDisabledT m) = JSX m
-  liftJS = lift . liftJS
 
 instance DomRenderHook t m => DomRenderHook t (InputDisabledT m) where
   withRenderHook f = InputDisabledT . withRenderHook f . runInputDisabledT
diff --git a/src/Reflex/Dom/Old.hs b/src/Reflex/Dom/Old.hs
--- a/src/Reflex/Dom/Old.hs
+++ b/src/Reflex/Dom/Old.hs
@@ -63,7 +63,6 @@
 import Data.Set (Set)
 import qualified Data.Set as Set
 import Data.Text (Text)
-import Foreign.JavaScript.TH
 import qualified GHCJS.DOM.Element as Element
 import GHCJS.DOM.EventM (EventM)
 import GHCJS.DOM.NamedNodeMap as NNM
@@ -118,8 +117,6 @@
   , DOM.MonadJSM (Performable m)
 #endif
   , TriggerEvent t m
-  , HasJSContext m
-  , HasJSContext (Performable m)
   , HasDocument m
   , MonadRef m
   , Ref m ~ Ref IO
diff --git a/src/Reflex/Dom/Prerender.hs b/src/Reflex/Dom/Prerender.hs
--- a/src/Reflex/Dom/Prerender.hs
+++ b/src/Reflex/Dom/Prerender.hs
@@ -45,19 +45,17 @@
 import qualified GHCJS.DOM.Node as Node
 import qualified GHCJS.DOM.Types as DOM
 
-type PrerenderClientConstraint js t m =
+type PrerenderClientConstraint t m =
   ( DomBuilder t m
   , DomBuilderSpace m ~ GhcjsDomSpace
   , DomRenderHook t m
   , HasDocument m
   , TriggerEvent t m
-  , PrerenderBaseConstraints js t m
+  , PrerenderBaseConstraints t m
   )
 
-type PrerenderBaseConstraints js t m =
-  ( HasJSContext (Performable m)
-  , HasJSContext m
-  , MonadFix m
+type PrerenderBaseConstraints t m =
+  ( MonadFix m
   , MonadHold t m
   , MonadJSM (Performable m)
   , MonadJSM m
@@ -70,18 +68,16 @@
   , PrimMonad m
   , Ref (Performable m) ~ IORef
   , Ref m ~ IORef
-  , HasJS js m
-  , HasJS js (Performable m)
   )
 
 -- | Render the first widget on the server, and the second on the client. The
 -- hydration builder will run *both* widgets.
 prerender_
-  :: (Functor m, Reflex t, Prerender js t m)
+  :: (Functor m, Reflex t, Prerender t m)
   => m () ->  Client m () -> m ()
 prerender_ server client = void $ prerender server client
 
-class (PrerenderClientConstraint js t (Client m), Client (Client m) ~ Client m, Prerender js t (Client m)) => Prerender js t m | m -> t js where
+class (PrerenderClientConstraint t (Client m), Client (Client m) ~ Client m, Prerender t (Client m)) => Prerender t m | m -> t where
   -- | Monad in which the client widget is built
   type Client m :: * -> *
   -- | Render the first widget on the server, and the second on the client. The
@@ -89,11 +85,11 @@
   -- switchover time.
   prerender :: m a -> Client m a -> m (Dynamic t a)
 
-instance (ReflexHost t, Adjustable t m, PrerenderBaseConstraints js t m) => Prerender js t (HydrationDomBuilderT GhcjsDomSpace t m) where
+instance (ReflexHost t, Adjustable t m, PrerenderBaseConstraints t m) => Prerender t (HydrationDomBuilderT GhcjsDomSpace t m) where
   type Client (HydrationDomBuilderT GhcjsDomSpace t m) = HydrationDomBuilderT GhcjsDomSpace t m
   prerender _ client = pure <$> client
 
-instance (Adjustable t m, PrerenderBaseConstraints js t m, ReflexHost t) => Prerender js t (HydrationDomBuilderT HydrationDomSpace t m) where
+instance (Adjustable t m, PrerenderBaseConstraints t m, ReflexHost t) => Prerender t (HydrationDomBuilderT HydrationDomSpace t m) where
   -- | PostBuildT is needed here because we delay running the client builder
   -- until after switchover, at which point the postBuild of @m@ has already fired
   type Client (HydrationDomBuilderT HydrationDomSpace t m) = PostBuildT t (HydrationDomBuilderT GhcjsDomSpace t m)
@@ -132,14 +128,14 @@
         insertBefore df =<< deleteToPrerenderEnd doc
     holdDyn a0 a'
 
-newtype UnrunnableT js t m a = UnrunnableT (ReaderT Void m a)
+newtype UnrunnableT t m a = UnrunnableT (ReaderT Void m a)
   deriving (Functor, Applicative, Monad, MonadTrans)
 
-unrunnable :: UnrunnableT js t m a
+unrunnable :: UnrunnableT t m a
 unrunnable = UnrunnableT $ ReaderT $ \case {}
 
-instance (Reflex t, Monad m) => DomBuilder t (UnrunnableT js t m) where
-  type DomBuilderSpace (UnrunnableT js t m) = GhcjsDomSpace
+instance (Reflex t, Monad m) => DomBuilder t (UnrunnableT t m) where
+  type DomBuilderSpace (UnrunnableT t m) = GhcjsDomSpace
   textNode _ = unrunnable
   commentNode _ = unrunnable
   element _ _ _ = unrunnable
@@ -148,106 +144,79 @@
   selectElement _ _ = unrunnable
   placeRawElement _ = unrunnable
   wrapRawElement _ _ = unrunnable
-instance (Reflex t, Monad m) => NotReady t (UnrunnableT js t m) where
+instance (Reflex t, Monad m) => NotReady t (UnrunnableT t m) where
   notReadyUntil _ = unrunnable
   notReady = unrunnable
-instance (Reflex t, Monad m) => Adjustable t (UnrunnableT js t m) where
+instance (Reflex t, Monad m) => Adjustable t (UnrunnableT t m) where
   runWithReplace _ _ = unrunnable
   traverseIntMapWithKeyWithAdjust _ _ _ = unrunnable
   traverseDMapWithKeyWithAdjust _ _ _ = unrunnable
   traverseDMapWithKeyWithAdjustWithMove _ _ _ = unrunnable
-instance (Reflex t, Monad m) => PerformEvent t (UnrunnableT js t m) where
-  type Performable (UnrunnableT js t m) = UnrunnableT js t m
+instance (Reflex t, Monad m) => PerformEvent t (UnrunnableT t m) where
+  type Performable (UnrunnableT t m) = UnrunnableT t m
   performEvent _ = unrunnable
   performEvent_ _ = unrunnable
-instance Monad m => MonadRef (UnrunnableT js t m) where
-  type Ref (UnrunnableT js t m) = Ref IO
+instance Monad m => MonadRef (UnrunnableT t m) where
+  type Ref (UnrunnableT t m) = Ref IO
   newRef _ = unrunnable
   readRef _ = unrunnable
   writeRef _ _ = unrunnable
-instance Monad m => MonadAtomicRef (UnrunnableT js t m) where
+instance Monad m => MonadAtomicRef (UnrunnableT t m) where
   atomicModifyRef _ _ = unrunnable
-instance Monad m => HasDocument (UnrunnableT js t m) where
+instance Monad m => HasDocument (UnrunnableT t m) where
   askDocument = unrunnable
-instance Monad m => HasJSContext (UnrunnableT js t m) where
-  type JSContextPhantom (UnrunnableT js t m) = ()
-  askJSContext = unrunnable
-instance Monad m => HasJS JS' (UnrunnableT js t m) where
-  type JSX (UnrunnableT js t m) = UnrunnableT js t m
-  liftJS _ = unrunnable
-instance Monad m => MonadJS JS' (UnrunnableT js t m) where
-  runJS _ _ = unrunnable
-  forkJS _ = unrunnable
-  mkJSUndefined = unrunnable
-  isJSNull _ = unrunnable
-  isJSUndefined _ = unrunnable
-  fromJSBool _ = unrunnable
-  fromJSString _ = unrunnable
-  fromJSArray _ = unrunnable
-  fromJSUint8Array _ = unrunnable
-  fromJSNumber _ = unrunnable
-  withJSBool _ _ = unrunnable
-  withJSString _ _ = unrunnable
-  withJSNumber _ _ = unrunnable
-  withJSArray _ _ = unrunnable
-  withJSUint8Array _ _ = unrunnable
-  mkJSFun _ = unrunnable
-  freeJSFun _ = unrunnable
-  setJSProp _ _ _ = unrunnable
-  getJSProp _ _ = unrunnable
-  withJSNode _ _ = unrunnable
-instance Monad m => TriggerEvent t (UnrunnableT js t m) where
+instance Monad m => TriggerEvent t (UnrunnableT t m) where
   newTriggerEvent = unrunnable
   newTriggerEventWithOnComplete = unrunnable
   newEventWithLazyTriggerWithOnComplete _ = unrunnable
-instance Monad m => MonadReflexCreateTrigger t (UnrunnableT js t m) where
+instance Monad m => MonadReflexCreateTrigger t (UnrunnableT t m) where
   newEventWithTrigger _ = unrunnable
   newFanEventWithTrigger _ = unrunnable
-instance Monad m => MonadFix (UnrunnableT js t m) where
+instance Monad m => MonadFix (UnrunnableT t m) where
   mfix _ = unrunnable
-instance (Monad m, MonadHold t m) => MonadHold t (UnrunnableT js t m) where
+instance (Monad m, MonadHold t m) => MonadHold t (UnrunnableT t m) where
   hold _ _ = unrunnable
   holdDyn _ _ = unrunnable
   holdIncremental _ _ = unrunnable
   buildDynamic _ _ = unrunnable
   headE _ = unrunnable
   now = unrunnable
-instance Monad m => MonadSample t (UnrunnableT js t m) where
+instance Monad m => MonadSample t (UnrunnableT t m) where
   sample _ = unrunnable
-instance Monad m => MonadIO (UnrunnableT js t m) where
+instance Monad m => MonadIO (UnrunnableT t m) where
   liftIO _ = unrunnable
 #ifndef ghcjs_HOST_OS
-instance Monad m => MonadJSM (UnrunnableT js t m) where
+instance Monad m => MonadJSM (UnrunnableT t m) where
   liftJSM' _ = unrunnable
 #endif
-instance (Reflex t, Monad m) => PostBuild t (UnrunnableT js t m) where
+instance (Reflex t, Monad m) => PostBuild t (UnrunnableT t m) where
   getPostBuild = unrunnable
-instance Monad m => PrimMonad (UnrunnableT js t m) where
-  type PrimState (UnrunnableT js t m) = PrimState IO
+instance Monad m => PrimMonad (UnrunnableT t m) where
+  type PrimState (UnrunnableT t m) = PrimState IO
   primitive _ = unrunnable
-instance (Reflex t, Monad m) => DomRenderHook t (UnrunnableT js t m) where
+instance (Reflex t, Monad m) => DomRenderHook t (UnrunnableT t m) where
   withRenderHook _ _ = unrunnable
   requestDomAction _ = unrunnable
   requestDomAction_ _ = unrunnable
-instance (Reflex t, Monad m, MonadHold t m) => Prerender JS' t (UnrunnableT js t m) where
-  type Client (UnrunnableT js t m) = UnrunnableT js t m
+instance (Reflex t, Monad m, MonadHold t m) => Prerender t (UnrunnableT t m) where
+  type Client (UnrunnableT t m) = UnrunnableT t m
   prerender _ _ = unrunnable
 
-instance (SupportsStaticDomBuilder t m) => Prerender JS' t (StaticDomBuilderT t m) where
-  type Client (StaticDomBuilderT t m) = UnrunnableT JS' t m
+instance (SupportsStaticDomBuilder t m) => Prerender t (StaticDomBuilderT t m) where
+  type Client (StaticDomBuilderT t m) = UnrunnableT t m
   prerender server _ = do
     _ <- commentNode $ CommentNodeConfig startMarker Nothing
     a <- server
     _ <- commentNode $ CommentNodeConfig endMarker Nothing
     pure $ pure a
 
-instance (Prerender js t m, Monad m) => Prerender js t (ReaderT r m) where
+instance (Prerender t m, Monad m) => Prerender t (ReaderT r m) where
   type Client (ReaderT r m) = ReaderT r (Client m)
   prerender server client = do
     r <- ask
     lift $ prerender (runReaderT server r) (runReaderT client r)
 
-instance (Prerender js t m, Monad m, Reflex t, MonadFix m, Monoid w) => Prerender js t (DynamicWriterT t w m) where
+instance (Prerender t m, Monad m, Reflex t, MonadFix m, Monoid w) => Prerender t (DynamicWriterT t w m) where
   type Client (DynamicWriterT t w m) = DynamicWriterT t w (Client m)
   prerender server client = do
     x <- lift $ prerender (runDynamicWriterT server) (runDynamicWriterT client)
@@ -256,7 +225,7 @@
     tellDyn w
     pure a
 
-instance (Prerender js t m, Monad m, Reflex t, Semigroup w) => Prerender js t (EventWriterT t w m) where
+instance (Prerender t m, Monad m, Reflex t, Semigroup w) => Prerender t (EventWriterT t w m) where
   type Client (EventWriterT t w m) = EventWriterT t w (Client m)
   prerender server client = do
     x <- lift $ prerender (runEventWriterT server) (runEventWriterT client)
@@ -265,7 +234,7 @@
     tellEvent w
     pure a
 
-instance (Prerender js t m, MonadFix m, Reflex t) => Prerender js t (RequesterT t request response m) where
+instance (Prerender t m, MonadFix m, Reflex t) => Prerender t (RequesterT t request response m) where
   type Client (RequesterT t request response m) = RequesterT t request response (Client m)
   prerender server client = mdo
     let fannedResponses = fanInt responses
@@ -277,7 +246,7 @@
     responses <- fmap (fmapCheap unMultiEntry) $ requesting' $ fmapCheap multiEntry $ switchPromptlyDyn requestsDyn
     return result
 
-instance (Prerender js t m, Monad m, Reflex t, MonadFix m, Group q, Additive q, Query q, Eq q) => Prerender js t (QueryT t q m) where
+instance (Prerender t m, Monad m, Reflex t, MonadFix m, Group q, Additive q, Query q, Eq q) => Prerender t (QueryT t q m) where
   type Client (QueryT t q m) = QueryT t q (Client m)
   prerender server client = mdo
     result <- queryDyn query
@@ -286,15 +255,15 @@
         query = incrementalToDynamic =<< inc -- Can we avoid the incrementalToDynamic?
     pure a
 
-instance (Prerender js t m, Monad m) => Prerender js t (InputDisabledT m) where
+instance (Prerender t m, Monad m) => Prerender t (InputDisabledT m) where
   type Client (InputDisabledT m) = InputDisabledT (Client m)
   prerender (InputDisabledT server) (InputDisabledT client) = InputDisabledT $ prerender server client
 
-instance (Prerender js t m, Monad m) => Prerender js t (HydratableT m) where
+instance (Prerender t m, Monad m) => Prerender t (HydratableT m) where
   type Client (HydratableT m) = HydratableT (Client m)
   prerender (HydratableT server) (HydratableT client) = HydratableT $ prerender server client
 
-instance (Prerender js t m, Monad m, ReflexHost t) => Prerender js t (PostBuildT t m) where
+instance (Prerender t m, Monad m, ReflexHost t) => Prerender t (PostBuildT t m) where
   type Client (PostBuildT t m) = PostBuildT t (Client m)
   prerender server client = PostBuildT $ do
     pb <- ask
diff --git a/src/Reflex/Dom/WebSocket.hs b/src/Reflex/Dom/WebSocket.hs
--- a/src/Reflex/Dom/WebSocket.hs
+++ b/src/Reflex/Dom/WebSocket.hs
@@ -31,7 +31,6 @@
 import Prelude hiding (all, concat, concatMap, div, mapM, mapM_, sequence, span)
 
 import Reflex.Class
-import Reflex.Dom.Class
 import Reflex.Dom.WebSocket.Foreign
 import Reflex.PerformEvent.Class
 import Reflex.PostBuild.Class
@@ -83,12 +82,11 @@
                                                 )
                   }
 
-webSocket :: (MonadJSM m, MonadJSM (Performable m), HasJSContext m, PerformEvent t m, TriggerEvent t m, PostBuild t m, IsWebSocketMessage a) => Text -> WebSocketConfig t a -> m (WebSocket t)
+webSocket :: (MonadJSM m, MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, PostBuild t m, IsWebSocketMessage a) => Text -> WebSocketConfig t a -> m (WebSocket t)
 webSocket url config = webSocket' url config onBSMessage
 
-webSocket' :: (MonadJSM m, MonadJSM (Performable m), HasJSContext m, PerformEvent t m, TriggerEvent t m, PostBuild t m, IsWebSocketMessage a) => Text -> WebSocketConfig t a -> (Either ByteString JSVal -> JSM b) -> m (RawWebSocket t b)
+webSocket' :: (MonadJSM m, MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, PostBuild t m, IsWebSocketMessage a) => Text -> WebSocketConfig t a -> (Either ByteString JSVal -> JSM b) -> m (RawWebSocket t b)
 webSocket' url config onRawMessage = do
-  wv <- fmap unJSContextSingleton askJSContext
   (eRecv, onMessage) <- newTriggerEvent
   currentSocketRef <- liftIO $ newIORef Nothing
   (eOpen, triggerEOpen) <- newTriggerEventWithOnComplete
@@ -106,7 +104,7 @@
           liftIO $ threadDelay 1000000
           start
       start = do
-        ws <- newWebSocket wv url (_webSocketConfig_protocols config) (onRawMessage >=> liftIO . onMessage) (liftIO onOpen) (liftIO onError) onClose
+        ws <- newWebSocket url (_webSocketConfig_protocols config) (onRawMessage >=> liftIO . onMessage) (liftIO onOpen) (liftIO onError) onClose
         liftIO $ writeIORef currentSocketRef $ Just ws
         return ()
   performEvent_ . (liftJSM start <$) =<< getPostBuild
@@ -136,10 +134,10 @@
     unless success $ atomically $ unGetTQueue payloadQueue payload
   return $ RawWebSocket eRecv eOpen eError eClose
 
-textWebSocket :: (IsWebSocketMessage a, MonadJSM m, MonadJSM (Performable m), HasJSContext m, PostBuild t m, TriggerEvent t m, PerformEvent t m, MonadHold t m, Reflex t) => Text -> WebSocketConfig t a -> m (RawWebSocket t Text)
+textWebSocket :: (IsWebSocketMessage a, MonadJSM m, MonadJSM (Performable m), PostBuild t m, TriggerEvent t m, PerformEvent t m, MonadHold t m, Reflex t) => Text -> WebSocketConfig t a -> m (RawWebSocket t Text)
 textWebSocket url cfg = webSocket' url cfg (either (return . decodeUtf8) fromJSValUnchecked)
 
-jsonWebSocket :: (ToJSON a, FromJSON b, MonadJSM m, MonadJSM (Performable m), HasJSContext m, PostBuild t m, TriggerEvent t m, PerformEvent t m, MonadHold t m, Reflex t) => Text -> WebSocketConfig t a -> m (RawWebSocket t (Maybe b))
+jsonWebSocket :: (ToJSON a, FromJSON b, MonadJSM m, MonadJSM (Performable m), PostBuild t m, TriggerEvent t m, PerformEvent t m, MonadHold t m, Reflex t) => Text -> WebSocketConfig t a -> m (RawWebSocket t (Maybe b))
 jsonWebSocket url cfg = do
   ws <- textWebSocket url $ cfg { _webSocketConfig_send = fmap (decodeUtf8 . toStrict . encode) <$> _webSocketConfig_send cfg }
   return ws { _webSocket_recv = jsonDecode . textToJSString <$> _webSocket_recv ws }
diff --git a/src/Reflex/Dom/WebSocket/Foreign.hs b/src/Reflex/Dom/WebSocket/Foreign.hs
--- a/src/Reflex/Dom/WebSocket/Foreign.hs
+++ b/src/Reflex/Dom/WebSocket/Foreign.hs
@@ -53,15 +53,14 @@
 closeWebSocket (JSWebSocket ws) code reason = DOM.close ws (Just code) (Just reason)
 
 newWebSocket
-  :: a
-  -> Text -- url
+  :: Text -- url
   -> [Text] -- protocols
   -> (Either ByteString JSVal -> JSM ()) -- onmessage
   -> JSM () -- onopen
   -> JSM () -- onerror
   -> ((Bool, Word, Text) -> JSM ()) -- onclose
   -> JSM JSWebSocket
-newWebSocket _ url protocols onMessage onOpen onError onClose = do
+newWebSocket url protocols onMessage onOpen onError onClose = do
   let onOpenWrapped = fun $ \_ _ _ -> onOpen
       onErrorWrapped = fun $ \_ _ _ -> onError
       onCloseWrapped = fun $ \_ _ (e:_) -> do
diff --git a/src/Reflex/Dom/WebSocket/Query.hs b/src/Reflex/Dom/WebSocket/Query.hs
--- a/src/Reflex/Dom/WebSocket/Query.hs
+++ b/src/Reflex/Dom/WebSocket/Query.hs
@@ -8,11 +8,10 @@
 import Data.Aeson
 import Reflex
 import Reflex.Dom.WebSocket
-import Foreign.JavaScript.TH
 import Data.Maybe
 import Language.Javascript.JSaddle.Types (MonadJSM)
 
-runWebSocketQuery :: (MonadJSM m, MonadJSM (Performable m), HasJSContext m, PostBuild t m, TriggerEvent t m, PerformEvent t m, MonadHold t m, Reflex t, ToJSON q, MonadFix m, Query q, FromJSON (QueryResult q), Additive q, Group q, Eq q)
+runWebSocketQuery :: (MonadJSM m, MonadJSM (Performable m), PostBuild t m, TriggerEvent t m, PerformEvent t m, MonadHold t m, Reflex t, ToJSON q, MonadFix m, Query q, FromJSON (QueryResult q), Additive q, Group q, Eq q)
                   => QueryT t q m a
                   -> Text -- ^ WebSocket url
                   -> m a
diff --git a/src/Reflex/Dom/Widget/Input.hs b/src/Reflex/Dom/Widget/Input.hs
--- a/src/Reflex/Dom/Widget/Input.hs
+++ b/src/Reflex/Dom/Widget/Input.hs
@@ -33,9 +33,6 @@
 import Data.Semigroup
 import Data.Text (Text)
 import qualified Data.Text as T
-import qualified GHCJS.DOM.GlobalEventHandlers as Events
-import GHCJS.DOM.EventM (on)
-import qualified GHCJS.DOM.FileList as FileList
 import GHCJS.DOM.HTMLInputElement (HTMLInputElement)
 import GHCJS.DOM.HTMLTextAreaElement (HTMLTextAreaElement)
 import GHCJS.DOM.Types (MonadJSM, File, uncheckedCastTo)
diff --git a/src/Reflex/Dom/Xhr.hs b/src/Reflex/Dom/Xhr.hs
--- a/src/Reflex/Dom/Xhr.hs
+++ b/src/Reflex/Dom/Xhr.hs
@@ -239,7 +239,7 @@
 -- the XHR connection), and will pass an exception ('XhrException') to the
 -- continuation if the connection cannot be made (or is aborted).
 newXMLHttpRequestWithError
-    :: (HasJSContext m, MonadJSM m, IsXhrPayload a)
+    :: (MonadJSM m, IsXhrPayload a)
     => XhrRequest a
     -- ^ The request to make.
     -> (Either XhrException XhrResponse -> JSM ())
@@ -295,7 +295,7 @@
   L.dropWhileEnd T.null $ T.splitOn (T.pack "\r\n") s
   where stripBoth (txt1, txt2) = (CI.mk $ T.strip txt1, T.strip $ T.drop 1 txt2)
 
-newXMLHttpRequest :: (HasJSContext m, MonadJSM m, IsXhrPayload a) => XhrRequest a -> (XhrResponse -> JSM ()) -> m XMLHttpRequest
+newXMLHttpRequest :: (MonadJSM m, IsXhrPayload a) => XhrRequest a -> (XhrResponse -> JSM ()) -> m XMLHttpRequest
 newXMLHttpRequest req cb = newXMLHttpRequestWithError req $ mapM_ cb
 
 -- | Given Event of requests, issue them when the Event fires.
@@ -304,17 +304,17 @@
 -- The request is processed asynchronously, therefore handling does
 -- not block or cause a delay while creating the connection.
 performRequestAsyncWithError
-    :: (MonadJSM (Performable m), HasJSContext (Performable m), PerformEvent t m, TriggerEvent t m, IsXhrPayload a)
+    :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, IsXhrPayload a)
     => Event t (XhrRequest a)
     -> m (Event t (Either XhrException XhrResponse))
 performRequestAsyncWithError = performRequestAsync' newXMLHttpRequestWithError . fmap return
 
 -- | Given Event of request, issue them when the Event fires.  Returns Event of corresponding response.
-performRequestAsync :: (MonadJSM (Performable m), HasJSContext (Performable m), PerformEvent t m, TriggerEvent t m, IsXhrPayload a) => Event t (XhrRequest a) -> m (Event t XhrResponse)
+performRequestAsync :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, IsXhrPayload a) => Event t (XhrRequest a) -> m (Event t XhrResponse)
 performRequestAsync = performRequestAsync' newXMLHttpRequest . fmap return
 
 -- | Given Event with an action that creates a request, build and issue the request when the Event fires.  Returns Event of corresponding response.
-performMkRequestAsync :: (MonadJSM (Performable m), HasJSContext (Performable m), PerformEvent t m, TriggerEvent t m, IsXhrPayload a) => Event t (Performable m (XhrRequest a)) -> m (Event t XhrResponse)
+performMkRequestAsync :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, IsXhrPayload a) => Event t (Performable m (XhrRequest a)) -> m (Event t XhrResponse)
 performMkRequestAsync = performRequestAsync' newXMLHttpRequest
 
 performRequestAsync' :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m) => (XhrRequest p -> (a -> JSM ()) -> Performable m XMLHttpRequest) -> Event t (Performable m (XhrRequest p)) -> m (Event t a)
@@ -333,16 +333,16 @@
 -- Order of request execution and completion is not guaranteed, but
 -- order of creation and the collection result is preserved.
 performRequestsAsyncWithError
-    :: (MonadJSM (Performable m), HasJSContext (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f, IsXhrPayload a)
+    :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f, IsXhrPayload a)
     => Event t (f (XhrRequest a)) -> m (Event t (f (Either XhrException XhrResponse)))
 performRequestsAsyncWithError = performRequestsAsync' newXMLHttpRequestWithError . fmap return
 
 -- | Issues a collection of requests when the supplied Event fires.  When ALL requests from a given firing complete, the results are collected and returned via the return Event.
-performRequestsAsync :: (MonadJSM (Performable m), HasJSContext (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f, IsXhrPayload a) => Event t (f (XhrRequest a)) -> m (Event t (f XhrResponse))
+performRequestsAsync :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f, IsXhrPayload a) => Event t (f (XhrRequest a)) -> m (Event t (f XhrResponse))
 performRequestsAsync = performRequestsAsync' newXMLHttpRequest . fmap return
 
 -- | Builds and issues a collection of requests when the supplied Event fires.  When ALL requests from a given firing complete, the results are collected and returned via the return Event.
-performMkRequestsAsync :: (MonadJSM (Performable m), HasJSContext (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f, IsXhrPayload a) => Event t (Performable m (f (XhrRequest a))) -> m (Event t (f XhrResponse))
+performMkRequestsAsync :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f, IsXhrPayload a) => Event t (Performable m (f (XhrRequest a))) -> m (Event t (f XhrResponse))
 performMkRequestsAsync = performRequestsAsync' newXMLHttpRequest
 
 performRequestsAsync' :: (MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, Traversable f) => (XhrRequest b -> (a -> JSM ()) -> Performable m XMLHttpRequest) -> Event t (Performable m (f (XhrRequest b))) -> m (Event t (f a))
@@ -356,7 +356,7 @@
   return ()
 
 -- | Simplified interface to "GET" URLs and return decoded results.
-getAndDecode :: (MonadIO m, MonadJSM (Performable m), PerformEvent t m, HasJSContext (Performable m), TriggerEvent t m, FromJSON a) => Event t Text -> m (Event t (Maybe a))
+getAndDecode :: (MonadIO m, MonadJSM (Performable m), PerformEvent t m, TriggerEvent t m, FromJSON a) => Event t Text -> m (Event t (Maybe a))
 getAndDecode url = do
   r <- performRequestAsync $ fmap (\x -> XhrRequest "GET" x def) url
   return $ fmap decodeXhrResponse r
diff --git a/src/Reflex/Dom/Xhr/FormData.hs b/src/Reflex/Dom/Xhr/FormData.hs
--- a/src/Reflex/Dom/Xhr/FormData.hs
+++ b/src/Reflex/Dom/Xhr/FormData.hs
@@ -26,7 +26,7 @@
 
 -- | Performs a POST request with the provided FormData payload
 postForms
-  :: ( IsBlob blob, HasJSContext (Performable m), MonadJSM (Performable m)
+  :: ( IsBlob blob, MonadJSM (Performable m)
      , PerformEvent t m, TriggerEvent t m
      , Traversable f)
   => Text -- ^ The target url
diff --git a/test/hydration.hs b/test/hydration.hs
--- a/test/hydration.hs
+++ b/test/hydration.hs
@@ -166,11 +166,11 @@
         r <- m
         putStrLnDebug "after"
         return r
-      testWidgetStatic :: WD b -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ()) -> WD b
+      testWidgetStatic :: WD b -> (forall m js. TestWidget (SpiderTimeline Global) m => m ()) -> WD b
       testWidgetStatic = testWidgetStaticDebug withDebugging
-      testWidget :: WD () -> WD b -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ()) -> WD b
+      testWidget :: WD () -> WD b -> (forall m js. TestWidget (SpiderTimeline Global) m => m ()) -> WD b
       testWidget = testWidgetDebug True withDebugging
-      testWidget' :: WD a -> (a -> WD b) -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ()) -> WD b
+      testWidget' :: WD a -> (a -> WD b) -> (forall m js. TestWidget (SpiderTimeline Global) m => m ()) -> WD b
       testWidget' = testWidgetDebug' True withDebugging
   session' "text" $ do
     it "works" $ runWD $ do
@@ -1653,7 +1653,7 @@
     , _selenium_stopServer = stopServer
     }
 
-triggerEventWithChan :: (Reflex t, TriggerEvent t m, Prerender js t m) => Chan a -> m (Event t a)
+triggerEventWithChan :: (Reflex t, TriggerEvent t m, Prerender t m) => Chan a -> m (Event t a)
 triggerEventWithChan chan = do
   (e, trigger) <- newTriggerEvent
   -- In prerender because we only want to do this on the client
@@ -1716,13 +1716,13 @@
 divId :: DomBuilder t m => Text -> m a -> m a
 divId i = elAttr "div" ("id" =: i)
 
-type TestWidget js t m = (DomBuilder t m, MonadHold t m, PostBuild t m, Prerender js t m, PerformEvent t m, TriggerEvent t m, MonadFix m, MonadIO (Performable m), MonadIO m)
+type TestWidget t m = (DomBuilder t m, MonadHold t m, PostBuild t m, Prerender t m, PerformEvent t m, TriggerEvent t m, MonadFix m, MonadIO (Performable m), MonadIO m)
 
 testWidgetStaticDebug
   :: Bool
   -> WD b
   -- ^ Webdriver commands to run before JS runs and after hydration switchover
-  -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ())
+  -> (forall m js. TestWidget (SpiderTimeline Global) m => m ())
   -- ^ Widget we are testing
   -> WD b
 testWidgetStaticDebug withDebugging w = testWidgetDebug True withDebugging (void w) w
@@ -1735,7 +1735,7 @@
   -- ^ Webdriver commands to run before the JS runs (i.e. on the statically rendered page)
   -> WD b
   -- ^ Webdriver commands to run after hydration switchover
-  -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ())
+  -> (forall m js. TestWidget (SpiderTimeline Global) m => m ())
   -- ^ Widget we are testing
   -> WD b
 testWidgetDebug hardFailure withDebugging beforeJS afterSwitchover =
@@ -1752,7 +1752,7 @@
   -- ^ Webdriver commands to run before the JS runs (i.e. on the statically rendered page)
   -> (a -> WD b)
   -- ^ Webdriver commands to run after hydration switchover
-  -> (forall m js. TestWidget js (SpiderTimeline Global) m => m ())
+  -> (forall m js. TestWidget (SpiderTimeline Global) m => m ())
   -- ^ Widget we are testing (contents of body)
   -> WD b
 testWidgetDebug' hardFailure withDebugging beforeJS afterSwitchover bodyWidget = do
