diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # Change Log
 
+## [v0.8.0](https://github.com/tweag/linear-base/tree/v0.8.0) (2026-05-12)
+
+[Full Changelog](https://github.com/tweag/linear-base/compare/v0.7.0...v0.8.0)
+
+### Headline changes
+
+- Add MonadIO instances for StateT and ReaderT [\#506](https://github.com/tweag/linear-base/pull/506) ([dcastro](https://github.com/dcastro))
+- Coerce `System.IO` and `Linear.IO` into `RIO` [\#505](https://github.com/tweag/linear-base/pull/505) ([dcastro](https://github.com/dcastro))
+
 ## [v0.7.0](https://github.com/tweag/linear-base/tree/v0.7.0) (2026-02-27)
 
 [Full Changelog](https://github.com/tweag/linear-base/compare/v0.6.0...v0.7.0)
diff --git a/bench/Data/Mutable/HashMap.hs b/bench/Data/Mutable/HashMap.hs
--- a/bench/Data/Mutable/HashMap.hs
+++ b/bench/Data/Mutable/HashMap.hs
@@ -10,6 +10,11 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE StandaloneDeriving #-}
 {-# LANGUAGE TupleSections #-}
+{-# OPTIONS_GHC -Wno-unused-imports #-}
+
+-- `-Wno-unused-imports`: so that we can import `foldl'` without GHC 9.10+
+-- complaining. Inelegant, but this is just a test file, not the end of the
+-- world.
 
 module Data.Mutable.HashMap (benchmarks) where
 
diff --git a/linear-base.cabal b/linear-base.cabal
--- a/linear-base.cabal
+++ b/linear-base.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               linear-base
-version:            0.7.0
+version:            0.8.0
 license:            MIT
 license-file:       LICENSE
 copyright:          (c) Tweag Holding and affiliates
diff --git a/src/Control/Monad/IO/Class/Linear.hs b/src/Control/Monad/IO/Class/Linear.hs
--- a/src/Control/Monad/IO/Class/Linear.hs
+++ b/src/Control/Monad/IO/Class/Linear.hs
@@ -7,6 +7,8 @@
 import Prelude.Linear
 import qualified System.IO as System
 import qualified System.IO.Linear as Linear
+import System.IO.Resource.Linear (RIO)
+import qualified System.IO.Resource.Linear as RIO
 
 -- | Like 'NonLinear.MonadIO' but allows to lift both linear
 -- and non-linear 'IO' actions into a linear monad.
@@ -19,3 +21,12 @@
 
 instance MonadIO Linear.IO where
   liftIO = id
+
+instance MonadIO RIO where
+  liftIO = RIO.fromIO
+
+instance (MonadIO m) => MonadIO (Linear.StateT s m) where
+  liftIO = Linear.lift . liftIO
+
+instance (MonadIO m, Dupable r) => MonadIO (Linear.ReaderT r m) where
+  liftIO = Linear.lift . liftIO
diff --git a/src/Streaming/Linear/Internal/Consume.hs b/src/Streaming/Linear/Internal/Consume.hs
--- a/src/Streaming/Linear/Internal/Consume.hs
+++ b/src/Streaming/Linear/Internal/Consume.hs
@@ -62,6 +62,7 @@
 where
 
 import qualified Control.Functor.Linear as Control
+import Control.Monad.IO.Class.Linear (liftSystemIO)
 import qualified Data.Bool.Linear as Linear
 import Data.Functor.Identity
 import Data.Text (Text)
@@ -116,7 +117,7 @@
         Return r -> Control.return r
         Effect ms -> ms Control.>>= stdoutLn'
         Step (str :> stream) -> Control.do
-          fromSystemIO $ Text.putStrLn str
+          liftSystemIO $ Text.putStrLn str
           stdoutLn' stream
 {-# INLINEABLE stdoutLn' #-}
 
diff --git a/src/Streaming/Linear/Internal/Produce.hs b/src/Streaming/Linear/Internal/Produce.hs
--- a/src/Streaming/Linear/Internal/Produce.hs
+++ b/src/Streaming/Linear/Internal/Produce.hs
@@ -45,6 +45,7 @@
 where
 
 import qualified Control.Functor.Linear as Control
+import Control.Monad.IO.Class.Linear (liftSystemIOU)
 import Data.Text (Text)
 import qualified Data.Text as Text
 import Data.Unrestricted.Linear
@@ -344,7 +345,7 @@
   where
     getALine :: () %1 -> IO (Either (Of Text ()) ())
     getALine () = Control.do
-      Ur line <- fromSystemIOU System.getLine
+      Ur line <- liftSystemIOU System.getLine
       Control.return $ Left (Text.pack line :> ())
 
 -- | An affine stream of reading lines, crashing on failed parse.
@@ -353,7 +354,7 @@
   where
     readALine :: (Read a) => () %1 -> IO (Either (Of a ()) ())
     readALine () = Control.do
-      Ur line <- fromSystemIOU System.getLine
+      Ur line <- liftSystemIOU System.getLine
       Control.return $ Left (Prelude.read line :> ())
 
 -- | An affine stream iterating an initial state forever.
diff --git a/src/System/IO/Resource/Linear.hs b/src/System/IO/Resource/Linear.hs
--- a/src/System/IO/Resource/Linear.hs
+++ b/src/System/IO/Resource/Linear.hs
@@ -32,6 +32,11 @@
     RIO,
     run,
 
+    -- * Interfacing with IO
+    fromIO,
+    fromSystemIO,
+    fromSystemIOU,
+
     -- * Using Resource Handles
     -- $monad
     -- $files
diff --git a/src/System/IO/Resource/Linear/Internal.hs b/src/System/IO/Resource/Linear/Internal.hs
--- a/src/System/IO/Resource/Linear/Internal.hs
+++ b/src/System/IO/Resource/Linear/Internal.hs
@@ -88,10 +88,24 @@
       result <- action'
       Control.return $ move result
 
--- | Should not be applied to a function that acquires or releases resources.
-unsafeFromSystemIO :: System.IO a %1 -> RIO a
-unsafeFromSystemIO action = RIO (\_ -> Linear.fromSystemIO action)
+-- | Coerces a linear IO action into a 'RIO' action.
+fromIO :: Linear.IO a %1 -> RIO a
+fromIO action = RIO (\_ -> action)
 
+-- | Coerces a standard IO action into a 'RIO' action.
+-- Note that the value @a@ must be used linearly in the 'RIO' monad.
+fromSystemIO :: System.IO a %1 -> RIO a
+fromSystemIO action =
+  -- Should not be applied to a function that acquires or releases resources.
+  fromIO (Linear.fromSystemIO action)
+
+-- | Coerces a standard IO action into a 'RIO' action, allowing you to use
+-- the result of type @a@ in a non-linear manner by wrapping it inside
+-- 'Ur'.
+fromSystemIOU :: System.IO a -> RIO (Ur a)
+fromSystemIOU action =
+  fromIO (Linear.fromSystemIOU action)
+
 -- monad
 
 instance Control.Functor RIO where
@@ -235,7 +249,7 @@
   (a -> System.IO b) ->
   (Resource a %1 -> RIO (Ur b, Resource a))
 unsafeFromSystemIOResource action (UnsafeResource key resource) =
-  unsafeFromSystemIO
+  fromSystemIO
     ( do
         c <- action resource
         Prelude.return (Ur c, UnsafeResource key resource)
diff --git a/test/Test/Data/List.hs b/test/Test/Data/List.hs
--- a/test/Test/Data/List.hs
+++ b/test/Test/Data/List.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE NoImplicitPrelude #-}
+{-# OPTIONS_GHC -Wno-x-partial #-}
 
 module Test.Data.List (listTests) where
 
