diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # binary-io
 
+## 0.5.0
+
+* Let runPut and company return the result of the PutM operation
+
 ## 0.4.0
 
 * Add module Data.Binary.IO.Lifted module which contains versions of all functions and types
diff --git a/binary-io.cabal b/binary-io.cabal
--- a/binary-io.cabal
+++ b/binary-io.cabal
@@ -5,7 +5,7 @@
   binary-io
 
 version:
-  0.4.0
+  0.5.0
 
 category:
   Data, Parsing, IO
diff --git a/lib/Data/Binary/IO.hs b/lib/Data/Binary/IO.hs
--- a/lib/Data/Binary/IO.hs
+++ b/lib/Data/Binary/IO.hs
@@ -46,8 +46,8 @@
 
 import           Data.Bifunctor (bimap)
 import qualified Data.Binary as Binary
-import qualified Data.Binary.Get as Binary.Get
 import qualified Data.Binary.IO.Lifted as Lifted
+import qualified Data.Binary.Put as Put
 import qualified Data.ByteString as ByteString
 import           Prelude hiding (read)
 import           System.IO (Handle)
@@ -136,8 +136,9 @@
 newDuplex
   :: Handle -- ^ Handle that will be read from and written to
   -> IO Duplex
-newDuplex handle =
-  Duplex (newWriter handle) <$> newReader handle
+newDuplex handle = do
+  Lifted.Duplex writer reader <- Lifted.newDuplex handle
+  pure (Duplex (Writer writer) (Reader reader))
 
 -- | Unlifted version of 'Lifted.newDuplexWith'
 --
@@ -146,8 +147,9 @@
   :: IO ByteString.ByteString
   -> (ByteString.ByteString -> IO ())
   -> IO Duplex
-newDuplexWith get push =
-  Duplex (newWriterWith push) <$> newReaderWith get
+newDuplexWith get push = do
+  Lifted.Duplex writer reader <- Lifted.newDuplexWith get push
+  pure (Duplex (Writer writer) (Reader reader))
 
 -- * Classes
 
@@ -174,14 +176,14 @@
   :: (CanGet r, Binary.Binary a)
   => r -- ^ Read source
   -> IO a
-read reader =
-  runGet reader Binary.get
+read =
+  Lifted.read
 
 -- | Unlifted version of 'Lifted.isEmpty'
 --
 -- @since 0.3.0
 isEmpty :: CanGet r => r -> IO Bool
-isEmpty reader = runGet reader Binary.Get.isEmpty
+isEmpty = Lifted.isEmpty
 
 -- | Alias for 'Lifted.CanPut' @w@ 'IO'
 --
@@ -194,9 +196,10 @@
 runPut
   :: CanPut w
   => w -- ^ Writer / target
-  -> Binary.Put -- ^ Operation to execute
-  -> IO ()
-runPut = Lifted.runPut
+  -> Put.PutM a -- ^ Operation to execute
+  -> IO a
+runPut =
+  Lifted.runPut
 
 -- | Unlifted version of 'Lifted.write'
 --
diff --git a/lib/Data/Binary/IO/Lifted.hs b/lib/Data/Binary/IO/Lifted.hs
--- a/lib/Data/Binary/IO/Lifted.hs
+++ b/lib/Data/Binary/IO/Lifted.hs
@@ -229,21 +229,24 @@
 
 -- | @since 0.4.0
 newtype Writer m = Writer
-  { runWriter :: Binary.Put -> m () }
+  { runWriter :: forall a. Put.PutM a -> m a }
 
 -- | Transform the underlying functor.
 --
 -- @since 0.4.0
-mapWriter :: (m () -> n ()) -> Writer m -> Writer n
+mapWriter :: (forall x. m x -> n x) -> Writer m -> Writer n
 mapWriter f (Writer write) = Writer (f . write)
 
 -- | Create a writer using a function that handles the output chunks.
 --
 -- @since 0.4.0
 newWriterWith
-  :: (ByteString -> m ()) -- ^ Chunk writer
+  :: Functor m
+  => (ByteString -> m ()) -- ^ Chunk writer
   -> Writer m
-newWriterWith write = Writer (write . toStrict . Put.runPut)
+newWriterWith write = Writer $ \put -> do
+  let (result, body) = Put.runPutM put
+  result <$ write (toStrict body)
 
 -- | Create a writer.
 --
@@ -253,15 +256,16 @@
 -- @since 0.4.0
 newWriter
   :: MonadIO m
-  => Handle-- ^ Write target
+  => Handle -- ^ Write target
   -> Writer m
-newWriter handle = newWriterWith (liftIO . ByteString.hPut handle)
+newWriter handle =
+  newWriterWith (liftIO . ByteString.hPut handle)
 
 -- | @w@ can execute 'Binary.Put' operations in @m@
 --
 -- @since 0.4.0
 class CanPut w m where
-  runPut :: w -> Binary.Put -> m ()
+  runPut :: w -> Put.PutM a -> m a
 
 instance CanPut (Writer m) m where
   runPut = runWriter
@@ -270,7 +274,9 @@
   runPut = runPut . duplexWriter
 
 instance MonadIO m => CanPut Handle m where
-  runPut handle = liftIO . ByteString.hPut handle . toStrict . Put.runPut
+  runPut handle put = do
+    let (result, body) = Put.runPutM put
+    result <$ liftIO (ByteString.hPut handle (toStrict body))
 
 -- | Write something to @w@.
 --
