diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Api.hs b/components/amazonka/Effectful/Zoo/Amazonka/Api.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Api.hs
@@ -0,0 +1,9 @@
+{- HLINT "Use let" -}
+
+module Effectful.Zoo.Amazonka.Api
+  ( module Effectful.Zoo.Amazonka.Api.Discover,
+    module Effectful.Zoo.Amazonka.Api.Log,
+  ) where
+
+import Effectful.Zoo.Amazonka.Api.Discover
+import Effectful.Zoo.Amazonka.Api.Log
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Api/Discover.hs b/components/amazonka/Effectful/Zoo/Amazonka/Api/Discover.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Api/Discover.hs
@@ -0,0 +1,67 @@
+{- HLINT "Use let" -}
+
+module Effectful.Zoo.Amazonka.Api.Discover
+  ( discoverAwsEnv,
+    maybeSetEndpoint,
+    setAwsEnvEndpointOverride,
+    setAwsServiceEndpointOverride,
+  ) where
+
+import Amazonka qualified as AWS
+import Control.Monad.IO.Class
+import Data.Generics.Product.Any
+import Data.Text qualified as T
+import Data.Text.Encoding qualified as T
+import Effectful
+import Effectful.Environment
+import Effectful.Zoo.Amazonka.Data
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+import Lens.Micro
+import System.IO qualified as IO
+import Text.Read
+
+maybeSetEndpoint :: ()
+  => Maybe (String, String)
+  -> (AwsService -> AwsService)
+  -> AwsService
+  -> AwsService
+maybeSetEndpoint = \case
+  Just (host, portString) ->
+    case readMaybe portString of
+      Just port -> (. AWS.setEndpoint False (T.encodeUtf8 (T.pack host)) port)
+      Nothing   -> id
+  Nothing           -> id
+
+setAwsEnvEndpointOverride :: ByteString -> Int -> Bool -> AwsEnv -> AwsEnv
+setAwsEnvEndpointOverride host port ssl env = do
+  env
+    & the @"overrides" .~ setAwsServiceEndpointOverride host port ssl
+
+setAwsServiceEndpointOverride :: ByteString -> Int -> Bool -> AwsService -> AwsService
+setAwsServiceEndpointOverride host port ssl svc =
+  svc & the @"endpoint" %~ \mkEndpoint region ->
+    mkEndpoint region
+      & the @"host" .~ host
+      & the @"port" .~ port
+      & the @"secure" .~ ssl
+
+discoverAwsEnv :: ()
+  => r <: Environment
+  => r <: IOE
+  => Eff r AwsEnv
+discoverAwsEnv = do
+  logger' <- liftIO $ AWS.newLogger AWS.Debug IO.stdout
+
+  mLocalStackHost <- lookupEnv "AWS_LOCALSTACK_HOST"
+  mLocalStackPort <- lookupEnv "AWS_LOCALSTACK_PORT"
+
+  mLocalStackEndpoint <- pure $ (,)
+    <$> mLocalStackHost
+    <*> mLocalStackPort
+
+  discoveredAwsEnv <- liftIO $ AWS.newEnv AWS.discover
+
+  pure $ discoveredAwsEnv
+    & the @"logger" .~ logger'
+    & the @"overrides" %~ maybeSetEndpoint mLocalStackEndpoint
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Api/Log.hs b/components/amazonka/Effectful/Zoo/Amazonka/Api/Log.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Api/Log.hs
@@ -0,0 +1,16 @@
+module Effectful.Zoo.Amazonka.Api.Log
+  ( awsLogLevelToSeverity,
+  ) where
+
+import Amazonka qualified as AWS
+import Effectful.Zoo.Amazonka.Data
+import Effectful.Zoo.Log.Data.Severity
+
+awsLogLevelToSeverity :: ()
+  => AwsLogLevel
+  -> Severity
+awsLogLevelToSeverity = \case
+  AWS.Trace -> Trace
+  AWS.Debug -> Debug
+  AWS.Info  -> Info
+  AWS.Error -> Error
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Api/Run.hs b/components/amazonka/Effectful/Zoo/Amazonka/Api/Run.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Api/Run.hs
@@ -0,0 +1,63 @@
+{- HLINT ignore "Use let" -}
+
+module Effectful.Zoo.Amazonka.Api.Run
+  ( runDataLogAwsLogEntryToLog,
+    runDataLogAwsLogEntryToLogWith,
+    runDataLogAwsLogEntryLocalToLogWith,
+  ) where
+
+import Control.Monad.IO.Class
+import Data.ByteString.Builder qualified as B
+import Data.Text.Lazy qualified as LT
+import Data.Text.Lazy.Encoding qualified as LT
+import Data.Time.Clock qualified as IO
+import Effectful
+import Effectful.Zoo.Amazonka.Api
+import Effectful.Zoo.Amazonka.Data
+import Effectful.Zoo.Core
+import Effectful.Zoo.DataLog.Api
+import Effectful.Zoo.DataLog.Data.LogEntry
+import Effectful.Zoo.DataLog.Dynamic
+import Effectful.Zoo.Log.Data.LogMessage
+import Effectful.Zoo.Log.Data.Severity
+import HaskellWorks.Prelude
+
+runDataLogAwsLogEntryToLog :: forall a r. ()
+  => r <: DataLog (LogEntry (LogMessage Text))
+  => r <: IOE
+  => Eff (DataLog AwsLogEntry : r) a
+  -> Eff r a
+runDataLogAwsLogEntryToLog =
+  runDataLogAwsLogEntryToLogWith awsLogLevelToSeverity
+
+runDataLogAwsLogEntryToLogWith :: forall a r. ()
+  => r <: DataLog (LogEntry (LogMessage Text))
+  => r <: IOE
+  => (AwsLogLevel -> Severity)
+  -> Eff (DataLog AwsLogEntry : r) a
+  -> Eff r a
+runDataLogAwsLogEntryToLogWith mapSeverity
+  = runDataLogAwsLogEntryLocalToLogWith mapSeverity id
+
+runDataLogAwsLogEntryLocalToLogWith :: forall a r. ()
+  => r <: DataLog (LogEntry (LogMessage Text))
+  => r <: IOE
+  => (AwsLogLevel -> Severity)
+  -> (AwsLogEntry -> AwsLogEntry)
+  -> Eff (DataLog AwsLogEntry : r) a
+  -> Eff r a
+runDataLogAwsLogEntryLocalToLogWith mapSeverity context =
+  runDataLog $ \logEntry -> do
+    now <- liftIO IO.getCurrentTime
+
+    let entry = context logEntry
+    let message =
+          LogMessage (mapSeverity entry.logLevel) $
+            LT.toStrict (LT.decodeUtf8 (B.toLazyByteString entry.builder))
+
+    dataLog $
+      LogEntry
+        { message = message
+        , time = now
+        , source = entry.callStack
+        }
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Api/Send.hs b/components/amazonka/Effectful/Zoo/Amazonka/Api/Send.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Api/Send.hs
@@ -0,0 +1,92 @@
+module Effectful.Zoo.Amazonka.Api.Send
+  ( sendAws,
+    askAwsEnv,
+    localAwsEnv,
+    lazySendAws,
+  ) where
+
+import Amazonka qualified as AWS
+import Effectful
+import Effectful.Dispatch.Dynamic
+import Effectful.Error.Static
+import Effectful.Resource
+import Effectful.Zoo.Amazonka.Data.AwsEnv
+import Effectful.Zoo.Amazonka.Data.AwsError
+import Effectful.Zoo.Amazonka.Data.AwsLogEntry
+import Effectful.Zoo.Amazonka.Data.AwsRequest
+import Effectful.Zoo.Amazonka.Data.AwsResponse
+import Effectful.Zoo.Amazonka.Dynamic
+import Effectful.Zoo.Core
+import Effectful.Zoo.DataLog.Api
+import Effectful.Zoo.DataLog.Dynamic
+import Effectful.Zoo.Lazy.Dynamic
+import GHC.Stack qualified as GHC
+import HaskellWorks.Prelude
+
+sendAwsInternal :: forall a r. ()
+  => AwsRequest a
+  => HasCallStack
+  => r <: Amazonka
+  => r <: Error AwsError
+  => Typeable (AwsResponse a)
+  => Typeable a
+  => a
+  -> Eff r (AwsResponse a)
+sendAwsInternal req =
+  send (SendAws req)
+    & onLeftM throwError
+
+askAwsEnv :: ()
+  => HasCallStack
+  => r <: Amazonka
+  => Eff r AwsEnv
+askAwsEnv =
+  send AskAwsEnv
+
+localAwsEnv :: ()
+  => HasCallStack
+  => r <: Amazonka
+  => (AwsEnv -> AwsEnv)
+  -> Eff r a
+  -> Eff r a
+localAwsEnv f m =
+  send (LocalAwsEnv f m)
+
+sendAws :: forall a r. ()
+  => HasCallStack
+  => AwsRequest a
+  => r <: Amazonka
+  => r <: DataLog AwsLogEntry
+  => r <: Error AwsError
+  => r <: IOE
+  => Typeable (AwsResponse a)
+  => Typeable a
+  => a
+  -> Eff r (AwsResponse a)
+sendAws req = withFrozenCallStack $ do
+  envAws0 <- askAwsEnv
+
+  envAws1 <- withEffToIO (ConcUnlift Persistent Unlimited) $ \effToIO ->
+    pure $ envAws0
+      { AWS.logger = \logLevel builder ->
+          effToIO $ dataLog $ AwsLogEntry GHC.callStack logLevel builder
+      }
+
+  localAwsEnv (const envAws1) $
+    sendAwsInternal req
+
+lazySendAws :: forall a r. ()
+  => HasCallStack
+  => AwsRequest a
+  => r <: DataLog AwsLogEntry
+  => r <: Error AwsError
+  => r <: IOE
+  => r <: Lazy AwsEnv
+  => r <: Resource
+  => Typeable (AwsResponse a)
+  => Typeable a
+  => a
+  -> Eff r (AwsResponse a)
+lazySendAws req = GHC.withFrozenCallStack $ do
+  awsEnv <- lazyAsk
+  runAmazonka awsEnv (sendAws req)
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data.hs
@@ -0,0 +1,17 @@
+module Effectful.Zoo.Amazonka.Data
+  ( module Effectful.Zoo.Amazonka.Data.AwsEnv,
+    module Effectful.Zoo.Amazonka.Data.AwsError,
+    module Effectful.Zoo.Amazonka.Data.AwsLogEntry,
+    module Effectful.Zoo.Amazonka.Data.AwsLogLevel,
+    module Effectful.Zoo.Amazonka.Data.AwsRequest,
+    module Effectful.Zoo.Amazonka.Data.AwsResponse,
+    module Effectful.Zoo.Amazonka.Data.AwsService,
+  ) where
+
+import Effectful.Zoo.Amazonka.Data.AwsEnv
+import Effectful.Zoo.Amazonka.Data.AwsError
+import Effectful.Zoo.Amazonka.Data.AwsLogEntry
+import Effectful.Zoo.Amazonka.Data.AwsLogLevel
+import Effectful.Zoo.Amazonka.Data.AwsRequest
+import Effectful.Zoo.Amazonka.Data.AwsResponse
+import Effectful.Zoo.Amazonka.Data.AwsService
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsEnv.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsEnv.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsEnv.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Amazonka.Data.AwsEnv
+  ( AwsEnv,
+  ) where
+
+import Amazonka qualified as AWS
+
+type AwsEnv = AWS.Env
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsError.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsError.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsError.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Amazonka.Data.AwsError
+  ( AwsError,
+  ) where
+
+import Amazonka qualified as AWS
+
+type AwsError = AWS.Error
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsLogEntry.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsLogEntry.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsLogEntry.hs
@@ -0,0 +1,16 @@
+module Effectful.Zoo.Amazonka.Data.AwsLogEntry
+  ( AwsLogEntry(..),
+  ) where
+
+import Data.ByteString.Builder
+import Effectful.Zoo.Amazonka.Data.AwsLogLevel
+import HaskellWorks.Prelude
+
+data AwsLogEntry = AwsLogEntry
+  { callStack :: CallStack
+  , logLevel  :: AwsLogLevel
+  , builder   :: Builder
+  }
+  deriving stock Generic
+  deriving stock Show
+  deriving stock Typeable
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsLogLevel.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsLogLevel.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsLogLevel.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Amazonka.Data.AwsLogLevel
+  ( AwsLogLevel,
+  ) where
+
+import Amazonka qualified as AWS
+
+type AwsLogLevel = AWS.LogLevel
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsRequest.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsRequest.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsRequest.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Amazonka.Data.AwsRequest
+  ( AwsRequest,
+  ) where
+
+import Amazonka qualified as AWS
+
+type AwsRequest a = AWS.AWSRequest a
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsResponse.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsResponse.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsResponse.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Amazonka.Data.AwsResponse
+  ( AwsResponse,
+  ) where
+
+import Amazonka qualified as AWS
+
+type AwsResponse a = AWS.AWSResponse a
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsService.hs b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsService.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Data/AwsService.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Amazonka.Data.AwsService
+  ( AwsService,
+  ) where
+
+import Amazonka qualified as AWS
+
+type AwsService = AWS.Service
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Dynamic.hs b/components/amazonka/Effectful/Zoo/Amazonka/Dynamic.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Dynamic.hs
@@ -0,0 +1,65 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Effectful.Zoo.Amazonka.Dynamic
+  ( Amazonka(..),
+
+    runAmazonka,
+    runAmazonkaM,
+  ) where
+
+import Amazonka qualified as AWS
+import Effectful
+import Effectful.Dispatch.Dynamic
+import Effectful.Resource
+import Effectful.Zoo.Amazonka.Data.AwsEnv
+import Effectful.Zoo.Amazonka.Data.AwsError
+import Effectful.Zoo.Amazonka.Data.AwsRequest
+import Effectful.Zoo.Amazonka.Data.AwsResponse
+import Effectful.Zoo.Amazonka.Static qualified as S
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+
+data Amazonka :: Effect where
+  AskAwsEnv
+      :: Amazonka m AwsEnv
+
+  LocalAwsEnv
+    :: (AwsEnv -> AwsEnv)
+    -> m a
+    -> Amazonka m a
+    
+  SendAws
+    :: ( HasCallStack
+       , AwsRequest a
+       , Typeable a
+       , Typeable (AwsResponse a)
+       )
+    => a
+    -> Amazonka m (Either AwsError (AwsResponse a))
+  
+type instance DispatchOf Amazonka = Dynamic
+
+runAmazonka :: forall a r. ()
+  => r <: IOE
+  => r <: Resource
+  => AwsEnv
+  -> Eff (Amazonka : r) a
+  -> Eff r a
+runAmazonka awsEnv =
+  reinterpret (S.runAmazonka awsEnv) $ \env -> \case
+    AskAwsEnv -> S.askAwsEnv
+    LocalAwsEnv f m -> do
+      localSeqUnlift env \unlift -> S.localAmazonka f (unlift m)
+    SendAws req -> do
+      awsEnv' <- S.askAwsEnv
+      AWS.sendEither awsEnv' req
+
+runAmazonkaM :: forall a r. ()
+  => r <: IOE
+  => r <: Resource
+  => Eff r AwsEnv
+  -> Eff (Amazonka : r) a
+  -> Eff r a
+runAmazonkaM mk f = do
+  awsEnv <- mk
+  runAmazonka awsEnv f
diff --git a/components/amazonka/Effectful/Zoo/Amazonka/Static.hs b/components/amazonka/Effectful/Zoo/Amazonka/Static.hs
new file mode 100644
--- /dev/null
+++ b/components/amazonka/Effectful/Zoo/Amazonka/Static.hs
@@ -0,0 +1,106 @@
+{- HLINT ignore "Use let" -}
+
+module Effectful.Zoo.Amazonka.Static
+  ( Amazonka,
+    runAmazonka,
+    withAmazonka,
+    localAmazonka,
+    askAwsEnv,
+    sendAws,
+    lazySendAws,
+  ) where
+
+import Amazonka qualified as AWS
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Resource
+import Data.Typeable
+import Effectful
+import Effectful.Dispatch.Static
+import Effectful.Error.Static
+import Effectful.Zoo.Amazonka.Data
+import Effectful.Zoo.Core
+import Effectful.Zoo.DataLog.Api
+import Effectful.Zoo.DataLog.Dynamic
+import Effectful.Zoo.Lazy.Dynamic
+import GHC.Stack qualified as GHC
+import HaskellWorks.Prelude
+
+data Amazonka :: Effect
+
+type instance DispatchOf Amazonka = Static WithSideEffects
+
+newtype instance StaticRep Amazonka = Amazonka AwsEnv
+
+runAmazonka :: forall a r. ()
+  => r <: IOE
+  => AwsEnv
+  -> Eff (Amazonka : r) a
+  -> Eff r a
+runAmazonka awsEnv =
+  evalStaticRep $ Amazonka awsEnv
+
+withAmazonka :: forall r a. ()
+  => HasCallStack
+  => r <: IOE
+  => (AwsEnv -> AwsEnv)
+  -> Eff (Amazonka : r) a
+  -> Eff (Amazonka : r) a
+withAmazonka f m = do
+  Amazonka awsEnv <- getStaticRep
+
+  raise $ runAmazonka (f awsEnv) m
+
+localAmazonka :: ()
+  => HasCallStack
+  => r <: Amazonka
+  => (AwsEnv -> AwsEnv)
+  -> Eff r a
+  -> Eff r a
+localAmazonka f =
+  localStaticRep $ \(Amazonka r) -> Amazonka (f r)
+
+askAwsEnv :: forall r. ()
+  => r <: Amazonka
+  => Eff r AwsEnv
+askAwsEnv = do
+  Amazonka awsEnv <- getStaticRep
+
+  pure awsEnv
+
+sendAws :: forall a r. ()
+  => HasCallStack
+  => AwsRequest a
+  => r <: Amazonka
+  => r <: DataLog AwsLogEntry
+  => r <: Error AwsError
+  => r <: IOE
+  => Typeable (AwsResponse a)
+  => Typeable a
+  => a
+  -> Eff r (AwsResponse a)
+sendAws req = GHC.withFrozenCallStack $ do
+  envAws0 <- askAwsEnv
+
+  envAws1 <- withEffToIO (ConcUnlift Persistent Unlimited) $ \effToIO ->
+    pure $ envAws0
+      { AWS.logger = \logLevel builder ->
+          effToIO $ dataLog $ AwsLogEntry GHC.callStack logLevel builder
+      }
+
+  liftIO (runResourceT $ AWS.sendEither envAws1 req)
+    & onLeftM throwError
+
+lazySendAws :: forall a r. ()
+  => HasCallStack
+  => AwsRequest a
+  => r <: DataLog AwsLogEntry
+  => r <: Error AwsError
+  => r <: IOE
+  => r <: Lazy AwsEnv
+  => Typeable (AwsResponse a)
+  => Typeable a
+  => a
+  -> Eff r (AwsResponse a)
+lazySendAws req = GHC.withFrozenCallStack $ do
+  awsEnv <- lazyAsk
+  runAmazonka awsEnv (sendAws req)
diff --git a/components/console/Effectful/Zoo/Console/Data/Writer.hs b/components/console/Effectful/Zoo/Console/Data/Writer.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Data/Writer.hs
@@ -0,0 +1,24 @@
+module Effectful.Zoo.Console.Data.Writer
+  ( Writer(..),
+    mkWriter,
+  ) where
+
+import Effectful
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+
+newtype Writer i = Writer
+  { run :: i -> IO ()
+  } deriving stock Generic
+
+instance Contravariant Writer where
+  contramap f (Writer g) = Writer (g . f)
+
+mkWriter :: ()
+  => r <: IOE
+  => UnliftStrategy
+  -> (i -> Eff r ())
+  -> Eff r (Writer i)
+mkWriter strategy run =
+  withEffToIO strategy $ \effToIO ->
+    pure $ Writer $ effToIO . run
diff --git a/components/console/Effectful/Zoo/Console/Dynamic.hs b/components/console/Effectful/Zoo/Console/Dynamic.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Dynamic.hs
@@ -0,0 +1,12 @@
+module Effectful.Zoo.Console.Dynamic
+  ( Console (..),
+
+    runConsole,
+    runConsoleBrackedToConsole,
+    runConsoleAtomic,
+
+    print,
+  ) where
+
+import Effectful.Zoo.Console.Dynamic.Api
+import Effectful.Zoo.Console.Dynamic.Run
diff --git a/components/console/Effectful/Zoo/Console/Dynamic/Api.hs b/components/console/Effectful/Zoo/Console/Dynamic/Api.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Dynamic/Api.hs
@@ -0,0 +1,18 @@
+module Effectful.Zoo.Console.Dynamic.Api
+  ( Console (..),
+    print,
+  ) where
+
+import Effectful
+import Effectful.Dispatch.Dynamic
+import Effectful.Zoo.Console.Dynamic.Effect
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+
+print :: ()
+  => HasCallStack
+  => r <: Console i
+  => i
+  -> Eff r ()
+print i =
+  send $ Print i
diff --git a/components/console/Effectful/Zoo/Console/Dynamic/Effect.hs b/components/console/Effectful/Zoo/Console/Dynamic/Effect.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Dynamic/Effect.hs
@@ -0,0 +1,17 @@
+module Effectful.Zoo.Console.Dynamic.Effect
+  ( Console (..),
+  ) where
+
+import Effectful
+
+data Console a :: Effect where
+  Print
+    :: a
+    -> Console a m ()
+
+  Local
+    :: (a -> a)
+    -> m b
+    -> Console a m b
+
+type instance DispatchOf (Console a) = Dynamic
diff --git a/components/console/Effectful/Zoo/Console/Dynamic/Run.hs b/components/console/Effectful/Zoo/Console/Dynamic/Run.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Dynamic/Run.hs
@@ -0,0 +1,53 @@
+module Effectful.Zoo.Console.Dynamic.Run
+  ( Console (..),
+    runConsole,
+    runConsoleBrackedToConsole,
+    runConsoleAtomic,
+  ) where
+
+import Effectful
+import Effectful.Exception
+import Effectful.Concurrent.QSem
+import Effectful.Dispatch.Dynamic
+import Effectful.Zoo.Console.Dynamic.Effect
+import Effectful.Zoo.Core
+import Effectful.Zoo.Console.Static qualified as S
+import HaskellWorks.Prelude
+
+runConsole :: ()
+  => HasCallStack
+  => r <: IOE
+  => UnliftStrategy
+  -> (HasCallStack => i -> Eff r ())
+  -> Eff (Console i : r) a
+  -> Eff r a
+runConsole s run =
+  reinterpret (S.runConsole s run) $ \env -> \case
+    Print i -> S.print i
+    Local f m -> localSeqUnlift env $ \unlift -> S.local f (unlift m)
+
+runConsoleBrackedToConsole :: ()
+  => HasCallStack
+  => r <: Console i
+  => Eff r b
+  -> Eff r c
+  -> Eff (Console i : r) a
+  -> Eff r a
+runConsoleBrackedToConsole before after =
+  interpret $ \env -> \case
+    Print i ->
+      bracket_ before after $
+        send $ Print i
+    Local f m ->
+      bracket_ before after $
+        localSeqUnlift env $ \unlift -> send $ Local f (unlift m)
+
+runConsoleAtomic :: ()
+  => HasCallStack
+  => r <: Concurrent
+  => r <: Console i
+  => Eff (Console i : r) a
+  -> Eff r a
+runConsoleAtomic f = do
+  qsem <- newQSem 1
+  runConsoleBrackedToConsole (waitQSem qsem) (signalQSem qsem) f
diff --git a/components/console/Effectful/Zoo/Console/Effect.hs b/components/console/Effectful/Zoo/Console/Effect.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Effect.hs
@@ -0,0 +1,5 @@
+module Effectful.Zoo.Console.Effect
+  ( Console,
+  ) where
+
+import Effectful.Console.ByteString
diff --git a/components/console/Effectful/Zoo/Console/Static.hs b/components/console/Effectful/Zoo/Console/Static.hs
new file mode 100644
--- /dev/null
+++ b/components/console/Effectful/Zoo/Console/Static.hs
@@ -0,0 +1,103 @@
+module Effectful.Zoo.Console.Static
+  ( Console,
+    runConsole,
+    runConsoleTextToHandle,
+    runConsoleTextToStdout,
+    runConsoleTextToStderr,
+    withConsole,
+    print,
+    local,
+  ) where
+
+import Data.Text.IO qualified as T
+import Data.Kind
+import Effectful
+import Effectful.Zoo.Console.Data.Writer
+import Effectful.Zoo.Core
+import Effectful.Dispatch.Static
+import HaskellWorks.Prelude
+import System.IO qualified as IO
+
+data Console (i :: Type) :: Effect
+
+type instance DispatchOf (Console i) = Static NoSideEffects
+
+newtype instance StaticRep (Console i) = Console (Writer i)
+
+runConsole :: ()
+  => r <: IOE
+  => HasCallStack
+  => UnliftStrategy
+  -> (HasCallStack => i -> Eff r ())
+  -> Eff (Console i : r) a
+  -> Eff r a
+runConsole strategy run f = do
+  s <- mkWriter strategy run
+  evalStaticRep (Console s) f
+
+runConsoleTextToHandle :: ()
+  => HasCallStack
+  => Handle
+  -> Eff (Console Text : r) a
+  -> Eff r a
+runConsoleTextToHandle h =
+  evalStaticRep $ Console $ Writer $ T.hPutStrLn h
+
+runConsoleTextToStdout :: ()
+  => HasCallStack
+  => Eff (Console Text : r) a
+  -> Eff r a
+runConsoleTextToStdout =
+  runConsoleTextToHandle IO.stdout
+
+runConsoleTextToStderr :: ()
+  => HasCallStack
+  => Eff (Console Text : r) a
+  -> Eff r a
+runConsoleTextToStderr =
+  runConsoleTextToHandle IO.stderr
+
+withConsoleSerialiser :: ()
+  => HasCallStack
+  => (Writer i -> Writer o)
+  -> Eff (Console o : r) a
+  -> Eff (Console i : r) a
+withConsoleSerialiser f m = do
+  writer <- getWriter
+  let _ = writer
+  raise $ evalStaticRep (Console (f writer)) m
+
+withConsole :: ()
+  => HasCallStack
+  => (o -> i)
+  -> Eff (Console o : r) a
+  -> Eff (Console i : r) a
+withConsole =
+  withConsoleSerialiser . contramap
+
+getWriter :: ()
+  => HasCallStack
+  => r <: Console i
+  => Eff r (Writer i)
+getWriter = do
+  Console i <- getStaticRep
+  pure i
+
+print :: ()
+  => HasCallStack
+  => r <: Console i
+  => r <: IOE
+  => i
+  -> Eff r ()
+print i = do
+  writer <- getWriter
+  liftIO $ writer.run i
+
+local :: ()
+  => HasCallStack
+  => r <: Console i
+  => (i -> i)
+  -> Eff r a
+  -> Eff r a
+local f =
+  localStaticRep $ \(Console s) -> Console (contramap f s)
diff --git a/components/core/Effectful/Zoo/Core.hs b/components/core/Effectful/Zoo/Core.hs
--- a/components/core/Effectful/Zoo/Core.hs
+++ b/components/core/Effectful/Zoo/Core.hs
@@ -2,6 +2,4 @@
   ( type (<:)
   ) where
 
-import           Effectful ((:>))
-
-type (<:) r e = (:>) e r
+import           Effectful.Zoo.Core.Prim
diff --git a/components/core/Effectful/Zoo/Core/Error/Dynamic.hs b/components/core/Effectful/Zoo/Core/Error/Dynamic.hs
new file mode 100644
--- /dev/null
+++ b/components/core/Effectful/Zoo/Core/Error/Dynamic.hs
@@ -0,0 +1,100 @@
+module Effectful.Zoo.Core.Error.Dynamic
+  ( Error,
+    catch,
+    catch_,
+    throw,
+    trap,
+    trap_,
+
+    catchWithCallStack,
+    catchWithCallStack_,
+    trapWithCallStack,
+    trapWithCallStack_,
+  ) where
+
+import Effectful
+import Effectful.Error.Dynamic (Error)
+import Effectful.Error.Dynamic qualified as E
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+
+catchWithCallStack :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> (CallStack -> e -> Eff es a)
+  -> Eff es a
+catchWithCallStack =
+  E.catchError
+
+catchWithCallStack_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> (CallStack -> Eff es a)
+  -> Eff es a
+catchWithCallStack_ f h =
+  catchWithCallStack @e f \cs _ -> h cs
+
+trapWithCallStack :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => (CallStack -> e -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trapWithCallStack =
+  flip catchWithCallStack
+
+trapWithCallStack_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => (CallStack -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trapWithCallStack_ h =
+  trapWithCallStack @e (const . h)
+
+catch :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> (e -> Eff es a)
+  -> Eff es a
+catch action handler =
+  catchWithCallStack action (const handler)
+
+catch_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> Eff es a
+  -> Eff es a
+catch_ action handler =
+  catch @e action (const handler)
+
+throw :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Show e
+  => e
+  -> Eff es a
+throw =
+  E.throwError
+
+trap :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => (e -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trap =
+  flip catch
+
+trap_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> Eff es a
+  -> Eff es a
+trap_ handler =
+  trap @e (const handler)
diff --git a/components/core/Effectful/Zoo/Core/Error/Static.hs b/components/core/Effectful/Zoo/Core/Error/Static.hs
new file mode 100644
--- /dev/null
+++ b/components/core/Effectful/Zoo/Core/Error/Static.hs
@@ -0,0 +1,175 @@
+module Effectful.Zoo.Core.Error.Static
+  ( Error,
+
+    throw,
+
+    catch,
+    catch_,
+    trap,
+    trap_,
+
+    catchWithCallStack,
+    catchWithCallStack_,
+    trapWithCallStack,
+    trapWithCallStack_,
+
+    catchIn,
+    catchIn_,
+    trapIn,
+    trapIn_,
+
+    catchWithCallStackIn,
+    catchWithCallStackIn_,
+    trapWithCallStackIn,
+    trapWithCallStackIn_,
+  ) where
+
+import Effectful
+import Effectful.Error.Static (Error)
+import Effectful.Error.Static qualified as E
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+
+throw :: forall e r a. ()
+  => HasCallStack
+  => r <: Error e
+  => Show e
+  => e
+  -> Eff r a
+throw =
+  E.throwError
+
+catchWithCallStack :: forall e r a. ()
+  => HasCallStack
+  => Eff (Error e : r) a
+  -> (CallStack -> e -> Eff r a)
+  -> Eff r a
+catchWithCallStack action handler =
+  E.runError action
+    & onLeftM (uncurry handler)
+
+catchWithCallStack_ :: forall e r a. ()
+  => HasCallStack
+  => Eff (Error e : r) a
+  -> (CallStack -> Eff r a)
+  -> Eff r a
+catchWithCallStack_ f h =
+  catchWithCallStack @e f \cs _ -> h cs
+
+trapWithCallStack :: forall e r a. ()
+  => HasCallStack
+  => (CallStack -> e -> Eff r a)
+  -> Eff (Error e : r) a
+  -> Eff r a
+trapWithCallStack =
+  flip catchWithCallStack
+
+trapWithCallStack_ :: forall e r a. ()
+  => HasCallStack
+  => (CallStack -> Eff r a)
+  -> Eff (Error e : r) a
+  -> Eff r a
+trapWithCallStack_ h =
+  trapWithCallStack @e (const . h)
+
+catch :: forall e r a. ()
+  => Eff (Error e : r) a
+  -> (e -> Eff r a)
+  -> Eff r a
+catch action handler =
+  E.runError action
+    & onLeftM (handler . snd)
+
+catch_ :: forall e r a. ()
+  => Eff (Error e : r) a
+  -> Eff r a
+  -> Eff r a
+catch_ action handler =
+  catch @e action (const handler)
+
+trap :: forall e r a. ()
+  => (e -> Eff r a)
+  -> Eff (Error e : r) a
+  -> Eff r a
+trap =
+  flip catch
+
+trap_ :: forall e r a. ()
+  => Eff r a
+  -> Eff (Error e : r) a
+  -> Eff r a
+trap_ handler =
+  trap @e (const handler)
+
+
+catchWithCallStackIn :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> (CallStack -> e -> Eff es a)
+  -> Eff es a
+catchWithCallStackIn =
+  E.catchError
+
+catchWithCallStackIn_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> (CallStack -> Eff es a)
+  -> Eff es a
+catchWithCallStackIn_ f h =
+  catchWithCallStackIn @e f \cs _ -> h cs
+
+trapWithCallStackIn :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => (CallStack -> e -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trapWithCallStackIn =
+  flip catchWithCallStackIn
+
+trapWithCallStackIn_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => (CallStack -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trapWithCallStackIn_ h =
+  trapWithCallStackIn @e (const . h)
+
+catchIn :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> (e -> Eff es a)
+  -> Eff es a
+catchIn action handler =
+  catchWithCallStackIn action (const handler)
+
+catchIn_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> Eff es a
+  -> Eff es a
+catchIn_ action handler =
+  catchIn @e action (const handler)
+
+trapIn :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => (e -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trapIn =
+  flip catchIn
+
+trapIn_ :: forall e es a. ()
+  => HasCallStack
+  => es <: Error e
+  => Eff es a
+  -> Eff es a
+  -> Eff es a
+trapIn_ handler =
+  trapIn @e (const handler)
diff --git a/components/core/Effectful/Zoo/Core/Exception.hs b/components/core/Effectful/Zoo/Core/Exception.hs
new file mode 100644
--- /dev/null
+++ b/components/core/Effectful/Zoo/Core/Exception.hs
@@ -0,0 +1,35 @@
+module Effectful.Zoo.Core.Exception
+  ( Exception,
+    catchIO,
+    throwIO,
+    trapIO,
+  ) where
+
+import Effectful
+import Effectful.Exception (Exception)
+import Effectful.Exception qualified as E
+import HaskellWorks.Prelude
+
+catchIO :: ()
+  => E.Exception e
+  => Eff es a
+  -> (e -> Eff es a)
+  -> Eff es a
+catchIO =
+  E.catch
+
+throwIO :: ()
+  => HasCallStack
+  => E.Exception e
+  => e
+  -> Eff es a
+throwIO =
+  E.throwIO
+
+trapIO
+  :: E.Exception e
+  => (e -> Eff es a)
+  -> Eff es a
+  -> Eff es a
+trapIO =
+  flip catchIO
diff --git a/components/core/Effectful/Zoo/Core/Function.hs b/components/core/Effectful/Zoo/Core/Function.hs
new file mode 100644
--- /dev/null
+++ b/components/core/Effectful/Zoo/Core/Function.hs
@@ -0,0 +1,26 @@
+module Effectful.Zoo.Core.Function
+  ( once,
+  ) where
+
+import Effectful
+import Effectful.Concurrent
+import Effectful.Concurrent.MVar
+import Effectful.Zoo.Core.Prim
+import HaskellWorks.Prelude
+
+once :: ()
+  => r <: Concurrent
+  => Eff r a
+  -> Eff r (Eff r a)
+once f = do
+  cache <- newMVar Nothing
+  return $ do
+    resultOrRunning <- takeMVar cache
+    case resultOrRunning of
+      Just result -> do
+        putMVar cache (Just result)
+        return result
+      Nothing -> do
+        result <- f
+        putMVar cache (Just result)
+        return result
diff --git a/components/core/Effectful/Zoo/Core/Prim.hs b/components/core/Effectful/Zoo/Core/Prim.hs
new file mode 100644
--- /dev/null
+++ b/components/core/Effectful/Zoo/Core/Prim.hs
@@ -0,0 +1,7 @@
+module Effectful.Zoo.Core.Prim
+  ( type (<:)
+  ) where
+
+import           Effectful ((:>))
+
+type (<:) r e = (:>) e r
diff --git a/components/datalog/Effectful/Zoo/DataLog/Api.hs b/components/datalog/Effectful/Zoo/DataLog/Api.hs
--- a/components/datalog/Effectful/Zoo/DataLog/Api.hs
+++ b/components/datalog/Effectful/Zoo/DataLog/Api.hs
@@ -6,7 +6,7 @@
 import Effectful.Dispatch.Dynamic
 import Effectful.Zoo.Core
 import Effectful.Zoo.DataLog.Dynamic
-import HaskellWorks.Prelude hiding (log)
+import HaskellWorks.Prelude
 
 dataLog :: ()
   => HasCallStack
@@ -16,4 +16,3 @@
 dataLog i =
   withFrozenCallStack do
     send $ DataLog i
-{-# inline dataLog #-}
diff --git a/components/datalog/Effectful/Zoo/DataLog/Data/DataLogger.hs b/components/datalog/Effectful/Zoo/DataLog/Data/DataLogger.hs
--- a/components/datalog/Effectful/Zoo/DataLog/Data/DataLogger.hs
+++ b/components/datalog/Effectful/Zoo/DataLog/Data/DataLogger.hs
@@ -4,8 +4,8 @@
   ) where
 
 import Effectful
-import Effectful.Zoo.Core
-import HaskellWorks.Prelude hiding (Floating(..))
+import Effectful.Dispatch.Static
+import HaskellWorks.Prelude
 
 newtype DataLogger i = DataLogger
   { run :: i -> IO ()
@@ -15,10 +15,8 @@
   contramap f (DataLogger g) = DataLogger (g . f)
 
 mkDataLogger :: ()
-  => r <: IOE
-  => UnliftStrategy
-  -> (i -> Eff r ())
+  => (i -> Eff r ())
   -> Eff r (DataLogger i)
-mkDataLogger strategy run =
-  withEffToIO strategy $ \effToIO ->
+mkDataLogger run =
+  unsafeConcUnliftIO Persistent Unlimited $ \effToIO ->
     pure $ DataLogger $ effToIO . run
diff --git a/components/datalog/Effectful/Zoo/DataLog/Dynamic.hs b/components/datalog/Effectful/Zoo/DataLog/Dynamic.hs
--- a/components/datalog/Effectful/Zoo/DataLog/Dynamic.hs
+++ b/components/datalog/Effectful/Zoo/DataLog/Dynamic.hs
@@ -5,7 +5,6 @@
 
 import Effectful
 import Effectful.Dispatch.Dynamic
-import Effectful.Zoo.Core
 import Effectful.Zoo.DataLog.Static qualified as S
 import HaskellWorks.Prelude
 
@@ -23,12 +22,10 @@
 
 runDataLog :: ()
   => HasCallStack
-  => r <: IOE
-  => UnliftStrategy
-  -> (HasCallStack => i -> Eff r ())
+  => (HasCallStack => i -> Eff r ())
   -> Eff (DataLog i : r) a
   -> Eff r a
-runDataLog s run =
-  reinterpret (S.runDataLog s run) $ \env -> \case
+runDataLog run =
+  reinterpret (S.runDataLog run) $ \env -> \case
     DataLog i -> S.log i
     Local f m -> localSeqUnlift env $ \unlift -> S.local f (unlift m)
diff --git a/components/datalog/Effectful/Zoo/DataLog/Static.hs b/components/datalog/Effectful/Zoo/DataLog/Static.hs
--- a/components/datalog/Effectful/Zoo/DataLog/Static.hs
+++ b/components/datalog/Effectful/Zoo/DataLog/Static.hs
@@ -15,7 +15,7 @@
 import Effectful.Zoo.Core
 import Effectful.Dispatch.Static
 import Effectful.Zoo.DataLog.Data.DataLogger
-import HaskellWorks.Prelude hiding (Floating(..))
+import HaskellWorks.Prelude
 import System.IO qualified as IO
 
 data DataLog (i :: Type) :: Effect
@@ -24,15 +24,13 @@
 
 newtype instance StaticRep (DataLog i) = DataLog (DataLogger i)
 
-runDataLog :: ()
-  => r <: IOE
+runDataLog :: forall i a r. ()
   => HasCallStack
-  => UnliftStrategy
-  -> (HasCallStack => i -> Eff r ())
+  => (HasCallStack => i -> Eff r ())
   -> Eff (DataLog i : r) a
   -> Eff r a
-runDataLog strategy run f = do
-  s <- mkDataLogger strategy run
+runDataLog run f = do
+  s <- mkDataLogger run
   evalStaticRep (DataLog s) f
 
 runDataLogTextToHandle :: ()
@@ -86,12 +84,11 @@
 log :: ()
   => HasCallStack
   => r <: DataLog i
-  => r <: IOE
   => i
   -> Eff r ()
 log i = do
   dataLogger <- getDataLogger
-  liftIO $ dataLogger.run i
+  unsafeEff_ $ dataLogger.run i
 
 local :: ()
   => HasCallStack
diff --git a/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Assert.hs b/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Assert.hs
--- a/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Assert.hs
+++ b/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Assert.hs
@@ -2,11 +2,16 @@
   ( assert,
     (===),
     (/==),
+    onNothingFail,
+    onNothingFailM,
+    onLeftFail,
+    onLeftFailM,
   ) where
 
 import Effectful
 import Effectful.Dispatch.Dynamic
 import Effectful.Zoo.Core
+import Effectful.Zoo.Hedgehog.Api.Failure
 import Effectful.Zoo.Hedgehog.Dynamic
 import HaskellWorks.Prelude
 import Hedgehog qualified as H
@@ -45,3 +50,45 @@
 (/==) a b =
   withFrozenCallStack $
     a H./== b
+
+onNothingFail :: forall a r. ()
+  => HasCallStack
+  => r <: Hedgehog
+  => Maybe a
+  -> Eff r a
+onNothingFail mv =
+  withFrozenCallStack $
+    case mv of
+      Just a -> pure a
+      Nothing -> failWith Nothing "Expected Just, but got Nothing"
+
+onNothingFailM :: forall a r. ()
+  => HasCallStack
+  => r <: Hedgehog
+  => Eff r (Maybe a)
+  -> Eff r a
+onNothingFailM f =
+  withFrozenCallStack $
+    f >>= onNothingFail
+
+onLeftFail :: forall e a r. ()
+  => HasCallStack
+  => Show e
+  => r <: Hedgehog
+  => Either e a
+  -> Eff r a
+onLeftFail ea =
+  withFrozenCallStack $
+    case ea of
+      Right a -> pure a
+      Left e -> failWith Nothing $ "Expected Just, but got Left: " <> show e
+
+onLeftFailM :: forall e a r. ()
+  => HasCallStack
+  => Show e
+  => r <: Hedgehog
+  => Eff r (Either e a)
+  -> Eff r a
+onLeftFailM f =
+  withFrozenCallStack $
+    f >>= onLeftFail
diff --git a/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Journal.hs b/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Journal.hs
--- a/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Journal.hs
+++ b/components/hedgehog/Effectful/Zoo/Hedgehog/Api/Journal.hs
@@ -39,6 +39,8 @@
 
     jotLogTextWithCallStack,
 
+    jotShowDataLog,
+
     writeLog,
   ) where
 
@@ -55,6 +57,8 @@
 import Effectful
 import Effectful.Dispatch.Dynamic
 import Effectful.Zoo.Core
+import Effectful.Zoo.DataLog.Dynamic
+import Effectful.Zoo.DataLog.Dynamic qualified as DataLog
 import Effectful.Zoo.Hedgehog.Api.Eval
 import Effectful.Zoo.Hedgehog.Api.Failure
 import Effectful.Zoo.Hedgehog.Dynamic
@@ -520,6 +524,17 @@
 jotLogTextWithCallStack cs severity a =
   withFrozenCallStack do
     jotWithCallStack cs $ T.unpack $ "[" <> toText severity <> "] " <> a
+
+jotShowDataLog :: forall i a r. ()
+  => HasCallStack
+  => Show i
+  => r <: Hedgehog
+  => Eff (DataLog i : r) a
+  -> Eff r a
+jotShowDataLog =
+  withFrozenCallStack $
+    DataLog.runDataLog jotShow_
+{-# inline jotShowDataLog #-}
 
 writeLog :: forall r. ()
   => HasCallStack
diff --git a/components/hunit/Effectful/Zoo/HUnit.hs b/components/hunit/Effectful/Zoo/HUnit.hs
new file mode 100644
--- /dev/null
+++ b/components/hunit/Effectful/Zoo/HUnit.hs
@@ -0,0 +1,27 @@
+module Effectful.Zoo.HUnit
+  ( requireTest,
+  ) where
+
+import Control.Monad.IO.Class
+import Data.List qualified as L
+import GHC.Stack (SrcLoc)
+import GHC.Stack qualified as GHC
+import HaskellWorks.Prelude
+import Hedgehog
+import Test.HUnit.Lang
+
+import qualified Control.Exception as E
+
+location :: HasCallStack => Maybe SrcLoc
+location = case L.reverse (GHC.getCallStack GHC.callStack) of
+  (_, loc) : _ -> Just loc
+  []           -> Nothing
+
+require :: HasCallStack => Property -> Assertion
+require p = do
+  result <- liftIO $ check p
+  unless result $
+    E.throwIO (HUnitFailure location $ Reason "Hedgehog property test failed")
+
+requireTest :: HasCallStack => TestT IO () -> Assertion
+requireTest = require . withTests 1 . property . test
diff --git a/components/lazy/Effectful/Zoo/Lazy/Dynamic.hs b/components/lazy/Effectful/Zoo/Lazy/Dynamic.hs
new file mode 100644
--- /dev/null
+++ b/components/lazy/Effectful/Zoo/Lazy/Dynamic.hs
@@ -0,0 +1,44 @@
+module Effectful.Zoo.Lazy.Dynamic
+  ( Lazy(..),
+    runLazy,
+    lazyAsk,
+  ) where
+
+import Effectful
+import Effectful.Concurrent.MVar
+import Effectful.Dispatch.Dynamic
+import Effectful.Zoo.Core
+import HaskellWorks.Prelude
+
+data Lazy i :: Effect where
+  LazyAsk
+    :: Lazy i m i
+
+type instance DispatchOf (Lazy i) = Dynamic
+
+runLazy :: forall i a r. ()
+  => r <: Concurrent
+  => Eff r i
+  -> Eff (Lazy i : r) a
+  -> Eff r a
+runLazy f h = do
+  mvCache <- newMVar @_ @(Maybe i) Nothing
+  interpret
+    do \_ -> \case
+        LazyAsk -> do
+          resultOrRunning <- takeMVar mvCache
+          case resultOrRunning of
+            Just result -> do
+              putMVar mvCache (Just result)
+              return result
+            Nothing -> do
+              result <- f
+              putMVar mvCache (Just result)
+              return result
+    do h
+
+lazyAsk :: ()
+  => r <: Lazy i
+  => Eff r i
+lazyAsk =
+  send LazyAsk
diff --git a/components/log/Effectful/Zoo/Log/Api/Generic.hs b/components/log/Effectful/Zoo/Log/Api/Generic.hs
--- a/components/log/Effectful/Zoo/Log/Api/Generic.hs
+++ b/components/log/Effectful/Zoo/Log/Api/Generic.hs
@@ -13,7 +13,7 @@
 import Effectful.Zoo.Core
 import Effectful.Zoo.Log.Data.Severity
 import Effectful.Zoo.Log.Dynamic
-import HaskellWorks.Prelude hiding (log)
+import HaskellWorks.Prelude
 
 log :: ()
   => HasCallStack
diff --git a/components/log/Effectful/Zoo/Log/Api/LazyText.hs b/components/log/Effectful/Zoo/Log/Api/LazyText.hs
--- a/components/log/Effectful/Zoo/Log/Api/LazyText.hs
+++ b/components/log/Effectful/Zoo/Log/Api/LazyText.hs
@@ -13,7 +13,7 @@
 import Effectful.Zoo.Core
 import Effectful.Zoo.Log.Data.Severity
 import Effectful.Zoo.Log.Dynamic
-import HaskellWorks.Prelude hiding (log)
+import HaskellWorks.Prelude
 
 log :: ()
   => HasCallStack
diff --git a/components/log/Effectful/Zoo/Log/Api/Render.hs b/components/log/Effectful/Zoo/Log/Api/Render.hs
--- a/components/log/Effectful/Zoo/Log/Api/Render.hs
+++ b/components/log/Effectful/Zoo/Log/Api/Render.hs
@@ -3,7 +3,7 @@
   ) where
 
 import Effectful.Zoo.Log.Data.Severity
-import HaskellWorks.Prelude hiding (log)
+import HaskellWorks.Prelude
 import HaskellWorks.ToText
 
 defaultRenderLogToText :: ToText i => Severity -> i -> Text
diff --git a/components/log/Effectful/Zoo/Log/Api/String.hs b/components/log/Effectful/Zoo/Log/Api/String.hs
--- a/components/log/Effectful/Zoo/Log/Api/String.hs
+++ b/components/log/Effectful/Zoo/Log/Api/String.hs
@@ -13,7 +13,7 @@
 import Effectful.Zoo.Core
 import Effectful.Zoo.Log.Data.Severity
 import Effectful.Zoo.Log.Dynamic
-import HaskellWorks.Prelude hiding (log)
+import HaskellWorks.Prelude
 
 log :: ()
   => HasCallStack
diff --git a/components/log/Effectful/Zoo/Log/Api/Text.hs b/components/log/Effectful/Zoo/Log/Api/Text.hs
--- a/components/log/Effectful/Zoo/Log/Api/Text.hs
+++ b/components/log/Effectful/Zoo/Log/Api/Text.hs
@@ -13,7 +13,7 @@
 import Effectful.Zoo.Core
 import Effectful.Zoo.Log.Data.Severity
 import Effectful.Zoo.Log.Dynamic
-import HaskellWorks.Prelude hiding (log)
+import HaskellWorks.Prelude
 
 log :: ()
   => HasCallStack
diff --git a/components/log/Effectful/Zoo/Log/Data/Logger.hs b/components/log/Effectful/Zoo/Log/Data/Logger.hs
--- a/components/log/Effectful/Zoo/Log/Data/Logger.hs
+++ b/components/log/Effectful/Zoo/Log/Data/Logger.hs
@@ -6,7 +6,7 @@
 import Effectful
 import Effectful.Zoo.Core
 import Effectful.Zoo.Log.Data.Severity
-import HaskellWorks.Prelude hiding (Floating(..))
+import HaskellWorks.Prelude
 
 newtype Logger i = Logger
   { run :: CallStack -> Severity -> i -> IO ()
diff --git a/components/log/Effectful/Zoo/Log/Static.hs b/components/log/Effectful/Zoo/Log/Static.hs
--- a/components/log/Effectful/Zoo/Log/Static.hs
+++ b/components/log/Effectful/Zoo/Log/Static.hs
@@ -17,8 +17,7 @@
 import Effectful.Zoo.Log.Data.Logger
 import Effectful.Zoo.Log.Data.Severity
 import GHC.Stack qualified as GHC
-import HaskellWorks.Prelude hiding (Floating(..))
-import System.IO (Handle)
+import HaskellWorks.Prelude
 import System.IO qualified as IO
 
 data Log (i :: Type) :: Effect
diff --git a/effectful-zoo.cabal b/effectful-zoo.cabal
--- a/effectful-zoo.cabal
+++ b/effectful-zoo.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.4
 
 name:                   effectful-zoo
-version:                0.0.0.1
+version:                0.0.1.0
 synopsis:               Effectful effects for testing
 description:            See https://hackage.haskell.org/package/effectful-zoo/docs/effectful-zoo.html
 category:               Development
@@ -24,12 +24,18 @@
 
 common aeson                      { build-depends: aeson                      >= 2.2.3      && < 3      }
 common aeson-pretty               { build-depends: aeson-pretty               >= 0.8.10     && < 1      }
+common amazonka                   { build-depends: amazonka                   >= 2          && < 3      }
 common bytestring                 { build-depends: bytestring                 >= 0.11       && < 1      }
 common effectful                  { build-depends: effectful                  >= 2.5        && < 3      }
 common effectful-core             { build-depends: effectful-core             >= 2.5        && < 3      }
 common effectful-plugin           { build-depends: effectful-plugin           >= 1.1.0.4    && < 2      }
+common generic-lens               { build-depends: generic-lens               >= 2.2.2      && < 3      }
 common hedgehog                   { build-depends: hedgehog                   >= 1.5        && < 2      }
-common hw-prelude                 { build-depends: hw-prelude                 >= 0.0.2.0    && < 0.2    }
+common HUnit                      { build-depends: HUnit                      >= 1.6.2      && < 2      }
+common hw-prelude                 { build-depends: hw-prelude                 >= 0.0.4      && < 0.1    }
+common microlens                  { build-depends: microlens                  >= 0.4.13.1   && < 0.5    }
+common resourcet                  { build-depends: resourcet                  >= 1.3        && < 2      }
+common resourcet-effectful        { build-depends: resourcet-effectful        >= 1.0.1      && < 2      }
 common tasty                      { build-depends: tasty                      >= 1.4.3      && < 1.5    }
 common tasty-hedgehog             { build-depends: tasty-hedgehog             >= 1.1.0.0    && < 1.5    }
 common text                       { build-depends: text                       >= 2          && < 3      }
@@ -37,9 +43,12 @@
 common transformers               { build-depends: transformers               >= 0.5.6.2    && < 0.7    }
 common yaml                       { build-depends: yaml                       >= 0.11.11.2  && < 1      }
 
+common effectful-zoo-amazonka     { build-depends: effectful-zoo:amazonka                               }
 common effectful-zoo-core         { build-depends: effectful-zoo:core                                   }
+common effectful-zoo-datalog      { build-depends: effectful-zoo:datalog                                }
 common effectful-zoo-hedgehog     { build-depends: effectful-zoo:hedgehog                               }
 common effectful-zoo-log          { build-depends: effectful-zoo:log                                    }
+common effectful-zoo-lazy         { build-depends: effectful-zoo:lazy                                   }
 
 common project-config
   default-extensions:   AllowAmbiguousTypes
@@ -90,10 +99,72 @@
 library core
   import:               project-config,
                         effectful,
+                        hw-prelude,
   visibility:           public
   exposed-modules:      Effectful.Zoo.Core
+                        Effectful.Zoo.Core.Error.Dynamic
+                        Effectful.Zoo.Core.Error.Static
+                        Effectful.Zoo.Core.Exception
+                        Effectful.Zoo.Core.Function
+                        Effectful.Zoo.Core.Prim
   hs-source-dirs:       components/core
 
+library amazonka
+  import:               base, project-config,
+                        amazonka,
+                        bytestring,
+                        effectful,
+                        effectful-core,
+                        effectful-plugin,
+                        effectful-zoo-core,
+                        effectful-zoo-datalog,
+                        effectful-zoo-lazy,
+                        effectful-zoo-log,
+                        generic-lens,
+                        hw-prelude,
+                        microlens,
+                        resourcet,
+                        resourcet-effectful,
+                        text,
+                        time,
+  visibility:           public
+  exposed-modules:      Effectful.Zoo.Amazonka.Api
+                        Effectful.Zoo.Amazonka.Api.Discover
+                        Effectful.Zoo.Amazonka.Api.Log
+                        Effectful.Zoo.Amazonka.Api.Run
+                        Effectful.Zoo.Amazonka.Api.Send
+                        Effectful.Zoo.Amazonka.Data
+                        Effectful.Zoo.Amazonka.Data.AwsError
+                        Effectful.Zoo.Amazonka.Data.AwsEnv
+                        Effectful.Zoo.Amazonka.Data.AwsLogEntry
+                        Effectful.Zoo.Amazonka.Data.AwsLogLevel
+                        Effectful.Zoo.Amazonka.Data.AwsRequest
+                        Effectful.Zoo.Amazonka.Data.AwsResponse
+                        Effectful.Zoo.Amazonka.Data.AwsService
+                        Effectful.Zoo.Amazonka.Dynamic
+                        Effectful.Zoo.Amazonka.Static
+  ghc-options:          -fplugin=Effectful.Plugin
+  hs-source-dirs:       components/amazonka
+
+library console
+  import:               base, project-config,
+                        effectful,
+                        effectful-core,
+                        effectful-plugin,
+                        effectful-zoo-core,
+                        hw-prelude,
+                        text,
+  visibility:           public
+  exposed-modules:      Effectful.Zoo.Console.Data.Writer
+                        Effectful.Zoo.Console.Dynamic
+                        Effectful.Zoo.Console.Dynamic.Api
+                        Effectful.Zoo.Console.Dynamic.Effect
+                        Effectful.Zoo.Console.Dynamic.Run
+                        Effectful.Zoo.Console.Effect
+                        Effectful.Zoo.Console.Static
+  ghc-options:          -fplugin=Effectful.Plugin
+  hs-source-dirs:       components/console
+
 library datalog
   import:               base, project-config,
                         effectful-core,
@@ -119,6 +190,7 @@
                         effectful-core,
                         effectful-plugin,
                         effectful-zoo-core,
+                        effectful-zoo-datalog,
                         effectful-zoo-log,
                         hedgehog,
                         hw-prelude,
@@ -140,6 +212,27 @@
                         Effectful.Zoo.Hedgehog.MonadTestProxy
   ghc-options:          -fplugin=Effectful.Plugin
   hs-source-dirs:       components/hedgehog
+
+library hunit
+  import:               base, project-config,
+                        hedgehog,
+                        HUnit,
+                        hw-prelude,
+  visibility:           public
+  exposed-modules:      Effectful.Zoo.HUnit
+  hs-source-dirs:       components/hunit
+
+library lazy
+  import:               project-config,
+                        effectful,
+                        effectful-core,
+                        effectful-plugin,
+                        effectful-zoo-core,
+                        hw-prelude,
+  visibility:           public
+  exposed-modules:      Effectful.Zoo.Lazy.Dynamic
+  ghc-options:          -fplugin=Effectful.Plugin
+  hs-source-dirs:       components/lazy
 
 library log
   import:               base, project-config,
