diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,2 +1,7 @@
-# resourcet-effectful-0.1 (2022-07-14)
+# resourcet-effectful-1.0.1.0 (2023-11-06)
+* Add `allocateEff`, `allocateEff_`, `registerEff`, `releaseEff` and
+  `unprotectEff'.
+* Re-export `ReleaseKey` and `ResourceCleanupException`.
+
+# resourcet-effectful-1.0.0.0 (2022-07-14)
 * Initial release.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 [![Build Status](https://github.com/haskell-effectful/resourcet-effectful/workflows/Haskell-CI/badge.svg?branch=master)](https://github.com/haskell-effectful/resourcet-effectful/actions?query=branch%3Amaster)
 [![Hackage](https://img.shields.io/hackage/v/resourcet-effectful.svg)](https://hackage.haskell.org/package/resourcet-effectful)
 [![Dependencies](https://img.shields.io/hackage-deps/v/resourcet-effectful.svg)](https://packdeps.haskellers.com/feed?needle=andrzej@rybczak.net)
-[![Stackage LTS](https://www.stackage.org/package/resourcet-effectful/badge/lts)](https://www.stackage.org/lts/package/resource-teffectful)
+[![Stackage LTS](https://www.stackage.org/package/resourcet-effectful/badge/lts)](https://www.stackage.org/lts/package/resourcet-effectful)
 [![Stackage Nightly](https://www.stackage.org/package/resourcet-effectful/badge/nightly)](https://www.stackage.org/nightly/package/resourcet-effectful)
 
 
diff --git a/resourcet-effectful.cabal b/resourcet-effectful.cabal
--- a/resourcet-effectful.cabal
+++ b/resourcet-effectful.cabal
@@ -1,7 +1,7 @@
 cabal-version:      2.4
 build-type:         Simple
 name:               resourcet-effectful
-version:            1.0.0.0
+version:            1.0.1.0
 license:            BSD-3-Clause
 license-file:       LICENSE
 category:           Control
@@ -15,7 +15,8 @@
   CHANGELOG.md
   README.md
 
-tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.3
+tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.7 || ==9.6.3
+              || ==9.8.1
 
 bug-reports: https://github.com/haskell-effectful/resourcet-effectful/issues
 source-repository head
@@ -52,8 +53,8 @@
     import:         language
 
     build-depends:    base                >= 4.13      && < 5
-                    , effectful-core      >= 1.0.0.0   && < 1.0.1.0
-                    , resourcet           >= 1.2.4.3   && < 1.3
+                    , effectful-core      >= 1.0.0.0   && < 3.0.0.0
+                    , resourcet           >= 1.2.4.3   && < 1.4
 
     hs-source-dirs:  src
 
diff --git a/src/Effectful/Resource.hs b/src/Effectful/Resource.hs
--- a/src/Effectful/Resource.hs
+++ b/src/Effectful/Resource.hs
@@ -9,11 +9,17 @@
   , runResource
 
     -- * Registering and releasing resources
+  , allocateEff
+  , allocateEff_
+  , registerEff
+  , releaseEff
   , R.allocate
   , R.allocate_
   , R.register
   , R.release
   , R.unprotect
+  , ReleaseAction(..)
+  , unprotectEff
 
     -- * Internal state
   , R.InternalState
@@ -21,6 +27,10 @@
   , runInternalState
   , R.createInternalState
   , R.closeInternalState
+
+    -- * Re-exports
+  , R.ReleaseKey
+  , R.ResourceCleanupException(..)
   ) where
 
 import Control.Exception
@@ -50,6 +60,72 @@
     unconsEnv es
     RI.stateCleanupChecked Nothing istate
     pure a
+
+----------------------------------------
+-- Registering and releasing resources
+
+-- | A variant of 'R.allocate` adjusted to work in the 'Eff' monad.
+--
+-- /Note:/ the @release@ action will run a cloned environment, so any changes it
+-- makes to thread local data will not be visible outside of it.
+allocateEff
+  :: Resource :> es
+  => Eff es a -- ^ allocate
+  -> (a -> Eff es ()) -- ^ free resource
+  -> Eff es (R.ReleaseKey, a)
+allocateEff acquire release = do
+  istate <- getInternalState
+  unsafeEff $ \es0 -> mask_ $ do
+    a <- unEff acquire es0
+    -- we need to clone original env for release action
+    -- because it will be called when original env already unconsed
+    es1 <- cloneEnv es0
+    key <- RI.register' istate $ unEff (release a) es1
+    pure (key, a)
+
+-- | A variant of 'R.allocate_' adjusted to work in the 'Eff' monad.
+--
+-- /Note:/ the @release@ action will run a cloned environment, so any changes it
+-- makes to thread local data will not be visible outside of it.
+allocateEff_
+  :: Resource :> es
+  => Eff es a -- ^ allocate
+  -> Eff es () -- ^ free resource
+  -> Eff es R.ReleaseKey
+allocateEff_ a = fmap fst . allocateEff a . const
+
+-- | A variant of 'R.register' adjusted to work in the 'Eff' monad.
+--
+-- /Note:/ the @release@ action will run a cloned environment, so any changes it
+-- makes to thread local data will not be visible outside of it.
+registerEff :: Resource :> es => Eff es () -> Eff es R.ReleaseKey
+registerEff release = do
+  istate <- getInternalState
+  unsafeEff $ \es0 -> do
+    -- we need to clone original env for release action
+    -- because it will be called when original env already unconsed
+    es1 <- cloneEnv es0
+    RI.register' istate $ unEff release es1
+
+-- | A variant of 'R.release' adjusted to work in the 'Eff' monad.
+releaseEff :: Resource :> es => R.ReleaseKey -> Eff es ()
+releaseEff = unsafeEff_ . R.release
+
+-- | Action for releasing a resource.
+newtype ReleaseAction = ReleaseAction
+  { runReleaseAction :: forall es. Resource :> es => Eff es ()
+  }
+
+-- | A variant of 'R.unprotect' adjusted to work in the 'Eff' monad.
+--
+-- /Note:/ if the resource was acquired using 'allocateEff', 'allocateEff_' or
+-- 'registerEff' then the returned 'ReleaseAction' will run in a clone of the
+-- environment it was registered in.
+--
+-- See the documentation of the aforementioned functions for more information.
+unprotectEff :: Resource :> es => R.ReleaseKey -> Eff es (Maybe ReleaseAction)
+unprotectEff key = unsafeEff_ $ do
+  fmap (\m -> ReleaseAction $ unsafeEff_ m) <$> R.unprotect key
 
 ----------------------------------------
 -- Internal state
