diff --git a/library/PostgreSQL/Binary/Decoder.hs b/library/PostgreSQL/Binary/Decoder.hs
--- a/library/PostgreSQL/Binary/Decoder.hs
+++ b/library/PostgreSQL/Binary/Decoder.hs
@@ -17,8 +17,10 @@
   fn,
   numeric,
   uuid,
-  json,
-  jsonb,
+  json_ast,
+  json_bytes,
+  jsonb_ast,
+  jsonb_bytes,
   -- * Time
   date,
   time_int,
@@ -146,14 +148,27 @@
 uuid =
   UUID.fromWords <$> intOfSize 4 <*> intOfSize 4 <*> intOfSize 4 <*> intOfSize 4
 
-{-# INLINABLE json #-}
-json :: Decoder Aeson.Value
-json =
+{-# INLINABLE json_ast #-}
+json_ast :: Decoder Aeson.Value
+json_ast =
   bytea_strict >>= either (BinaryParser.failure . fromString) pure . Aeson.eitherDecodeStrict'
 
-{-# INLINABLE jsonb #-}
-jsonb :: Decoder Aeson.Value
-jsonb =
+-- |
+-- Given a function, which parses a plain UTF-8 JSON string encoded as a byte-array,
+-- produces a decoder.
+{-# INLINABLE json_bytes #-}
+json_bytes :: (ByteString -> Either Text a) -> Decoder a
+json_bytes cont =
+  getAllBytes >>= parseJSON
+  where
+    getAllBytes =
+      BinaryParser.remainders
+    parseJSON =
+      either BinaryParser.failure return . cont
+
+{-# INLINABLE jsonb_ast #-}
+jsonb_ast :: Decoder Aeson.Value
+jsonb_ast =
   jsonb_bytes $ mapLeft fromString . Aeson.eitherDecodeStrict'
 
 -- |
diff --git a/library/PostgreSQL/Binary/Encoder.hs b/library/PostgreSQL/Binary/Encoder.hs
--- a/library/PostgreSQL/Binary/Encoder.hs
+++ b/library/PostgreSQL/Binary/Encoder.hs
@@ -16,8 +16,10 @@
   bool,
   numeric,
   uuid,
-  json,
-  jsonb,
+  json_ast,
+  json_bytes,
+  jsonb_ast,
+  jsonb_bytes,
   char,
   text_strict,
   text_lazy,
@@ -220,20 +222,30 @@
 uuid =
   premap UUID.toWords (tuple4 int4_word32 int4_word32 int4_word32 int4_word32)
 
-{-# INLINABLE json #-}
-json :: Encoder Aeson.Value
+{-# INLINABLE json_ast #-}
+json_ast :: Encoder Aeson.Value
 #if MIN_VERSION_aeson(0,10,0)
-json =
+json_ast =
   Aeson.fromEncoding . Aeson.toEncoding
 #else
-json =
+json_ast =
   Builder.lazyByteString . Aeson.encode
 #endif
 
-{-# INLINABLE jsonb #-}
-jsonb :: Encoder Aeson.Value
-jsonb =
-  \x -> "\1" <> json x
+{-# INLINABLE json_bytes #-}
+json_bytes :: Encoder ByteString
+json_bytes =
+  Builder.byteString
+
+{-# INLINABLE jsonb_ast #-}
+jsonb_ast :: Encoder Aeson.Value
+jsonb_ast =
+  \x -> "\1" <> json_ast x
+
+{-# INLINABLE jsonb_bytes #-}
+jsonb_bytes :: Encoder ByteString
+jsonb_bytes =
+  \x -> "\1" <> Builder.byteString x
 
 -- * Text
 -------------------------
diff --git a/postgresql-binary.cabal b/postgresql-binary.cabal
--- a/postgresql-binary.cabal
+++ b/postgresql-binary.cabal
@@ -1,7 +1,7 @@
 name:
   postgresql-binary
 version:
-  0.7.9
+  0.8
 synopsis:
   Encoders and decoders for the PostgreSQL's binary format
 description:
@@ -133,7 +133,7 @@
     conversion-text == 1.*,
     either == 4.*,
     transformers,
-    rebase >= 0.2.1 && < 0.3,
+    rebase >= 0.4 && < 0.5,
     base
 
 
diff --git a/tasty/Main.hs b/tasty/Main.hs
--- a/tasty/Main.hs
+++ b/tasty/Main.hs
@@ -26,7 +26,7 @@
 binary =
   testGroup "Binary format"
   [
-    stdRoundtrip "jsonb" Gens.aeson PTI.jsonb Encoder.jsonb Decoder.jsonb
+    stdRoundtrip "jsonb" Gens.aeson PTI.jsonb Encoder.jsonb_ast Decoder.jsonb_ast
     ,
     select "SELECT '1 year 2 months 3 days 4 hours 5 minutes 6 seconds 332211 microseconds' :: interval"
     (bool Decoder.interval_float Decoder.interval_int)
diff --git a/tasty/Main/Prelude.hs b/tasty/Main/Prelude.hs
--- a/tasty/Main/Prelude.hs
+++ b/tasty/Main/Prelude.hs
@@ -7,23 +7,14 @@
   TextBuilder,
   bug,
   bottom,
-  mapLeft,
-  joinMap,
 )
 where
 
 
--- base-prelude
+-- rebase
 -------------------------
 import Rebase.Prelude as Exports hiding (assert, Data, fail)
 
--- transformers
--------------------------
-import Control.Monad.Trans.State.Strict as Exports hiding (liftCallCC, liftCatch)
-import Control.Monad.Trans.Reader as Exports hiding (liftCallCC, liftCatch)
-import Control.Monad.Trans.Class as Exports
-import Data.Functor.Identity as Exports
-
 -- conversion
 -------------------------
 import Conversion as Exports
@@ -65,12 +56,3 @@
     msg = "A \"postgresql-binary\" package bug: " :: String
 
 bottom = [e| $bug "Bottom evaluated" |]
-
-{-# INLINE mapLeft #-}
-mapLeft :: (a -> b) -> Either a x -> Either b x
-mapLeft f =
-  either (Left . f) Right
-
-joinMap :: Monad m => (a -> m b) -> m a -> m b
-joinMap f =
-  join . liftM f
