diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,7 @@
-# Revision history for mason
+## 0.2.3
+
+* Added `intDecPadded`
+* Exported backend types: `StrictByteStringBackend`, `LazyByteStringBackend` and `BufferedIOBackend`
 
 ## 0.2.2
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -15,11 +15,13 @@
 * `toStrictByteString` produces a strict `ByteString` directly.
 * `hPutBuilderLen` writes a builder to a handle and returns the number of bytes.
 * `sendBuilder` sends the content of `Builder` over a socket.
+* `withPopper` turns a builder into http-client's[GivesPopper](http://hackage.haskell.org/package/http-client-0.7.2.1/docs/Network-HTTP-Client.html#t:GivesPopper)
+* `toStreamingBody` creates wai's [StreamingBody](http://hackage.haskell.org/package/wai-3.2.2.1/docs/Network-Wai.html#t:StreamingBody)
 
 Usage
 ----
 
-Replace `Data.ByteString.Builder` with `Mason.Builder`. Note that if you have `Builder` in the type signature, you'll need `RankNTypes` extensions because of the design explained below.
+Replace `Data.ByteString.Builder` with `Mason.Builder`. Note that if you have `Builder` in the type signature, you'll need `RankNTypes` extensions because of the design explained below. Alternatively, you can also import `Mason.Builder.Compat` which has an API almost compatible with `Data.ByteString.Builder`.
 
 Performance
 ----
@@ -63,7 +65,83 @@
 bytestring/double                        mean 2.312 μs  ( +- 118.8 ns  )
 ```
 
-TBD: more benchmarks
+You can find more benchmarks below:
+
+* [bytes-builder-shootout](https://github.com/andrewthad/bytes-builder-shootout)
+
+<details>
+<summary>Click to expand</summary>
+<pre>
+treeToHex-2000/small-bytearray-builder   mean 44.01 μs  ( +- 1.620 μs  )
+treeToHex-2000/fast-builder              mean 34.40 μs  ( +- 390.1 ns  )
+treeToHex-2000/bytestring                mean 58.76 μs  ( +- 3.843 μs  )
+treeToHex-2000/mason                     mean 41.08 μs  ( +- 180.8 ns  )
+treeToHex-9000/small-bytearray-builder   mean 191.8 μs  ( +- 1.835 μs  )
+treeToHex-9000/bytestring                mean 284.8 μs  ( +- 1.156 μs  )
+treeToHex-9000/mason                     mean 181.2 μs  ( +- 386.3 ns  )
+short-text-tree-1000/small-bytearray-builder mean 26.54 μs  ( +- 34.08 ns  )
+short-text-tree-1000/fast-builder        mean 37.51 μs  ( +- 99.85 ns  )
+short-text-tree-1000/bytestring          mean 37.95 μs  ( +- 167.5 ns  )
+short-text-tree-1000/mason               mean 26.87 μs  ( +- 312.4 ns  )
+byte-tree-2000/small-bytearray-builder   mean 30.53 μs  ( +- 51.53 ns  )
+byte-tree-2000/fast-builder              mean 26.91 μs  ( +- 592.2 ns  )
+byte-tree-2000/bytestring                mean 54.40 μs  ( +- 1.743 μs  )
+byte-tree-2000/mason                     mean 34.34 μs  ( +- 193.5 ns  )
+</pre>
+</details>
+
+* [haskell-perf/strict-bytestring-builder](https://github.com/haskell-perf/strict-bytestring-builders)
+
+<details>
+<summary>Click to expand</summary>
+<pre>
+averagedAppends-1/byteStringStrictBuilder mean 116.3 ns  ( +- 6.479 ns  )
+averagedAppends-1/byteStringTreeBuilder  mean 181.7 ns  ( +- 20.88 ns  )
+averagedAppends-1/fastBuilder            mean 181.5 ns  ( +- 7.219 ns  )
+averagedAppends-1/bufferBuilder          mean 728.5 ns  ( +- 9.114 ns  )
+averagedAppends-1/byteString             mean 358.7 ns  ( +- 4.663 ns  )
+averagedAppends-1/blazeBuilder           mean 356.0 ns  ( +- 7.604 ns  )
+averagedAppends-1/binary                 mean 635.0 ns  ( +- 7.936 ns  )
+averagedAppends-1/cereal                 mean 638.6 ns  ( +- 12.40 ns  )
+averagedAppends-1/mason                  mean 155.2 ns  ( +- 2.000 ns  )
+averagedAppends-100/byteStringStrictBuilder mean 7.290 μs  ( +- 99.74 ns  )
+averagedAppends-100/byteStringTreeBuilder mean 13.40 μs  ( +- 283.4 ns  )
+averagedAppends-100/fastBuilder          mean 13.07 μs  ( +- 418.2 ns  )
+averagedAppends-100/bufferBuilder        mean 19.57 μs  ( +- 5.644 μs  )
+averagedAppends-100/byteString           mean 17.31 μs  ( +- 1.609 μs  )
+averagedAppends-100/blazeBuilder         mean 19.15 μs  ( +- 6.533 μs  )
+averagedAppends-100/binary               mean 48.26 μs  ( +- 727.1 ns  )
+averagedAppends-100/cereal               mean 51.57 μs  ( +- 21.81 μs  )
+averagedAppends-100/mason                mean 12.07 μs  ( +- 233.8 ns  )
+averagedAppends-10000/byteStringStrictBuilder mean 1.038 ms  ( +- 18.63 μs  )
+averagedAppends-10000/byteStringTreeBuilder mean 1.989 ms  ( +- 70.63 μs  )
+averagedAppends-10000/fastBuilder        mean 1.611 ms  ( +- 42.24 μs  )
+averagedAppends-10000/bufferBuilder      mean 1.895 ms  ( +- 25.09 μs  )
+averagedAppends-10000/byteString         mean 2.248 ms  ( +- 40.99 μs  )
+averagedAppends-10000/blazeBuilder       mean 2.394 ms  ( +- 1.016 ms  )
+averagedAppends-10000/binary             mean 6.503 ms  ( +- 157.6 μs  )
+averagedAppends-10000/cereal             mean 6.458 ms  ( +- 221.6 μs  )
+averagedAppends-10000/mason              mean 1.738 ms  ( +- 25.89 μs  )
+regularConcat-100/byteStringStrictBuilder mean 1.606 μs  ( +- 32.93 ns  )
+regularConcat-100/byteStringTreeBuilder  mean 2.000 μs  ( +- 43.73 ns  )
+regularConcat-100/fastBuilder            mean 1.364 μs  ( +- 37.95 ns  )
+regularConcat-100/bufferBuilder          mean 2.204 μs  ( +- 48.40 ns  )
+regularConcat-100/byteString             mean 1.253 μs  ( +- 25.68 ns  )
+regularConcat-100/blazeBuilder           mean 1.317 μs  ( +- 24.05 ns  )
+regularConcat-100/binary                 mean 2.845 μs  ( +- 62.24 ns  )
+regularConcat-100/cereal                 mean 3.021 μs  ( +- 48.53 ns  )
+regularConcat-100/mason                  mean 1.405 μs  ( +- 35.11 ns  )
+regularConcat-10000/byteStringStrictBuilder mean 321.3 μs  ( +- 11.13 μs  )
+regularConcat-10000/byteStringTreeBuilder mean 349.1 μs  ( +- 4.359 μs  )
+regularConcat-10000/fastBuilder          mean 121.0 μs  ( +- 1.755 μs  )
+regularConcat-10000/bufferBuilder        mean 156.1 μs  ( +- 2.050 μs  )
+regularConcat-10000/byteString           mean 106.6 μs  ( +- 1.355 μs  )
+regularConcat-10000/blazeBuilder         mean 110.8 μs  ( +- 1.397 μs  )
+regularConcat-10000/binary               mean 308.1 μs  ( +- 5.346 μs  )
+regularConcat-10000/cereal               mean 352.0 μs  ( +- 6.142 μs  )
+regularConcat-10000/mason                mean 130.2 μs  ( +- 10.39 μs  )
+</pre>
+</details>
 
 Architecture
 ----
diff --git a/mason.cabal b/mason.cabal
--- a/mason.cabal
+++ b/mason.cabal
@@ -1,7 +1,7 @@
 cabal-version:       2.4
 
 name:                mason
-version:             0.2.2
+version:             0.2.3
 synopsis:            Fast and extensible bytestring builder
 description:
   This package provides efficient implementation of bytestring builders.
diff --git a/src/Mason/Builder.hs b/src/Mason/Builder.hs
--- a/src/Mason/Builder.hs
+++ b/src/Mason/Builder.hs
@@ -16,12 +16,16 @@
   , BuilderFor
   , Buildable
   -- * Runners
+  , StrictByteStringBackend
   , toStrictByteString
+  , LazyByteStringBackend
   , toLazyByteString
+  , BufferedIOBackend
   , hPutBuilderLen
   , hPutBuilder
   , sendBuilder
   , withPopper
+  , StreamingBackend
   , toStreamingBody
   -- * Primitives
   , flush
@@ -75,6 +79,7 @@
   , int32Dec
   , int64Dec
   , intDec
+  , intDecPadded
   , integerDec
   , word8Hex
   , word16Hex
@@ -481,7 +486,10 @@
 intDec :: Int -> Builder
 intDec = B.primBounded P.intDec
 
-
+-- | 'intDec' with 0 padding
+intDecPadded :: Int -> Int -> Builder
+intDecPadded n = zeroPaddedBoundedPrim n P.intDec
+{-# INLINE intDecPadded #-}
 
 ------------------------------------------------------------------------------
 -- Hexadecimal Encoding
@@ -615,7 +623,7 @@
     go n | n < maxPow10 = intDec (fromInteger n)
          | otherwise    =
              case putH (splitf (maxPow10 * maxPow10) n) of
-               (x:xs) -> intDec x `mappend` B.primMapListBounded intDecPadded xs
+               (x:xs) -> intDec x `mappend` B.primMapListBounded intDecPadded18 xs
                []     -> errImpossible "integerDec: go"
 
     splitf :: Integer -> Integer -> [Integer]
@@ -653,9 +661,9 @@
 foreign import ccall unsafe "static _hs_bytestring_long_long_int_dec_padded18"
     c_long_long_int_dec_padded18 :: CLLong -> Ptr Word8 -> IO ()
 
-{-# INLINE intDecPadded #-}
-intDecPadded :: P.BoundedPrim Int
-intDecPadded = P.liftFixedToBounded $ caseWordSize_32_64
+{-# INLINE intDecPadded18 #-}
+intDecPadded18 :: P.BoundedPrim Int
+intDecPadded18 = P.liftFixedToBounded $ caseWordSize_32_64
     (P.fixedPrim  9 $ c_int_dec_padded9            . fromIntegral)
     (P.fixedPrim 18 $ c_long_long_int_dec_padded18 . fromIntegral)
 
diff --git a/src/Mason/Builder/Internal.hs b/src/Mason/Builder/Internal.hs
--- a/src/Mason/Builder/Internal.hs
+++ b/src/Mason/Builder/Internal.hs
@@ -16,11 +16,13 @@
   , unBuilder
   , byteStringCopy
   , shortByteString
+  , StrictByteStringBackend
   , toStrictByteString
   , Channel(..)
+  , LazyByteStringBackend
   , toLazyByteString
   , withPopper
-  , StreamingEnv(..)
+  , StreamingBackend(..)
   , toStreamingBody
   , stringUtf8
   , lengthPrefixedWithin
@@ -31,6 +33,7 @@
   , primMapByteStringFixed
   , primMapLazyByteStringFixed
   , PutEnv(..)
+  , BufferedIOBackend
   , hPutBuilderLen
   , encodeUtf8BuilderEscaped
   , sendBuilder
@@ -305,8 +308,10 @@
     return $ Buffer (dst' `plusPtr` size') (dst' `plusPtr` pos)
   {-# INLINE allocate #-}
 
+type StrictByteStringBackend = GrowingBuffer
+
 -- | Create a strict 'B.ByteString'
-toStrictByteString :: BuilderFor GrowingBuffer -> B.ByteString
+toStrictByteString :: BuilderFor StrictByteStringBackend -> B.ByteString
 toStrictByteString b = unsafePerformIO $ do
   fptr0 <- mallocForeignPtrBytes initialSize
   bufferRef <- newIORef fptr0
@@ -341,8 +346,10 @@
   allocate = allocateConstant chBuffer
   {-# INLINE allocate #-}
 
+type LazyByteStringBackend = Channel
+
 -- | Create a lazy 'BL.ByteString'. Threaded runtime is required.
-toLazyByteString :: BuilderFor Channel -> BL.ByteString
+toLazyByteString :: BuilderFor LazyByteStringBackend -> BL.ByteString
 toLazyByteString body = unsafePerformIO $ withPopper body $ \pop -> do
   let go _ = unsafePerformIO $ do
         bs <- pop
@@ -353,7 +360,7 @@
 {-# INLINE toLazyByteString #-}
 
 -- | Use 'Builder' as a <http://hackage.haskell.org/package/http-client-0.7.1/docs/Network-HTTP-Client.html#t:GivesPopper GivesPopper'
-withPopper :: BuilderFor Channel -> (IO B.ByteString -> IO a) -> IO a
+withPopper :: BuilderFor LazyByteStringBackend -> (IO B.ByteString -> IO a) -> IO a
 withPopper body cont = do
   resp <- newEmptyMVar
 
@@ -410,10 +417,12 @@
   allocate = allocateConstant peBuffer
   {-# INLINE allocate #-}
 
+type BufferedIOBackend = PutEnv
+
 -- | Write a 'Builder' into a handle and obtain the number of bytes written.
 -- 'flush' does not imply actual disk operations. Set 'NoBuffering' if you want
 -- it to write the content immediately.
-hPutBuilderLen :: Handle -> BuilderFor PutEnv -> IO Int
+hPutBuilderLen :: Handle -> BuilderFor BufferedIOBackend -> IO Int
 hPutBuilderLen h b = do
   let initialSize = 4096
   fptr <- mallocForeignPtrBytes initialSize
@@ -436,7 +445,7 @@
       when (sent > 0) $ go $ p `plusPtr` sent
 
 -- | Write a 'Builder' into a handle and obtain the number of bytes written.
-sendBuilder :: S.Socket -> BuilderFor PutEnv -> IO Int
+sendBuilder :: S.Socket -> BuilderFor BufferedIOBackend -> IO Int
 sendBuilder sock b = do
   let initialSize = 4096
   fptr <- mallocForeignPtrBytes initialSize
@@ -542,17 +551,17 @@
 foreign import ccall unsafe "static grisu3"
   c_grisu3 :: CDouble -> Ptr Word8 -> Ptr CInt -> Ptr CInt -> IO CInt
 
-data StreamingEnv = StreamingEnv
+data StreamingBackend = StreamingBackend
   { sePush :: !(B.ByteString -> IO ())
   , seBuffer :: !(IORef (ForeignPtr Word8))
   }
 
-instance Buildable StreamingEnv where
+instance Buildable StreamingBackend where
   byteString bs
     | B.length bs < 4096 = byteStringCopy bs
     | otherwise = flush <> Builder (\env b -> b <$ sePush env bs)
   {-# INLINE byteString #-}
-  flush = Builder $ \(StreamingEnv push ref) (Buffer end ptr) -> do
+  flush = Builder $ \(StreamingBackend push ref) (Buffer end ptr) -> do
     ptr0 <- unsafeForeignPtrToPtr <$> readIORef ref
     let len = minusPtr ptr ptr0
     when (len > 0) $ push $! B.unsafeCreate len $ \dst -> B.memcpy dst ptr0 len
@@ -562,14 +571,14 @@
   {-# INLINE allocate #-}
 
 -- | Convert a 'Builder' into a <http://hackage.haskell.org/package/wai-3.2.2.1/docs/Network-Wai.html#t:StreamingBody StreamingBody>.
-toStreamingBody :: BuilderFor StreamingEnv -> (BB.Builder -> IO ()) -> IO () -> IO ()
+toStreamingBody :: BuilderFor StreamingBackend -> (BB.Builder -> IO ()) -> IO () -> IO ()
 toStreamingBody body = \write _ -> do
   let initialSize = 4080
   fptr <- mallocForeignPtrBytes initialSize
   ref <- newIORef fptr
   let ptr = unsafeForeignPtrToPtr fptr
   Buffer _ ptr2 <- unBuilder body
-    (StreamingEnv (write . BB.byteString) ref)
+    (StreamingBackend (write . BB.byteString) ref)
     (Buffer (ptr `plusPtr` initialSize) ptr)
   fptr' <- readIORef ref
   let ptr1 = unsafeForeignPtrToPtr fptr'
