diff --git a/demo/Main.hs b/demo/Main.hs
--- a/demo/Main.hs
+++ b/demo/Main.hs
@@ -4,7 +4,7 @@
 import Data.ByteString (ByteString)
 import Data.Text (Text)
 import qualified JSONBytesBuilder.Builder as A
-import qualified JSONBytesBuilder.Interpreters.ByteString as B
+import qualified JSONBytesBuilder.ByteString.ByteString as B
 import qualified Data.ByteString.Char8 as C
 
 
diff --git a/json-bytes-builder.cabal b/json-bytes-builder.cabal
--- a/json-bytes-builder.cabal
+++ b/json-bytes-builder.cabal
@@ -1,7 +1,7 @@
 name:
   json-bytes-builder
 version:
-  0.3
+  0.4
 synopsis:
   Direct-to-bytes JSON Builder
 description:
@@ -47,14 +47,15 @@
   default-language:
     Haskell2010
   other-modules:
-    JSONBytesBuilder.Prelude
-    JSONBytesBuilder.ByteString.BoundedPrims
-    JSONBytesBuilder.ByteString.Builders
+    JSONBytesBuilder.Private.Prelude
+    JSONBytesBuilder.Private.ByteString.BoundedPrim
+    JSONBytesBuilder.Private.ByteString.Builder
+    JSONBytesBuilder.Private.Builder
   exposed-modules:
     JSONBytesBuilder.Builder
-    JSONBytesBuilder.Interpreters.ByteStringBuilder
-    JSONBytesBuilder.Interpreters.ByteString
-    JSONBytesBuilder.Interpreters.LazyByteString
+    JSONBytesBuilder.ByteString.Builder
+    JSONBytesBuilder.ByteString.ByteString
+    JSONBytesBuilder.ByteString.LazyByteString
   build-depends:
     scientific == 0.3.*,
     text == 1.*,
diff --git a/library/JSONBytesBuilder/Builder.hs b/library/JSONBytesBuilder/Builder.hs
--- a/library/JSONBytesBuilder/Builder.hs
+++ b/library/JSONBytesBuilder/Builder.hs
@@ -22,140 +22,4 @@
 )
 where
 
-import JSONBytesBuilder.Prelude hiding (null)
-import qualified Data.ByteString.Builder as A
-import qualified JSONBytesBuilder.ByteString.Builders as E
-
-
--- |
--- Builder of any JSON literal.
-newtype Literal =
-  Literal A.Builder
-
--- |
--- Builder of JSON Object rows.
-newtype Rows =
-  Rows (Maybe A.Builder)
-
-instance Monoid Rows where
-  {-# INLINE mempty #-}
-  mempty =
-    Rows Nothing
-  {-# INLINE mappend #-}
-  mappend =
-    \case
-      Rows (Just left) ->
-        \case
-          Rows (Just right) ->
-            Rows (Just (left <> A.char8 ',' <> right))
-          _ ->
-            Rows (Just left)
-      Rows Nothing ->
-        id
-
--- |
--- Builder of JSON Array elements.
-newtype Elements =
-  Elements (Maybe A.Builder)
-
-instance Monoid Elements where
-  {-# INLINE mempty #-}
-  mempty =
-    Elements Nothing
-  {-# INLINE mappend #-}
-  mappend =
-    \case
-      Elements (Just left) ->
-        \case
-          Elements (Just right) ->
-            Elements (Just (left <> A.char8 ',' <> right))
-          _ ->
-            Elements (Just left)
-      Elements Nothing ->
-        id
-
--- |
--- JSON Null literal.
-{-# INLINE null #-}
-null :: Literal
-null =
-  Literal (inline E.null)
-
--- |
--- JSON Boolean literal from 'Bool'.
-{-# INLINE boolean #-}
-boolean :: Bool -> Literal
-boolean =
-  Literal . inline E.boolean
-
--- |
--- JSON Number literal from 'Int'.
-{-# INLINE number_int #-}
-number_int :: Int -> Literal
-number_int =
-  Literal . inline A.intDec
-
--- |
--- JSON Number literal from 'Integer'.
-{-# INLINE number_integer #-}
-number_integer :: Integer -> Literal
-number_integer =
-  Literal . inline A.integerDec
-
--- |
--- JSON Number literal from 'Double'.
-{-# INLINE number_double #-}
-number_double :: Double -> Literal
-number_double =
-  Literal . inline A.doubleDec
-
--- |
--- JSON Number literal from 'Scientific'.
-{-# INLINE number_scientific #-}
-number_scientific :: Scientific -> Literal
-number_scientific =
-  Literal . inline E.scientific
-
--- |
--- JSON String literal from 'Text'.
-{-# INLINE string #-}
-string :: Text -> Literal
-string =
-  Literal . inline E.string
-
--- |
--- JSON Object literal from the 'Rows' builder.
-{-# INLINE object #-}
-object :: Rows -> Literal
-object (Rows x) =
-  Literal (maybe E.emptyObject (inline E.inCurlies) x)
-
--- |
--- JSON Array literal from the 'Elements' builder.
-{-# INLINE array #-}
-array :: Elements -> Literal
-array (Elements x) =
-  Literal (maybe E.emptyArray (inline E.inSquarelies) x)
-
--- |
--- Rows builder from a key-value pair,
--- where value is an already encoded JSON literal.
--- 
--- Use the 'Rows' 'Monoid' instance
--- to construct multi-row objects.
-{-# INLINE row #-}
-row :: Text -> Literal -> Rows
-row key (Literal literal) =
-  Rows (Just (inline E.row key literal))
-
--- |
--- Elements builder from an element,
--- which is an already encoded JSON literal.
--- 
--- Use the 'Elements' 'Monoid' instance
--- to construct multi-element arrays.
-{-# INLINE element #-}
-element :: Literal -> Elements
-element (Literal literal) =
-  Elements (Just literal)
-
+import JSONBytesBuilder.Private.Builder
diff --git a/library/JSONBytesBuilder/ByteString/BoundedPrims.hs b/library/JSONBytesBuilder/ByteString/BoundedPrims.hs
deleted file mode 100644
--- a/library/JSONBytesBuilder/ByteString/BoundedPrims.hs
+++ /dev/null
@@ -1,72 +0,0 @@
-module JSONBytesBuilder.ByteString.BoundedPrims
-where
-
-import JSONBytesBuilder.Prelude
-import Data.ByteString.Builder.Prim
-
-
-{-# INLINE null #-}
-null :: BoundedPrim ()
-null =
-  ascii4 ('n', ('u', ('l', 'l')))
-
-{-# INLINE boolean #-}
-boolean :: BoundedPrim Bool
-boolean =
-  condB id (ascii4 ('t', ('r', ('u', 'e')))) (ascii5 ('f', ('a', ('l', ('s', 'e')))))
-
-{-# INLINE emptyArray #-}
-emptyArray :: BoundedPrim ()
-emptyArray =
-  ascii2 ('[', ']')
-
-{-# INLINE emptyObject #-}
-emptyObject :: BoundedPrim ()
-emptyObject =
-  ascii2 ('{', '}')
-
-{-# INLINE stringEncodedByte #-}
-stringEncodedByte :: BoundedPrim Word8
-stringEncodedByte =
-  condB (== (fromIntegral . ord) '\\') (ascii2 ('\\', '\\')) $
-  condB (== (fromIntegral . ord) '\"') (ascii2 ('\\', '"')) $
-  condB (>= (fromIntegral . ord) '\x20') (liftFixedToBounded word8) $
-  condB (== (fromIntegral . ord) '\n') (ascii2 ('\\', 'n')) $
-  condB (== (fromIntegral . ord) '\r') (ascii2 ('\\', 'r')) $
-  condB (== (fromIntegral . ord) '\t') (ascii2 ('\\', 't')) $
-  hexEncodedByte
-
-{-# INLINE hexEncodedByte #-}
-hexEncodedByte :: BoundedPrim Word8
-hexEncodedByte =
-  liftFixedToBounded ((\c -> ('\\', ('u', fromIntegral c))) >$< char8 >*< char8 >*< word16HexFixed)
-
-{-# INLINE ascii2 #-}
-ascii2 :: (Char, Char) -> BoundedPrim a
-ascii2 cs =
-  liftFixedToBounded $
-  const cs >$< char8 >*< char8
-
-{-# INLINE ascii4 #-}
-ascii4 :: (Char, (Char, (Char, Char))) -> BoundedPrim a
-ascii4 cs =
-  liftFixedToBounded $
-  const cs >$< char8 >*< char8 >*< char8 >*< char8
-
-{-# INLINE ascii5 #-}
-ascii5 :: (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a
-ascii5 cs =
-  liftFixedToBounded $
-  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8
-
-{-# INLINE ascii6 #-}
-ascii6 :: (Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim a
-ascii6 cs =
-  liftFixedToBounded $ 
-  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8
-
-{-# INLINE ascii8 #-}
-ascii8 :: (Char, (Char, (Char, (Char, (Char, (Char, (Char, Char))))))) -> BoundedPrim a
-ascii8 cs =
-  liftFixedToBounded $
-  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8
diff --git a/library/JSONBytesBuilder/ByteString/Builder.hs b/library/JSONBytesBuilder/ByteString/Builder.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/ByteString/Builder.hs
@@ -0,0 +1,17 @@
+module JSONBytesBuilder.ByteString.Builder
+(
+  jsonLiteral,
+)
+where
+
+import JSONBytesBuilder.Private.Prelude hiding (length, null)
+import JSONBytesBuilder.Private.Builder
+import Data.ByteString.Builder
+
+
+-- |
+-- Produce a JSON ByteString builder with compact syntax from a literal builder.
+{-# INLINE jsonLiteral #-}
+jsonLiteral :: Literal -> Builder
+jsonLiteral (Literal builder) =
+  builder
diff --git a/library/JSONBytesBuilder/ByteString/Builders.hs b/library/JSONBytesBuilder/ByteString/Builders.hs
deleted file mode 100644
--- a/library/JSONBytesBuilder/ByteString/Builders.hs
+++ /dev/null
@@ -1,66 +0,0 @@
-module JSONBytesBuilder.ByteString.Builders
-where
-
-import JSONBytesBuilder.Prelude hiding (length, null)
-import Data.ByteString.Builder
-import qualified JSONBytesBuilder.ByteString.BoundedPrims as A
-import qualified Data.ByteString.Builder.Prim as A
-import qualified Data.Text.Encoding as B
-import qualified Data.Scientific as C
-import qualified Data.ByteString.Builder.Scientific as D
-
-
-{-# INLINABLE null #-}
-null :: Builder
-null =
-  A.primBounded A.null ()
-
-{-# INLINABLE boolean #-}
-boolean :: Bool -> Builder
-boolean =
-  A.primBounded A.boolean
-
-{-# INLINABLE string #-}
-string :: Text -> Builder
-string x =
-  char8 '"' <> B.encodeUtf8BuilderEscaped A.stringEncodedByte x <> char8 '"'
-
-{-# INLINABLE scientific #-}
-scientific :: Scientific -> Builder
-scientific n =
-  if e < 0
-    then D.scientificBuilder n
-    else integerDec (C.coefficient n * 10 ^ e)
-  where
-    e =
-      C.base10Exponent n
-
-{-# INLINABLE inCurlies #-}
-inCurlies :: Builder -> Builder
-inCurlies x =
-  char8 '{' <> x <> char8 '}'
-
-{-# INLINABLE row #-}
-row :: Text -> Builder -> Builder
-row key value =
-  string key <> char8 ':' <> value
-
-{-# INLINABLE inSquarelies #-}
-inSquarelies :: Builder -> Builder
-inSquarelies x =
-  char8 '[' <> x <> char8 ']'
-
-{-# INLINABLE commaSeparated #-}
-commaSeparated :: Builder -> Builder -> Builder
-commaSeparated left right =
-  left <> char8 ',' <> right
-
-{-# INLINABLE emptyObject #-}
-emptyObject :: Builder
-emptyObject =
-  A.primBounded A.emptyObject ()
-
-{-# INLINABLE emptyArray #-}
-emptyArray :: Builder
-emptyArray =
-  A.primBounded A.emptyArray ()
diff --git a/library/JSONBytesBuilder/ByteString/ByteString.hs b/library/JSONBytesBuilder/ByteString/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/ByteString/ByteString.hs
@@ -0,0 +1,18 @@
+module JSONBytesBuilder.ByteString.ByteString
+(
+  jsonLiteral,
+)
+where
+
+import JSONBytesBuilder.Private.Prelude hiding (length, null)
+import JSONBytesBuilder.Builder
+import qualified JSONBytesBuilder.ByteString.LazyByteString as A
+import qualified Data.ByteString.Lazy as B
+
+
+-- |
+-- Produce a strict JSON ByteString with compact syntax from a literal builder.
+{-# INLINE jsonLiteral #-}
+jsonLiteral :: Literal -> ByteString
+jsonLiteral =
+  B.toStrict . A.jsonLiteral
diff --git a/library/JSONBytesBuilder/ByteString/LazyByteString.hs b/library/JSONBytesBuilder/ByteString/LazyByteString.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/ByteString/LazyByteString.hs
@@ -0,0 +1,19 @@
+module JSONBytesBuilder.ByteString.LazyByteString
+(
+  jsonLiteral,
+)
+where
+
+import JSONBytesBuilder.Private.Prelude hiding (length, null)
+import JSONBytesBuilder.Builder
+import Data.ByteString.Builder
+import qualified JSONBytesBuilder.ByteString.Builder as A
+import qualified Data.ByteString.Lazy as B
+
+
+-- |
+-- Produce a lazy JSON ByteString with compact syntax from a literal builder.
+{-# INLINE jsonLiteral #-}
+jsonLiteral :: Literal -> B.ByteString
+jsonLiteral =
+  toLazyByteString . A.jsonLiteral
diff --git a/library/JSONBytesBuilder/Interpreters/ByteString.hs b/library/JSONBytesBuilder/Interpreters/ByteString.hs
deleted file mode 100644
--- a/library/JSONBytesBuilder/Interpreters/ByteString.hs
+++ /dev/null
@@ -1,18 +0,0 @@
-module JSONBytesBuilder.Interpreters.ByteString
-(
-  jsonLiteral,
-)
-where
-
-import JSONBytesBuilder.Prelude hiding (length, null)
-import JSONBytesBuilder.Builder
-import qualified JSONBytesBuilder.Interpreters.LazyByteString as A
-import qualified Data.ByteString.Lazy as B
-
-
--- |
--- Produce a strict JSON ByteString with compact syntax from a literal builder.
-{-# INLINE jsonLiteral #-}
-jsonLiteral :: Literal -> ByteString
-jsonLiteral =
-  B.toStrict . A.jsonLiteral
diff --git a/library/JSONBytesBuilder/Interpreters/ByteStringBuilder.hs b/library/JSONBytesBuilder/Interpreters/ByteStringBuilder.hs
deleted file mode 100644
--- a/library/JSONBytesBuilder/Interpreters/ByteStringBuilder.hs
+++ /dev/null
@@ -1,17 +0,0 @@
-module JSONBytesBuilder.Interpreters.ByteStringBuilder
-(
-  jsonLiteral,
-)
-where
-
-import JSONBytesBuilder.Prelude hiding (length, null)
-import JSONBytesBuilder.Builder
-import Data.ByteString.Builder
-
-
--- |
--- Produce a JSON ByteString builder with compact syntax from a literal builder.
-{-# INLINE jsonLiteral #-}
-jsonLiteral :: Literal -> Builder
-jsonLiteral =
-  unsafeCoerce
diff --git a/library/JSONBytesBuilder/Interpreters/LazyByteString.hs b/library/JSONBytesBuilder/Interpreters/LazyByteString.hs
deleted file mode 100644
--- a/library/JSONBytesBuilder/Interpreters/LazyByteString.hs
+++ /dev/null
@@ -1,19 +0,0 @@
-module JSONBytesBuilder.Interpreters.LazyByteString
-(
-  jsonLiteral,
-)
-where
-
-import JSONBytesBuilder.Prelude hiding (length, null)
-import JSONBytesBuilder.Builder
-import Data.ByteString.Builder
-import qualified JSONBytesBuilder.Interpreters.ByteStringBuilder as A
-import qualified Data.ByteString.Lazy as B
-
-
--- |
--- Produce a lazy JSON ByteString with compact syntax from a literal builder.
-{-# INLINE jsonLiteral #-}
-jsonLiteral :: Literal -> B.ByteString
-jsonLiteral =
-  toLazyByteString . A.jsonLiteral
diff --git a/library/JSONBytesBuilder/Prelude.hs b/library/JSONBytesBuilder/Prelude.hs
deleted file mode 100644
--- a/library/JSONBytesBuilder/Prelude.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module JSONBytesBuilder.Prelude
-(
-  module Exports,
-)
-where
-
-import BasePrelude as Exports hiding ((<>))
-import Data.Semigroup as Exports (Semigroup(..))
-import Data.Text as Exports (Text)
-import Data.ByteString as Exports (ByteString)
-import Data.Scientific as Exports (Scientific)
diff --git a/library/JSONBytesBuilder/Private/Builder.hs b/library/JSONBytesBuilder/Private/Builder.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/Private/Builder.hs
@@ -0,0 +1,140 @@
+module JSONBytesBuilder.Private.Builder
+where
+
+import JSONBytesBuilder.Private.Prelude hiding (null)
+import qualified Data.ByteString.Builder as A
+import qualified JSONBytesBuilder.Private.ByteString.Builder as E
+
+
+-- |
+-- Builder of any JSON literal.
+newtype Literal =
+  Literal A.Builder
+
+-- |
+-- Builder of JSON Object rows.
+newtype Rows =
+  Rows (Maybe A.Builder)
+
+instance Monoid Rows where
+  {-# INLINE mempty #-}
+  mempty =
+    Rows Nothing
+  {-# INLINE mappend #-}
+  mappend =
+    \case
+      Rows (Just left) ->
+        \case
+          Rows (Just right) ->
+            Rows (Just (left <> A.char8 ',' <> right))
+          _ ->
+            Rows (Just left)
+      Rows Nothing ->
+        id
+
+-- |
+-- Builder of JSON Array elements.
+newtype Elements =
+  Elements (Maybe A.Builder)
+
+instance Monoid Elements where
+  {-# INLINE mempty #-}
+  mempty =
+    Elements Nothing
+  {-# INLINE mappend #-}
+  mappend =
+    \case
+      Elements (Just left) ->
+        \case
+          Elements (Just right) ->
+            Elements (Just (left <> A.char8 ',' <> right))
+          _ ->
+            Elements (Just left)
+      Elements Nothing ->
+        id
+
+-- |
+-- JSON Null literal.
+{-# INLINE null #-}
+null :: Literal
+null =
+  Literal (inline E.null)
+
+-- |
+-- JSON Boolean literal from 'Bool'.
+{-# INLINE boolean #-}
+boolean :: Bool -> Literal
+boolean =
+  Literal . inline E.boolean
+
+-- |
+-- JSON Number literal from 'Int'.
+{-# INLINE number_int #-}
+number_int :: Int -> Literal
+number_int =
+  Literal . inline A.intDec
+
+-- |
+-- JSON Number literal from 'Integer'.
+{-# INLINE number_integer #-}
+number_integer :: Integer -> Literal
+number_integer =
+  Literal . inline A.integerDec
+
+-- |
+-- JSON Number literal from 'Double'.
+{-# INLINE number_double #-}
+number_double :: Double -> Literal
+number_double =
+  Literal . inline A.doubleDec
+
+-- |
+-- JSON Number literal from 'Scientific'.
+{-# INLINE number_scientific #-}
+number_scientific :: Scientific -> Literal
+number_scientific =
+  Literal . inline E.scientific
+
+-- |
+-- JSON String literal from 'Text'.
+{-# INLINE string #-}
+string :: Text -> Literal
+string =
+  Literal . inline E.string
+
+-- |
+-- JSON Object literal from the 'Rows' builder.
+{-# INLINE object #-}
+object :: Rows -> Literal
+object (Rows x) =
+  Literal (maybe E.emptyObject (inline E.inCurlies) x)
+
+-- |
+-- JSON Array literal from the 'Elements' builder.
+{-# INLINE array #-}
+array :: Elements -> Literal
+array (Elements x) =
+  Literal (maybe E.emptyArray (inline E.inSquarelies) x)
+
+-- |
+-- Rows builder from a key-value pair,
+-- where value is an already encoded JSON literal.
+-- 
+-- Use the 'Rows' 'Monoid' instance
+-- to construct multi-row objects.
+{-# INLINE row #-}
+row :: Text -> Literal -> Rows
+row key (Literal literal) =
+  Rows (Just (inline E.row key literal))
+
+-- |
+-- Elements builder from an element,
+-- which is an already encoded JSON literal.
+-- 
+-- Use the 'Elements' 'Monoid' instance
+-- to construct multi-element arrays.
+{-# INLINE element #-}
+element :: Literal -> Elements
+element (Literal literal) =
+  Elements (Just literal)
+
diff --git a/library/JSONBytesBuilder/Private/ByteString/BoundedPrim.hs b/library/JSONBytesBuilder/Private/ByteString/BoundedPrim.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/Private/ByteString/BoundedPrim.hs
@@ -0,0 +1,72 @@
+module JSONBytesBuilder.Private.ByteString.BoundedPrim
+where
+
+import JSONBytesBuilder.Private.Prelude
+import Data.ByteString.Builder.Prim
+
+
+{-# INLINE null #-}
+null :: BoundedPrim ()
+null =
+  ascii4 ('n', ('u', ('l', 'l')))
+
+{-# INLINE boolean #-}
+boolean :: BoundedPrim Bool
+boolean =
+  condB id (ascii4 ('t', ('r', ('u', 'e')))) (ascii5 ('f', ('a', ('l', ('s', 'e')))))
+
+{-# INLINE emptyArray #-}
+emptyArray :: BoundedPrim ()
+emptyArray =
+  ascii2 ('[', ']')
+
+{-# INLINE emptyObject #-}
+emptyObject :: BoundedPrim ()
+emptyObject =
+  ascii2 ('{', '}')
+
+{-# INLINE stringEncodedByte #-}
+stringEncodedByte :: BoundedPrim Word8
+stringEncodedByte =
+  condB (== (fromIntegral . ord) '\\') (ascii2 ('\\', '\\')) $
+  condB (== (fromIntegral . ord) '\"') (ascii2 ('\\', '"')) $
+  condB (>= (fromIntegral . ord) '\x20') (liftFixedToBounded word8) $
+  condB (== (fromIntegral . ord) '\n') (ascii2 ('\\', 'n')) $
+  condB (== (fromIntegral . ord) '\r') (ascii2 ('\\', 'r')) $
+  condB (== (fromIntegral . ord) '\t') (ascii2 ('\\', 't')) $
+  hexEncodedByte
+
+{-# INLINE hexEncodedByte #-}
+hexEncodedByte :: BoundedPrim Word8
+hexEncodedByte =
+  liftFixedToBounded ((\c -> ('\\', ('u', fromIntegral c))) >$< char8 >*< char8 >*< word16HexFixed)
+
+{-# INLINE ascii2 #-}
+ascii2 :: (Char, Char) -> BoundedPrim a
+ascii2 cs =
+  liftFixedToBounded $
+  const cs >$< char8 >*< char8
+
+{-# INLINE ascii4 #-}
+ascii4 :: (Char, (Char, (Char, Char))) -> BoundedPrim a
+ascii4 cs =
+  liftFixedToBounded $
+  const cs >$< char8 >*< char8 >*< char8 >*< char8
+
+{-# INLINE ascii5 #-}
+ascii5 :: (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a
+ascii5 cs =
+  liftFixedToBounded $
+  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8
+
+{-# INLINE ascii6 #-}
+ascii6 :: (Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim a
+ascii6 cs =
+  liftFixedToBounded $ 
+  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8
+
+{-# INLINE ascii8 #-}
+ascii8 :: (Char, (Char, (Char, (Char, (Char, (Char, (Char, Char))))))) -> BoundedPrim a
+ascii8 cs =
+  liftFixedToBounded $
+  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8
diff --git a/library/JSONBytesBuilder/Private/ByteString/Builder.hs b/library/JSONBytesBuilder/Private/ByteString/Builder.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/Private/ByteString/Builder.hs
@@ -0,0 +1,66 @@
+module JSONBytesBuilder.Private.ByteString.Builder
+where
+
+import JSONBytesBuilder.Private.Prelude hiding (length, null)
+import Data.ByteString.Builder
+import qualified JSONBytesBuilder.Private.ByteString.BoundedPrim as A
+import qualified Data.ByteString.Builder.Prim as A
+import qualified Data.Text.Encoding as B
+import qualified Data.Scientific as C
+import qualified Data.ByteString.Builder.Scientific as D
+
+
+{-# INLINABLE null #-}
+null :: Builder
+null =
+  A.primBounded A.null ()
+
+{-# INLINABLE boolean #-}
+boolean :: Bool -> Builder
+boolean =
+  A.primBounded A.boolean
+
+{-# INLINABLE string #-}
+string :: Text -> Builder
+string x =
+  char8 '"' <> B.encodeUtf8BuilderEscaped A.stringEncodedByte x <> char8 '"'
+
+{-# INLINABLE scientific #-}
+scientific :: Scientific -> Builder
+scientific n =
+  if e < 0
+    then D.scientificBuilder n
+    else integerDec (C.coefficient n * 10 ^ e)
+  where
+    e =
+      C.base10Exponent n
+
+{-# INLINABLE inCurlies #-}
+inCurlies :: Builder -> Builder
+inCurlies x =
+  char8 '{' <> x <> char8 '}'
+
+{-# INLINABLE row #-}
+row :: Text -> Builder -> Builder
+row key value =
+  string key <> char8 ':' <> value
+
+{-# INLINABLE inSquarelies #-}
+inSquarelies :: Builder -> Builder
+inSquarelies x =
+  char8 '[' <> x <> char8 ']'
+
+{-# INLINABLE commaSeparated #-}
+commaSeparated :: Builder -> Builder -> Builder
+commaSeparated left right =
+  left <> char8 ',' <> right
+
+{-# INLINABLE emptyObject #-}
+emptyObject :: Builder
+emptyObject =
+  A.primBounded A.emptyObject ()
+
+{-# INLINABLE emptyArray #-}
+emptyArray :: Builder
+emptyArray =
+  A.primBounded A.emptyArray ()
diff --git a/library/JSONBytesBuilder/Private/Prelude.hs b/library/JSONBytesBuilder/Private/Prelude.hs
new file mode 100644
--- /dev/null
+++ b/library/JSONBytesBuilder/Private/Prelude.hs
@@ -0,0 +1,11 @@
+module JSONBytesBuilder.Private.Prelude
+(
+  module Exports,
+)
+where
+
+import BasePrelude as Exports hiding ((<>))
+import Data.Semigroup as Exports (Semigroup(..))
+import Data.Text as Exports (Text)
+import Data.ByteString as Exports (ByteString)
+import Data.Scientific as Exports (Scientific)
