diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/integration/Polysemy/Http/CookieTest.hs b/integration/Polysemy/Http/CookieTest.hs
--- a/integration/Polysemy/Http/CookieTest.hs
+++ b/integration/Polysemy/Http/CookieTest.hs
@@ -1,17 +1,17 @@
 module Polysemy.Http.CookieTest where
 
 import Control.Lens ((.~))
+import Control.Monad.IO.Class (liftIO)
+import Exon (exon)
 import Hedgehog (evalEither, (===))
-import Polysemy (embedToFinal, runFinal)
 import Polysemy.Log (interpretLogNull)
-import Polysemy.Resource (resourceToIOFinal)
 
-import qualified Polysemy.Http.Effect.Http as Http
 import Polysemy.Http.Data.HttpError (HttpError)
 import qualified Polysemy.Http.Data.Request as Request
-import Polysemy.Http.Data.Request (Port(Port), Tls(Tls))
+import Polysemy.Http.Data.Request (Port (Port), Tls (Tls))
 import qualified Polysemy.Http.Data.Response as Response
 import Polysemy.Http.Data.Response (Response)
+import qualified Polysemy.Http.Effect.Http as Http
 import Polysemy.Http.Interpreter.Native (interpretHttpNative)
 import qualified Polysemy.Http.Request as Request
 import Polysemy.Http.Request (addCookie)
@@ -39,6 +39,6 @@
 
 test_cookies :: UnitTest
 test_cookies = do
-  result <- lift (withServer runRequest)
+  result <- liftIO (withServer runRequest)
   response <- evalEither result
-  [qt|#{c1}=#{c1v};#{c2}=#{c2v}|] === Response._body response
+  [exon|#{c1}=#{c1v};#{c2}=#{c2v}|] === decodeUtf8 (Response._body response)
diff --git a/integration/Polysemy/Http/RequestTest.hs b/integration/Polysemy/Http/RequestTest.hs
--- a/integration/Polysemy/Http/RequestTest.hs
+++ b/integration/Polysemy/Http/RequestTest.hs
@@ -1,22 +1,21 @@
 module Polysemy.Http.RequestTest where
 
 import Control.Lens ((.~))
+import Control.Monad.IO.Class (liftIO)
 import qualified Data.Aeson as Aeson
 import Hedgehog (evalEither, (===))
-import Polysemy (embedToFinal, runFinal)
 import Polysemy.Log (interpretLogNull)
-import Polysemy.Resource (resourceToIOFinal)
 
-import qualified Polysemy.Http.Effect.Http as Http
 import Polysemy.Http.Data.HttpError (HttpError)
 import qualified Polysemy.Http.Data.Request as Request
-import Polysemy.Http.Data.Request (Body(Body), Port(Port), Tls(Tls))
+import Polysemy.Http.Data.Request (Body (Body), Port (Port), Tls (Tls))
 import qualified Polysemy.Http.Data.Response as Response
 import Polysemy.Http.Data.Response (Response)
-import Polysemy.Http.Json (jsonContentType)
+import qualified Polysemy.Http.Effect.Http as Http
 import Polysemy.Http.Interpreter.Native (interpretHttpNative)
+import Polysemy.Http.Json (jsonContentType)
 import qualified Polysemy.Http.Request as Request
-import Polysemy.Http.Server (Payload(Payload), withServer)
+import Polysemy.Http.Server (Payload (Payload), withServer)
 import Polysemy.Http.Test (UnitTest)
 
 runRequest ::
@@ -33,6 +32,6 @@
 
 test_request :: UnitTest
 test_request = do
-  result <- lift (withServer runRequest)
+  result <- liftIO (withServer runRequest)
   response <- evalEither result
   "5" === Response._body response
diff --git a/integration/Polysemy/Http/Server.hs b/integration/Polysemy/Http/Server.hs
--- a/integration/Polysemy/Http/Server.hs
+++ b/integration/Polysemy/Http/Server.hs
@@ -19,20 +19,21 @@
   withSocketsDo,
   )
 import qualified Network.Wai.Handler.Warp as Warp
-import Servant (Header, Get, Handler, JSON, PlainText, Post, ReqBody, ServerT, serve, (:<|>)((:<|>)), (:>))
-import Servant.Client (BaseUrl(BaseUrl), Client, ClientEnv, ClientM, Scheme(Http), client, mkClientEnv, runClientM)
+import Polysemy.Time.Json (json)
+import Prelude hiding (bracket)
+import Servant (Get, Handler, Header, JSON, PlainText, Post, ReqBody, ServerT, serve, (:<|>) ((:<|>)), (:>))
+import Servant.Client (BaseUrl (BaseUrl), Client, ClientEnv, ClientM, Scheme (Http), client, mkClientEnv, runClientM)
 
 freePort ::
   IO PortNumber
 freePort =
-  withSocketsDo $ do
+  withSocketsDo do
     addr : _ <- getAddrInfo (Just defaultHints) (Just "127.0.0.1") (Just "0")
     bracket (open addr) close socketPort
   where
     open addr = do
       sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
-      bind sock (addrAddress addr)
-      return sock
+      sock <$ bind sock (addrAddress addr)
 
 data Payload =
   Payload {
@@ -41,7 +42,7 @@
   }
   deriving (Eq, Show)
 
-defaultJson ''Payload
+json ''Payload
 
 type Api =
   Get '[JSON] Text
diff --git a/integration/Polysemy/Http/StreamTest.hs b/integration/Polysemy/Http/StreamTest.hs
--- a/integration/Polysemy/Http/StreamTest.hs
+++ b/integration/Polysemy/Http/StreamTest.hs
@@ -1,12 +1,10 @@
 module Polysemy.Http.StreamTest where
 
 import Control.Lens ((.~))
+import Control.Monad.IO.Class (liftIO)
 import qualified Data.ByteString as ByteString
 import Hedgehog (assert, evalEither, (===))
-import Polysemy (embedToFinal, runFinal)
 import Polysemy.Log (interpretLogNull)
-import Polysemy.Resource (resourceToIOFinal)
-import Polysemy.State (runState)
 
 import Polysemy.Http.Data.HttpError (HttpError)
 import qualified Polysemy.Http.Data.Request as Request
@@ -55,7 +53,7 @@
 
 test_httpStream :: UnitTest
 test_httpStream = do
-  result <- lift (withServer runRequest)
+  result <- liftIO (withServer runRequest)
   (chunkSizes, ()) <- evalEither result
   assert (length chunkSizes >= 10)
   sum chunkSizes === 10 * 8192
diff --git a/lib/Polysemy/Http.hs b/lib/Polysemy/Http.hs
--- a/lib/Polysemy/Http.hs
+++ b/lib/Polysemy/Http.hs
@@ -124,7 +124,7 @@
   )
 
 -- $intro
--- A basic 'Polysemy' effect abstracting HTTP requests:
+-- A basic Polysemy effect abstracting HTTP requests:
 --
 -- @
 -- import Polysemy (resourceToIO, runM)
diff --git a/lib/Polysemy/Http/Data/Header.hs b/lib/Polysemy/Http/Data/Header.hs
--- a/lib/Polysemy/Http/Data/Header.hs
+++ b/lib/Polysemy/Http/Data/Header.hs
@@ -1,14 +1,17 @@
 {-# options_haddock prune #-}
+
 -- |Description: Header Data Types, Internal
 module Polysemy.Http.Data.Header where
 
+import Polysemy.Time.Json (json)
+
 -- |The name of a header.
 newtype HeaderName =
   HeaderName { unHeaderName :: Text }
   deriving (Eq, Show, Generic)
   deriving newtype (IsString)
 
-defaultJson ''HeaderName
+json ''HeaderName
 
 -- |The value of a header.
 newtype HeaderValue =
@@ -16,7 +19,7 @@
   deriving (Eq, Show, Generic)
   deriving newtype (IsString)
 
-defaultJson ''HeaderValue
+json ''HeaderValue
 
 -- |An HTTP header.
 data Header =
@@ -26,4 +29,4 @@
   }
   deriving (Eq, Show, Generic)
 
-defaultJson ''Header
+json ''Header
diff --git a/lib/Polysemy/Http/Data/Request.hs b/lib/Polysemy/Http/Data/Request.hs
--- a/lib/Polysemy/Http/Data/Request.hs
+++ b/lib/Polysemy/Http/Data/Request.hs
@@ -5,6 +5,8 @@
 import Control.Lens (makeClassy)
 import qualified Data.Text as Text
 import Network.HTTP.Client.Internal (CookieJar)
+import Polysemy.Time.Json (json)
+import Prelude hiding (Get, Put)
 
 import Polysemy.Http.Data.Header (HeaderName, HeaderValue)
 
@@ -31,7 +33,7 @@
   Custom Text
   deriving (Eq, Show)
 
-defaultJson ''Method
+json ''Method
 
 instance IsString Method where
   fromString = \case
@@ -67,7 +69,7 @@
   deriving (Eq, Show, Generic)
   deriving newtype (IsString)
 
-defaultJson ''Host
+json ''Host
 
 -- |Request port.
 newtype Port =
@@ -75,14 +77,14 @@
   deriving (Eq, Show, Generic)
   deriving newtype (Num, Ord, Enum, Real, Integral, Read)
 
-defaultJson ''Port
+json ''Port
 
 -- |A flag that indicates whether a request should use TLS.
 newtype Tls =
   Tls { unTls :: Bool }
   deriving (Eq, Show, Generic)
 
-defaultJson ''Tls
+json ''Tls
 
 -- |Rrequest path.
 newtype Path =
@@ -94,7 +96,7 @@
   Path l <> Path r =
     Path (Text.dropWhileEnd ('/' ==) l <> "/" <> Text.dropWhile ('/' ==) r)
 
-defaultJson ''Path
+json ''Path
 
 -- |The key of a query parameter.
 newtype QueryKey =
@@ -102,7 +104,7 @@
   deriving (Eq, Show, Generic)
   deriving newtype (IsString)
 
-defaultJson ''QueryKey
+json ''QueryKey
 
 -- |The value of a query parameter.
 newtype QueryValue =
@@ -110,7 +112,7 @@
   deriving (Eq, Show, Generic)
   deriving newtype (IsString)
 
-defaultJson ''QueryValue
+json ''QueryValue
 
 -- |Request body, using 'LByteString' because it is what 'Aeson.encode' produces.
 newtype Body =
diff --git a/lib/Polysemy/Http/Data/Response.hs b/lib/Polysemy/Http/Data/Response.hs
--- a/lib/Polysemy/Http/Data/Response.hs
+++ b/lib/Polysemy/Http/Data/Response.hs
@@ -5,6 +5,7 @@
   Status(Status),
 ) where
 
+import Exon (exon)
 import Network.HTTP.Client (BodyReader, CookieJar)
 import Network.HTTP.Types (
   Status (Status),
@@ -34,7 +35,7 @@
 
 instance {-# overlapping #-} Show (Response BodyReader) where
   show (Response s _ hs _) =
-    [qt|StreamingResponse { status :: #{s}, headers :: #{hs} }|]
+    [exon|StreamingResponse { status :: #{show s}, headers :: #{show hs} }|]
 
 instance Eq b => Eq (Response b) where
   Response ls lb lh _ == Response rs rb rh _ =
diff --git a/lib/Polysemy/Http/Effect/Entity.hs b/lib/Polysemy/Http/Effect/Entity.hs
--- a/lib/Polysemy/Http/Effect/Entity.hs
+++ b/lib/Polysemy/Http/Effect/Entity.hs
@@ -1,8 +1,7 @@
 {-# options_haddock prune #-}
+
 -- |Description: Entity Effects, Internal
 module Polysemy.Http.Effect.Entity where
-
-import Polysemy (makeSem_)
 
 -- |Generic error type for decoders.
 data EntityError =
diff --git a/lib/Polysemy/Http/Effect/Http.hs b/lib/Polysemy/Http/Effect/Http.hs
--- a/lib/Polysemy/Http/Effect/Http.hs
+++ b/lib/Polysemy/Http/Effect/Http.hs
@@ -1,9 +1,8 @@
 {-# options_haddock prune #-}
+
 -- |Description: Http Effect, Internal
 module Polysemy.Http.Effect.Http where
 
-import Polysemy (makeSem_)
-
 import Polysemy.Http.Data.HttpError (HttpError)
 import Polysemy.Http.Data.Request (Request)
 import Polysemy.Http.Data.Response (Response)
@@ -19,7 +18,8 @@
 
 makeSem_ ''Http
 
--- |Bracket a higher-order action with a 'Response' that has been opened while its body hasn't been fetched.
+-- |Bracket a higher-order action with a 'Polysemy.Http.Data.Response.Response' that has been opened while its body
+-- hasn't been fetched.
 response ::
   ∀ c r a .
   Member (Http c) r =>
diff --git a/lib/Polysemy/Http/Http.hs b/lib/Polysemy/Http/Http.hs
--- a/lib/Polysemy/Http/Http.hs
+++ b/lib/Polysemy/Http/Http.hs
@@ -1,9 +1,9 @@
 {-# options_haddock prune #-}
+
 -- |Description: Streaming Implementation, Internal
 module Polysemy.Http.Http where
 
 import qualified Data.ByteString as ByteString
-import Polysemy.Resource (Resource, bracket)
 
 import Polysemy.Http.Data.HttpError (HttpError)
 import Polysemy.Http.Data.Request (Request)
@@ -45,7 +45,7 @@
     release handle =
       process (StreamEvent.Release handle)
 
--- |Initiate a request and stream the response, calling 'process' after connecting, for every chunk, after closing the
+-- |Initiate a request and stream the response, calling @process@ after connecting, for every chunk, after closing the
 -- connection, and for the return value.
 -- 'StreamEvent' is used to indicate the stage of the request cycle.
 --
diff --git a/lib/Polysemy/Http/Interpreter/AesonEntity.hs b/lib/Polysemy/Http/Interpreter/AesonEntity.hs
--- a/lib/Polysemy/Http/Interpreter/AesonEntity.hs
+++ b/lib/Polysemy/Http/Interpreter/AesonEntity.hs
@@ -2,7 +2,7 @@
 -- |Description: Entity Aeson Interpreters, Internal
 module Polysemy.Http.Interpreter.AesonEntity where
 
-import Data.Aeson (eitherDecode', eitherDecodeStrict', encode)
+import Data.Aeson (FromJSON, ToJSON, eitherDecode', eitherDecodeStrict', encode)
 
 import Polysemy.Http.Effect.Entity (EntityDecode, EntityEncode, EntityError (EntityError))
 import qualified Polysemy.Http.Effect.Entity as Entity (EntityDecode (..), EntityEncode (..))
@@ -37,7 +37,7 @@
   s ->
   Sem r (Either EntityError a)
 decodeWith dec body =
-  pure . mapLeft (EntityError (decodeUtf8 body) . toText) $ dec body
+  pure . first (EntityError (decodeUtf8 body) . toText) $ dec body
 {-# inline decodeWith #-}
 
 -- |Interpreter for 'EntityDecode' that uses Aeson and a different codec type.
diff --git a/lib/Polysemy/Http/Interpreter/Manager.hs b/lib/Polysemy/Http/Interpreter/Manager.hs
--- a/lib/Polysemy/Http/Interpreter/Manager.hs
+++ b/lib/Polysemy/Http/Interpreter/Manager.hs
@@ -1,10 +1,12 @@
 {-# options_haddock prune #-}
+
 -- |Description: Manager Interpreters, Internal
 module Polysemy.Http.Interpreter.Manager where
 
 import Network.HTTP.Client (newManager)
 import qualified Network.HTTP.Client as HTTP (Manager)
 import Network.HTTP.Client.TLS (mkManagerSettings)
+import Prelude hiding (Get)
 
 import Polysemy.Http.Effect.Manager (Manager (..))
 
diff --git a/lib/Polysemy/Http/Interpreter/Native.hs b/lib/Polysemy/Http/Interpreter/Native.hs
--- a/lib/Polysemy/Http/Interpreter/Native.hs
+++ b/lib/Polysemy/Http/Interpreter/Native.hs
@@ -1,16 +1,16 @@
 {-# options_haddock prune #-}
+
 -- |Description: Http Interpreters, Internal
 module Polysemy.Http.Interpreter.Native where
 
 import qualified Data.CaseInsensitive as CaseInsensitive
 import Data.CaseInsensitive (foldedCase)
+import Exon (exon)
 import qualified Network.HTTP.Client as HTTP
 import Network.HTTP.Client (BodyReader, httpLbs, responseClose, responseOpen)
 import Network.HTTP.Client.Internal (CookieJar (CJ))
-import Polysemy (getInitialStateT, interpretH, runTSimple)
+import Polysemy.Internal.Tactics (liftT)
 import qualified Polysemy.Log as Log
-import Polysemy.Log (Log)
-import Polysemy.Resource (Resource, bracket)
 
 import Polysemy.Http.Data.Header (Header (Header), unHeaderName, unHeaderValue)
 import qualified Polysemy.Http.Data.HttpError as HttpError
@@ -68,7 +68,7 @@
   IO a ->
   Sem r (Either HttpError a)
 internalError =
-  tryHoist HttpError.Internal
+  fmap (first HttpError.Internal) . tryAny
 
 executeRequest ::
   Member (Embed IO) r =>
@@ -90,7 +90,7 @@
       manager <- Manager.get
       internalError (responseOpen (nativeRequest request) manager)
     release (Right response) =
-      tryAny (responseClose response) >>= traverseLeft closeFailed
+      tryAny (responseClose response) >>= either closeFailed pure
     release (Left _) =
       unit
     use (Right response) = do
@@ -98,7 +98,7 @@
     use (Left err) =
       pure (Left err)
     closeFailed err =
-      Log.error [qt|closing response failed: #{err}|]
+      Log.error [exon|closing response failed: #{err}|]
 {-# inline withResponse #-}
 
 distribEither ::
@@ -119,23 +119,23 @@
   InterpreterFor (Http BodyReader) r
 interpretHttpNativeWith =
   interpretH \case
-    Http.Response request f -> do
-      distribEither =<< withResponse request ((\x -> runTSimple x) . f)
+    Http.Response request f ->
+      distribEither =<< withResponse request ((\ x -> runTSimple x) . f)
     Http.Request request -> do
-      Log.debug [qt|http request: #{request}|]
+      Log.debug [exon|http request: #{show request}|]
       manager <- Manager.get
       liftT do
         response <- executeRequest manager request
-        response <$ Log.debug [qt|http response: #{response}|]
+        response <$ Log.debug [exon|http response: #{show response}|]
     Http.Stream request handler -> do
-      Log.debug [qt|http stream request: #{request}|]
-      distribEither =<< withResponse request ((\x -> runTSimple x). handler)
+      Log.debug [exon|http stream request: #{show request}|]
+      distribEither =<< withResponse request ((\ x -> runTSimple x) . handler)
     Http.ConsumeChunk body ->
       pureT . first HttpError.ChunkFailed =<< tryAny body
 {-# inline interpretHttpNativeWith #-}
 
--- |Interpret @'Http' 'BodyReader'@ using the native 'Network.HTTP.Client' implementation.
--- 'BodyReader' is an alias for @'IO' 'ByteString'@, it is how http-client represents chunks.
+-- |Interpret @'Http' 'BodyReader'@ using the native "Network.HTTP.Client" implementation.
+-- 'BodyReader' is an alias for @'IO' 'ByteString'@; it is how http-client represents chunks.
 -- This uses the default interpreter for 'Manager'.
 interpretHttpNative ::
   Members [Embed IO, Log, Resource] r =>
diff --git a/lib/Polysemy/Http/Interpreter/Pure.hs b/lib/Polysemy/Http/Interpreter/Pure.hs
--- a/lib/Polysemy/Http/Interpreter/Pure.hs
+++ b/lib/Polysemy/Http/Interpreter/Pure.hs
@@ -1,10 +1,10 @@
 {-# options_haddock prune #-}
+
 -- |Description: Pure Http Interpreters, Internal
 module Polysemy.Http.Interpreter.Pure where
 
 import Network.HTTP.Client.Internal (CookieJar (CJ))
-import Polysemy (interpretH)
-import Polysemy.Internal.Tactics (bindT, bindTSimple)
+import Polysemy.Internal.Tactics (liftT)
 
 import Polysemy.Http.Data.Response (Response (Response))
 import qualified Polysemy.Http.Effect.Http as Http
diff --git a/lib/Polysemy/Http/Prelude.hs b/lib/Polysemy/Http/Prelude.hs
deleted file mode 100644
--- a/lib/Polysemy/Http/Prelude.hs
+++ /dev/null
@@ -1,181 +0,0 @@
-{-# options_haddock hide #-}
--- |Description: Prelude, Internal
-{-# LANGUAGE NoImplicitPrelude #-}
-
-module Polysemy.Http.Prelude (
-  module Polysemy.Http.Prelude,
-  module Data.Aeson,
-  module Data.Aeson.TH,
-  module Data.Composition,
-  module Data.Default,
-  module Data.Either.Combinators,
-  module Data.Foldable,
-  module Data.Map.Strict,
-  module GHC.Err,
-  module Polysemy,
-  module Polysemy.State,
-  module Polysemy.Error,
-  module Relude,
-) where
-
-import Control.Exception (try)
-import Data.Aeson (FromJSON, ToJSON)
-import Data.Aeson.TH (deriveFromJSON, deriveJSON)
-import qualified Data.Aeson.TH as Aeson (Options, defaultOptions, unwrapUnaryRecords)
-import Data.Composition ((.:))
-import Data.Default (Default (def))
-import Data.Either.Combinators (mapLeft)
-import Data.Foldable (foldl, traverse_)
-import Data.Map.Strict (Map)
-import Data.String.Interpolate (i)
-import GHC.Err (undefined)
-import GHC.IO.Unsafe (unsafePerformIO)
-import Language.Haskell.TH.Quote (QuasiQuoter)
-import qualified Language.Haskell.TH.Syntax as TH
-import Polysemy (
-  Effect,
-  Embed,
-  InterpreterFor,
-  InterpretersFor,
-  Member,
-  Members,
-  Sem,
-  WithTactics,
-  embed,
-  interpret,
-  makeSem,
-  pureT,
-  raise,
-  raiseUnder,
-  raiseUnder2,
-  raiseUnder3,
-  )
-import Polysemy.Error (Error, fromEither, runError, throw)
-import Polysemy.State (State, evalState, get, gets, modify, put)
-import Relude hiding (
-  Reader,
-  State,
-  Type,
-  ask,
-  asks,
-  evalState,
-  get,
-  gets,
-  hoistEither,
-  modify,
-  put,
-  readFile,
-  runReader,
-  runState,
-  state,
-  undefined,
-  )
-
-dbg :: Monad m => Text -> m ()
-dbg msg = do
-  () <- return $ unsafePerformIO (putStrLn (toString msg))
-  return ()
-{-# inline dbg #-}
-
-dbgs :: Monad m => Show a => a -> m ()
-dbgs a =
-  dbg (show a)
-{-# inline dbgs_ #-}
-
-dbgs_ :: Monad m => Show a => a -> m a
-dbgs_ a =
-  a <$ dbg (show a)
-{-# inline dbgs #-}
-
-unit ::
-  Applicative f =>
-  f ()
-unit =
-  pure ()
-{-# inline unit #-}
-
-tuple ::
-  Applicative f =>
-  f a ->
-  f b ->
-  f (a, b)
-tuple fa fb =
-  (,) <$> fa <*> fb
-{-# inline tuple #-}
-
-unsafeLogSAnd :: Show a => a -> b -> b
-unsafeLogSAnd a b =
-  unsafePerformIO $ print a >> return b
-{-# inline unsafeLogSAnd #-}
-
-unsafeLogAnd :: Text -> b -> b
-unsafeLogAnd a b =
-  unsafePerformIO $ putStrLn (toString a) >> return b
-{-# inline unsafeLogAnd #-}
-
-unsafeLogS :: Show a => a -> a
-unsafeLogS a =
-  unsafePerformIO $ print a >> return a
-{-# inline unsafeLogS #-}
-
-qt :: QuasiQuoter
-qt =
-  i
-{-# inline qt #-}
-
-liftT ::
-  forall m f r e a .
-  Functor f =>
-  Sem r a ->
-  Sem (WithTactics e f m r) (f a)
-liftT =
-  pureT <=< raise
-{-# inline liftT #-}
-
-defaultOptions :: Aeson.Options
-defaultOptions =
-  Aeson.defaultOptions { Aeson.unwrapUnaryRecords = True }
-
-hoistEither ::
-  Member (Error e2) r =>
-  (e1 -> e2) ->
-  Either e1 a ->
-  Sem r a
-hoistEither f =
-  fromEither . mapLeft f
-
-tryAny ::
-  Member (Embed IO) r =>
-  IO a ->
-  Sem r (Either Text a)
-tryAny =
-  embed . fmap (mapLeft show) . try @SomeException
-
-tryHoist ::
-  Member (Embed IO) r =>
-  (Text -> e) ->
-  IO a ->
-  Sem r (Either e a)
-tryHoist f =
-  fmap (mapLeft f) . tryAny
-
-tryThrow ::
-  Members [Embed IO, Error e] r =>
-  (Text -> e) ->
-  IO a ->
-  Sem r a
-tryThrow f =
-  fromEither <=< tryHoist f
-
-traverseLeft ::
-  Applicative m =>
-  (a -> m b) ->
-  Either a b ->
-  m b
-traverseLeft f =
-  either f pure
-{-# inline traverseLeft #-}
-
-defaultJson :: TH.Name -> TH.Q [TH.Dec]
-defaultJson =
-  deriveJSON defaultOptions
diff --git a/lib/Polysemy/Http/Request.hs b/lib/Polysemy/Http/Request.hs
--- a/lib/Polysemy/Http/Request.hs
+++ b/lib/Polysemy/Http/Request.hs
@@ -1,4 +1,5 @@
 {-# options_haddock prune #-}
+
 -- |Description: Request Combinators, Internal
 module Polysemy.Http.Request where
 
@@ -7,9 +8,10 @@
 import Data.Time (UTCTime (UTCTime))
 import Data.Time.Calendar (fromGregorian)
 import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
+import Exon (exon)
 import Network.HTTP.Client (Cookie (Cookie))
 import Network.HTTP.Client.Internal (CookieJar (CJ, expose))
-import Prelude hiding (get, put)
+import Prelude hiding (Get, Put, get, put)
 
 import qualified Polysemy.Http.Data.Request as Request
 import Polysemy.Http.Data.Request (Body, Host (Host), Method (..), Path (Path), Port (Port), Request (Request), Tls (Tls))
@@ -19,7 +21,7 @@
   Text ->
   Either Text a
 invalidScheme scheme url =
-  Left [qt|invalid scheme `#{scheme}` in url: #{url}|]
+  Left [exon|invalid scheme `#{scheme}` in url: #{url}|]
 
 split ::
   Text ->
@@ -47,7 +49,7 @@
 parseHostPort url = \case
   (host, Nothing) -> Right (Host host, Nothing)
   (host, Just (readMaybe . toString -> Just port)) -> Right (Host host, Just (Port port))
-  (_, Just port) -> Left [qt|invalid port `#{port}` in url: #{url}|]
+  (_, Just port) -> Left [exon|invalid port `#{port}` in url: #{url}|]
 
 parseUrl ::
   Text ->
diff --git a/lib/Prelude.hs b/lib/Prelude.hs
deleted file mode 100644
--- a/lib/Prelude.hs
+++ /dev/null
@@ -1,7 +0,0 @@
-{-# options_haddock hide #-}
--- |Description: Prelude, Internal
-module Prelude (
-  module Polysemy.Http.Prelude,
-) where
-
-import Polysemy.Http.Prelude
diff --git a/polysemy-http.cabal b/polysemy-http.cabal
--- a/polysemy-http.cabal
+++ b/polysemy-http.cabal
@@ -1,11 +1,11 @@
 cabal-version: 2.2
 
--- This file has been generated from package.yaml by hpack version 0.34.4.
+-- This file has been generated from package.yaml by hpack version 0.34.6.
 --
 -- see: https://github.com/sol/hpack
 
 name:           polysemy-http
-version:        0.5.0.0
+version:        0.6.0.0
 synopsis:       Polysemy Effects for HTTP clients
 description:    See <https://hackage.haskell.org/package/polysemy-http/docs/Polysemy-Http.html>
 category:       Network
@@ -43,13 +43,7 @@
       Polysemy.Http.Interpreter.Native
       Polysemy.Http.Interpreter.Pure
       Polysemy.Http.Json
-      Polysemy.Http.Prelude
       Polysemy.Http.Request
-  other-modules:
-      Prelude
-      Paths_polysemy_http
-  autogen-modules:
-      Paths_polysemy_http
   hs-source-dirs:
       lib
   default-extensions:
@@ -109,23 +103,19 @@
       aeson >=1.4
     , ansi-terminal >=0.10.3
     , base ==4.*
-    , bytestring
     , case-insensitive >=1.2
-    , composition >=1.0.2
-    , containers
-    , data-default >=0.7
-    , either >=5.0.1
-    , http-client >=0.6.4
-    , http-client-tls >=0.3.5
+    , data-default >=0.2
+    , exon >=0.3
+    , http-client >=0.5.14
+    , http-client-tls >=0.3.1
     , http-types >=0.12.3
+    , incipit >=0.1.0.3
     , lens >=4
     , polysemy >=1.6
-    , polysemy-log >=0.2.2.4
+    , polysemy-log >=0.5
     , polysemy-plugin >=0.4
-    , relude >=0.7
-    , string-interpolate >=0.2.1
+    , polysemy-time >=0.3
     , template-haskell
-    , text
     , time
   mixins:
       base hiding (Prelude)
@@ -140,7 +130,6 @@
       Polysemy.Http.Server
       Polysemy.Http.StreamTest
       Polysemy.Http.Test
-      Paths_polysemy_http
   hs-source-dirs:
       integration
   default-extensions:
@@ -197,40 +186,26 @@
       ViewPatterns
   ghc-options: -fplugin=Polysemy.Plugin -flate-specialise -fspecialise-aggressively -Wall -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      aeson >=1.4
-    , ansi-terminal >=0.10.3
+      aeson
     , base ==4.*
-    , bytestring
-    , case-insensitive >=1.2
-    , composition >=1.0.2
-    , containers
-    , data-default >=0.7
-    , either >=5.0.1
+    , exon
     , hedgehog
-    , http-client >=0.6.4
-    , http-client-tls >=0.3.5
-    , http-types >=0.12.3
-    , lens >=4
+    , http-client
+    , incipit
+    , lens
     , network
-    , polysemy >=1.6
+    , polysemy
     , polysemy-http
-    , polysemy-log >=0.2.2.4
-    , polysemy-plugin >=0.4
-    , relude >=0.7
+    , polysemy-plugin
+    , polysemy-time
     , servant
     , servant-client
     , servant-server
-    , string-interpolate >=0.2.1
     , tasty
     , tasty-hedgehog
-    , template-haskell
-    , text
-    , time
     , warp
   mixins:
       base hiding (Prelude)
-    , polysemy-http hiding (Prelude)
-    , polysemy-http (Polysemy.Http.Prelude as Prelude)
   default-language: Haskell2010
 
 test-suite polysemy-http-unit
@@ -240,7 +215,6 @@
       Polysemy.Http.ResponseTest
       Polysemy.Http.Test
       Polysemy.Http.UrlTest
-      Paths_polysemy_http
   hs-source-dirs:
       test
   default-extensions:
@@ -297,33 +271,16 @@
       ViewPatterns
   ghc-options: -fplugin=Polysemy.Plugin -flate-specialise -fspecialise-aggressively -Wall -threaded -rtsopts -with-rtsopts=-N
   build-depends:
-      aeson >=1.4
-    , ansi-terminal >=0.10.3
-    , base ==4.*
-    , bytestring
-    , case-insensitive >=1.2
-    , composition >=1.0.2
-    , containers
-    , data-default >=0.7
-    , either >=5.0.1
+      base ==4.*
+    , exon
     , hedgehog
-    , http-client >=0.6.4
-    , http-client-tls >=0.3.5
-    , http-types >=0.12.3
-    , lens >=4
-    , polysemy >=1.6
+    , http-client
+    , incipit
+    , polysemy
     , polysemy-http
-    , polysemy-log >=0.2.2.4
-    , polysemy-plugin >=0.4
-    , relude >=0.7
-    , string-interpolate >=0.2.1
+    , polysemy-plugin
     , tasty
     , tasty-hedgehog
-    , template-haskell
-    , text
-    , time
   mixins:
       base hiding (Prelude)
-    , polysemy-http hiding (Prelude)
-    , polysemy-http (Polysemy.Http.Prelude as Prelude)
   default-language: Haskell2010
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -6,15 +6,17 @@
 # Example
 
 ```haskell
-import Polysemy (runM, resourceToIO)
+import Polysemy (runM)
+import Polysemy.Resource (resourceToIO)
 import qualified Polysemy.Http as Http
-import Polysemy.Http (interpretHttpNative, interpretLogStdout)
+import Polysemy.Http (interpretHttpNative)
+import Polysemy.Log (interpretLogStdout')
 
 main :: IO ()
 main = do
   result <- runM $
     resourceToIO $
-    interpretLogStdout $
+    interpretLogStdout' $
     interpretHttpNative $
     Http.request (Http.get "hackage.haskell.org" "package/polysemy-http")
   print result
@@ -160,7 +162,7 @@
 main = do
   result <- runM $
     resourceToIO $
-    interpretLogStdout $
+    interpretLogStdout' $
     interpretHttpPure [Response (toEnum 200) "foo" []] [] $
     Http.request (Http.get "hackage.haskell.org" "package/polysemy-http")
   print result
diff --git a/test/Polysemy/Http/UrlTest.hs b/test/Polysemy/Http/UrlTest.hs
--- a/test/Polysemy/Http/UrlTest.hs
+++ b/test/Polysemy/Http/UrlTest.hs
@@ -1,8 +1,9 @@
 module Polysemy.Http.UrlTest where
 
+import Exon (exon)
 import Hedgehog ((===))
 
-import Polysemy.Http.Data.Request (Host(Host), Path(Path), Port(Port), Tls(Tls))
+import Polysemy.Http.Data.Request (Host (Host), Path (Path), Port (Port), Tls (Tls))
 import Polysemy.Http.Request (parseUrl)
 import Polysemy.Http.Test (UnitTest)
 
@@ -11,8 +12,8 @@
   Right (Tls True, Host "host.com", Nothing, Path "path") === parseUrl "https://host.com/path"
   Right (Tls True, Host "host.com", Nothing, Path "path/to/file") === parseUrl "host.com/path/to/file"
   Right (Tls False, Host "host.com", Just (Port 553), Path "path") === parseUrl "http://host.com:553/path"
-  Left [qt|invalid port `foo` in url: #{url1}|] === parseUrl url1
-  Left [qt|invalid scheme `httpx` in url: #{url2}|] === parseUrl url2
+  Left [exon|invalid port `foo` in url: #{url1}|] === parseUrl url1
+  Left [exon|invalid scheme `httpx` in url: #{url2}|] === parseUrl url2
   where
     url1 =
       "http://host.com:foo"
