diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,10 @@
+0.4.0
+===
+
+  * I don't think a major version bump was strictly necessary, but did it anyway to be on the safe side.
+
+  * Supported lts-22.43 (GHC 9.6.6)
+
 0.3.0
 ===
 
diff --git a/ldap-client-og.cabal b/ldap-client-og.cabal
--- a/ldap-client-og.cabal
+++ b/ldap-client-og.cabal
@@ -1,95 +1,88 @@
-name:                ldap-client-og
-version:             0.3.0
-synopsis:            Pure Haskell LDAP Client Library
-description:
-  Pure Haskell LDAP client library implementing (the parts of) RFC 4511.
-homepage:            https://supki.github.io/ldap-client
-license:             BSD2
-license-file:        LICENSE
-author:              Matvey Aksenov
-maintainer:          matvey.aksenov@gmail.com
-copyright:           2015 Matvey Aksenov
-category:            Network
-build-type:          Simple
-cabal-version:       >= 1.10
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.37.0.
+--
+-- see: https://github.com/sol/hpack
+
+name:           ldap-client-og
+version:        0.4.0
+synopsis:       Pure Haskell LDAP Client Library
+description:    Pure Haskell LDAP client library implementing (parts of) RFC 4511.
+category:       Network
+homepage:       https://github.com/supki/ldap-client#readme
+bug-reports:    https://github.com/supki/ldap-client/issues
+maintainer:     matvey.aksenov@gmail.com
+copyright:      Matvey Aksenov 2015
+license:        BSD2
+license-file:   LICENSE
+build-type:     Simple
 tested-with:
-    GHC == 7.6.3
-  , GHC == 7.8.4
-  , GHC == 7.10.1
-  , GHC == 8.0.1
+    GHC==9.6.6
 extra-source-files:
-  README.markdown
-  CHANGELOG.markdown
+    README.markdown
+    CHANGELOG.markdown
 
 source-repository head
-  type:     git
-  location: git@github.com:supki/ldap-client
-  tag:      0.3.0
+  type: git
+  location: https://github.com/supki/ldap-client
 
 library
-  ghc-options:
-    -Wall
-    -fwarn-incomplete-uni-patterns
-    -fwarn-incomplete-record-updates
-    -fwarn-unrecognised-pragmas
-  default-language:
-    Haskell2010
-  hs-source-dirs:
-    src
   exposed-modules:
-    Ldap.Asn1.FromAsn1
-    Ldap.Asn1.ToAsn1
-    Ldap.Asn1.Type
-    Ldap.Client
-    Ldap.Client.Add
-    Ldap.Client.Bind
-    Ldap.Client.Compare
-    Ldap.Client.Delete
-    Ldap.Client.Extended
-    Ldap.Client.Internal
-    Ldap.Client.Modify
-    Ldap.Client.Search
+      Ldap.Asn1.FromAsn1
+      Ldap.Asn1.ToAsn1
+      Ldap.Asn1.Type
+      Ldap.Client
+      Ldap.Client.Add
+      Ldap.Client.Bind
+      Ldap.Client.Compare
+      Ldap.Client.Delete
+      Ldap.Client.Extended
+      Ldap.Client.Internal
+      Ldap.Client.Modify
+      Ldap.Client.Search
+  other-modules:
+      Paths_ldap_client_og
+  hs-source-dirs:
+      src
+  ghc-options: -funbox-strict-fields -Wall -Wno-incomplete-uni-patterns
   build-depends:
-      asn1-encoding >= 0.9
-    , asn1-types    >= 0.3
+      asn1-encoding
+    , asn1-types
     , async
-    , base          >= 4.6 && < 5
+    , base >=4.18 && <5
     , bytestring
-    , connection    >= 0.2
     , containers
-    , network       >= 2.6
-    , semigroups    >= 0.16
+    , crypton-connection
+    , network
+    , semigroups
     , stm
     , text
+  default-language: Haskell2010
 
 test-suite spec
-  ghc-options:
-    -Wall
-    -fwarn-incomplete-uni-patterns
-    -fwarn-incomplete-record-updates
-    -fwarn-unrecognised-pragmas
-  default-language:
-    Haskell2010
-  type:
-    exitcode-stdio-1.0
-  hs-source-dirs:
-    test
-  main-is:
-    Spec.hs
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
   other-modules:
-    Ldap.ClientSpec
-    Ldap.Client.AddSpec
-    Ldap.Client.BindSpec
-    Ldap.Client.CompareSpec
-    Ldap.Client.DeleteSpec
-    Ldap.Client.ExtendedSpec
-    Ldap.Client.ModifySpec
-    Ldap.Client.SearchSpec
-    SpecHelper
+      Ldap.Client.AddSpec
+      Ldap.Client.BindSpec
+      Ldap.Client.CompareSpec
+      Ldap.Client.DeleteSpec
+      Ldap.Client.ExtendedSpec
+      Ldap.Client.ModifySpec
+      Ldap.Client.SearchSpec
+      Ldap.ClientSpec
+      SpecHelper
+      Paths_ldap_client_og
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -Wno-incomplete-uni-patterns -threaded -with-rtsopts=-N
+  build-tool-depends:
+      hspec-discover:hspec-discover
   build-depends:
-      base          >= 4.6 && < 5
+      base >=4.18 && <5
     , bytestring
     , hspec
-    , ldap-client
+    , ldap-client-og
     , process
     , semigroups
+  default-language: Haskell2010
diff --git a/src/Ldap/Asn1/FromAsn1.hs b/src/Ldap/Asn1/FromAsn1.hs
--- a/src/Ldap/Asn1/FromAsn1.hs
+++ b/src/Ldap/Asn1/FromAsn1.hs
@@ -5,7 +5,7 @@
   , FromAsn1
   ) where
 
-import           Control.Applicative (Alternative(..), liftA2, optional)
+import           Control.Applicative (Alternative(..), optional)
 import           Control.Monad (MonadPlus(..), (>=>), guard)
 import           Data.ASN1.Types (ASN1)
 import qualified Data.ASN1.Types as Asn1
@@ -47,13 +47,13 @@
      controls       [0] Controls OPTIONAL }
 @
 -}
-instance FromAsn1 op =>  FromAsn1 (LdapMessage op) where
+instance FromAsn1 op => FromAsn1 (LdapMessage op) where
   fromAsn1 = do
     Asn1.Start Asn1.Sequence <- next
     i  <- fromAsn1
     op <- fromAsn1
     Asn1.End Asn1.Sequence <- next
-    return (LdapMessage i op Nothing)
+    pure (LdapMessage i op Nothing)
 
 {- |
 @
@@ -63,7 +63,7 @@
 instance FromAsn1 Id where
   fromAsn1 = do
     Asn1.IntVal i <- next
-    return (Id (fromIntegral i))
+    pure (Id (fromIntegral i))
 
 {- |
 @
@@ -74,7 +74,7 @@
   fromAsn1 = do
     Asn1.OctetString s <- next
     case Text.decodeUtf8' s of
-      Right t -> return (LdapString t)
+      Right t -> pure (LdapString t)
       Left  _ -> empty
 
 {- |
@@ -86,7 +86,7 @@
   fromAsn1 = do
     Asn1.OctetString s <- next
     case Text.decodeUtf8' s of
-      Right t -> return (LdapOid t)
+      Right t -> pure (LdapOid t)
       Left  _ -> empty
 
 {- |
@@ -113,7 +113,7 @@
 instance FromAsn1 AttributeValue where
   fromAsn1 = do
     Asn1.OctetString s <- next
-    return (AttributeValue s)
+    pure (AttributeValue s)
 
 {- |
 @
@@ -130,7 +130,7 @@
     vs <- many fromAsn1
     Asn1.End Asn1.Set <- next
     Asn1.End Asn1.Sequence <- next
-    return (PartialAttribute d vs)
+    pure (PartialAttribute d vs)
 
 {- |
 @
@@ -240,8 +240,8 @@
       Asn1.Start (Asn1.Container Asn1.Context 0) <- next
       x <- fromAsn1
       Asn1.End (Asn1.Container Asn1.Context 0) <- next
-      return x
-    return (LdapResult resultCode matchedDn diagnosticMessage referral)
+      pure x
+    pure (LdapResult resultCode matchedDn diagnosticMessage referral)
 
 {- |
 @
@@ -253,7 +253,7 @@
     Asn1.Start Asn1.Sequence <- next
     xs <- some1 fromAsn1
     Asn1.End Asn1.Sequence <- next
-    return (ReferralUris xs)
+    pure (ReferralUris xs)
 
 {- |
 @
@@ -333,31 +333,31 @@
       Asn1.Start (Asn1.Container Asn1.Application 19) <- next
       uris <- some1 fromAsn1
       Asn1.End (Asn1.Container Asn1.Application 19) <- next
-      return (SearchResultReference uris)
+      pure (SearchResultReference uris)
 
     , do
       Asn1.Start (Asn1.Container Asn1.Application 24) <- next
       res <- fromAsn1
       utf8Name <- optional $ do
         Asn1.Other Asn1.Context 10 s <- next
-        return s
-      name <- maybe (return Nothing) (\n -> case Text.decodeUtf8' n of
+        pure s
+      name <- maybe (pure Nothing) (\n -> case Text.decodeUtf8' n of
         Left  _    -> empty
-        Right name -> return (Just name)) utf8Name
+        Right name -> pure (Just name)) utf8Name
       value <- optional $ do
         Asn1.Other Asn1.Context 11 s <- next
-        return s
+        pure s
       Asn1.End (Asn1.Container Asn1.Application 24) <- next
-      return (ExtendedResponse res (fmap LdapOid name) value)
+      pure (ExtendedResponse res (fmap LdapOid name) value)
 
     , do
       Asn1.Start (Asn1.Container Asn1.Application 25) <- next
       name  <- optional fromAsn1
       value <- optional $ do
         Asn1.OctetString s <- next
-        return s
+        pure s
       Asn1.End (Asn1.Container Asn1.Application 25) <- next
-      return (IntermediateResponse name value)
+      pure (IntermediateResponse name value)
     ]
    where
     app l = do
@@ -366,7 +366,7 @@
       res <- fromAsn1
       Asn1.End (Asn1.Container Asn1.Application y) <- next
       guard (y == l)
-      return res
+      pure res
 
 {- |
 @
@@ -378,7 +378,7 @@
     Asn1.Start Asn1.Sequence <- next
     xs <- many fromAsn1
     Asn1.End Asn1.Sequence <- next
-    return (PartialAttributeList xs)
+    pure (PartialAttributeList xs)
 
 instance (FromAsn1 a, FromAsn1 b) => FromAsn1 (a, b) where
   fromAsn1 = liftA2 (,) fromAsn1 fromAsn1
@@ -402,7 +402,6 @@
     Parser (\s -> ma s <|> mb s)
 
 instance Monad (Parser s) where
-  return x = Parser (\s -> return (s, x))
   Parser mx >>= k =
     Parser (mx >=> \(s', x) -> unParser (k x) s')
 
diff --git a/src/Ldap/Client.hs b/src/Ldap/Client.hs
--- a/src/Ldap/Client.hs
+++ b/src/Ldap/Client.hs
@@ -148,9 +148,9 @@
         ]
       fmap (Right . snd) (Async.waitAnyCancel as)))
  `catches`
-  [ Handler (\(WrappedIOError e) -> return (Left (IOError e)))
-  , Handler (return . Left . ParseError)
-  , Handler (return . Left . ResponseError)
+  [ Handler (\(WrappedIOError e) -> pure (Left (IOError e)))
+  , Handler (pure . Left . ParseError)
+  , Handler (pure . Left . ResponseError)
   ]
  where
   params = Conn.ConnectionParams
@@ -194,7 +194,7 @@
         Right asn1 -> do
           flip fix asn1 $ \loop' asn1' ->
             case parseAsn1 asn1' of
-              Nothing -> return ()
+              Nothing -> pure ()
               Just (asn1'', a) -> do
                 atomically (writeTQueue inq a)
                 loop' asn1''
@@ -217,13 +217,13 @@
     loop =<< atomically (asum
       [ do New new var <- readTQueue client
            writeTQueue outq (Type.LdapMessage (Type.Id counter) new Nothing)
-           return (Map.insert (Type.Id counter) ([], var) req, counter + 1)
+           pure (Map.insert (Type.Id counter) ([], var) req, counter + 1)
       , do Type.LdapMessage mid op _
                <- readTQueue inq
            res <- case op of
              Type.BindResponse {}          -> done mid op req
              Type.SearchResultEntry {}     -> saveUp mid op req
-             Type.SearchResultReference {} -> return req
+             Type.SearchResultReference {} -> pure req
              Type.SearchResultDone {}      -> done mid op req
              Type.ModifyResponse {}        -> done mid op req
              Type.AddResponse {}           -> done mid op req
@@ -232,18 +232,18 @@
              Type.CompareResponse {}       -> done mid op req
              Type.ExtendedResponse {}      -> probablyDisconnect mid op req
              Type.IntermediateResponse {}  -> saveUp mid op req
-           return (res, counter)
+           pure (res, counter)
       ])
  where
   saveUp mid op res =
-    return (Map.adjust (\(stack, var) -> (op : stack, var)) mid res)
+    pure (Map.adjust (\(stack, var) -> (op : stack, var)) mid res)
 
   done mid op req =
     case Map.lookup mid req of
-      Nothing -> return req
+      Nothing -> pure req
       Just (stack, var) -> do
         putTMVar var (op :| stack)
-        return (Map.delete mid req)
+        pure (Map.delete mid req)
 
   probablyDisconnect (Type.Id 0)
                      (Type.ExtendedResponse
@@ -256,7 +256,7 @@
     case moid of
       Just (Type.LdapOid oid)
         | Oid oid == noticeOfDisconnectionOid -> throwSTM (Disconnect code (Dn dn) reason)
-      _ -> return req
+      _ -> pure req
   probablyDisconnect mid op req = done mid op req
 
 wrap :: IO a -> IO a
diff --git a/src/Ldap/Client/Internal.hs b/src/Ldap/Client/Internal.hs
--- a/src/Ldap/Client/Internal.hs
+++ b/src/Ldap/Client/Internal.hs
@@ -108,13 +108,13 @@
 sendRequest l p msg =
   do var <- newEmptyTMVar
      writeRequest l var msg
-     return (Async (fmap p (readTMVar var)))
+     pure (Async (fmap p (readTMVar var)))
 
 writeRequest :: Ldap -> TMVar Response -> Request -> STM ()
 writeRequest Ldap { client } var msg = writeTQueue client (New msg var)
 
 raise :: Exception e => Either e a -> IO a
-raise = either throwIO return
+raise = either throwIO pure
 
 
 -- | Terminate the connection to the Directory.
