diff --git a/builder.cabal b/builder.cabal
--- a/builder.cabal
+++ b/builder.cabal
@@ -2,7 +2,7 @@
 name:
   builder
 version:
-  0.1
+  0.2
 synopsis:
   bounded ByteArray builder type
 description:
diff --git a/src/Builder.hs b/src/Builder.hs
--- a/src/Builder.hs
+++ b/src/Builder.hs
@@ -16,23 +16,23 @@
   , build
 
     -- * Construction
-  , buildUnaligned
-  , buildWord8
-  , buildWord16
-  , buildWord32
-  , buildWord64
-  , buildWord
-  , buildInt8
-  , buildInt16
-  , buildInt32
-  , buildInt64
-  , buildInt
-  , buildFloat
-  , buildDouble
-  , buildChar
-  , buildPtr
-  , buildByteArray
-  , buildFixed
+  , unaligned
+  , word8
+  , word16
+  , word32
+  , word64
+  , word
+  , int8
+  , int16
+  , int32
+  , int64
+  , int
+  , float
+  , double
+  , char
+  , ptr
+  , bytearray
+  , fixed
   ) where
 
 import Data.Primitive hiding (writeByteArray)
@@ -42,50 +42,41 @@
 import GHC.Exts hiding (build)
 import System.ByteOrder
 
-newtype Writer s = W
-  { _w :: ()
+-- | A 'Builder' for 'ByteArray's that has O(1) append.
+--   To create a 'ByteArray', use 'build'. This will only
+--   do one allocation.
+data Builder = Builder
+  { size   :: Int#
+  , writer :: forall s. ()
       => MutableByteArray# s
-      -- buffer
       -> Int#
-      -- offset into buffer
       -> (State# s -> (# State# s, Int# #))
-      -- update to offset
   }
 
-instance Semigroup (Writer s) where
-  W x <> W y = W $ \marr# ix0# s0# -> case x marr# ix0# s0# of
-    (# s1#, ix1# #) -> y marr# ix1# s1#
-  {-# inline (<>) #-}
-
-instance Monoid (Writer s) where
-  mempty = W $ \_ ix0# s0# -> (# s0#, ix0# #)
-  {-# inline mempty #-}
-
-data BI s = BI !Int !(Writer s)
-
-instance Semigroup (BI s) where
-  BI len0 w0 <> BI len1 w1 = BI (len0 + len1) (w0 <> w1)
-  {-# inline (<>) #-}
-
-instance Monoid (BI s) where
-  mempty = BI 0 mempty
-  {-# inline mempty #-}
-
--- | A 'Builder' for 'ByteArray's that has O(1) append.
---   To create a 'ByteArray', use 'build'. This will only
---   do one allocation.
-newtype Builder = Builder (forall s. BI s)
-
 instance Semigroup Builder where
-  Builder b0 <> Builder b1 = Builder (b0 <> b1)
-  {-# inline (<>) #-}
+  Builder len0 w0 <> Builder len1 w1 = Builder
+    { size   = len0 +# len1
+    , writer = \marr# ix0# s0# ->
+        case w0 marr# ix0# s0# of
+          (# s1#, ix1# #) -> w1 marr# ix1# s1#
+    }
 
 instance Monoid Builder where
-  mempty = Builder mempty
-  {-# inline mempty #-}
+  mempty = Builder
+    { size   = 0#
+    , writer = \_ ix0# s0# -> (# s0#, ix0# #)
+    }
 
-runWriter# :: Int# -> Writer s -> State# s -> (# State# s, ByteArray# #)
-runWriter# sz# (W g) = \s0# -> case newByteArray# sz# s0# of
+type Writer# s = MutableByteArray# s
+  -> Int#
+  -> (State# s -> (# State# s, Int# #))
+
+runWriter# :: ()
+  => Int#
+  -> Writer# s
+  -> State# s
+  -> (# State# s, ByteArray# #)
+runWriter# sz# g = \s0# -> case newByteArray# sz# s0# of
   (# s1#, marr# #) -> case g marr# 0# s1# of
     (# s2#, _ #) -> case unsafeFreezeByteArray# marr# s2# of
       (# s3#, b# #) -> (# s3#, b# #)
@@ -93,14 +84,14 @@
 
 -- | Convert a 'Builder' into a 'ByteArray'.
 build :: Builder -> ByteArray
-build (Builder (BI (I# len#) w)) = case runRW# (runWriter# len# w) of
+build (Builder len# w) = case runRW# (runWriter# len# w) of
   (# _, b# #) -> ByteArray b#
 {-# inline build #-}
 
 writeUnaligned :: (Prim a, PrimUnaligned a)
   => a
-  -> Writer s
-writeUnaligned a = W $ \marr# ix0# s0# ->
+  -> Writer# s
+writeUnaligned a = \marr# ix0# s0# ->
   case writeUnalignedByteArray# marr# ix0# a s0# of
     s1# -> (# s1#, ix0# +# alignment# a #)
 {-# inline writeUnaligned #-}
@@ -109,103 +100,103 @@
   => ByteArray
   -> Int
   -> Int
-  -> Writer s
+  -> Writer# s
 writeByteArray (ByteArray src#) (I# off#) (I# len#)
-  = W $ \marr# ix0# s0# ->
+  = \marr# ix0# s0# ->
       case copyByteArray# src# off# marr# ix0# len# s0# of
         s1# -> (# s1#, ix0# +# len# #)
 {-# inline writeByteArray #-}
 
 -- | A 'Builder' for any 'Prim' and 'PrimUnaligned' value.
-buildUnaligned :: (Prim a, PrimUnaligned a)
+unaligned :: (Prim a, PrimUnaligned a)
   => a
   -> Builder
-buildUnaligned a = Builder (BI (sizeOf a) (writeUnaligned a))
-{-# inline buildUnaligned #-}
+unaligned a = Builder (sizeOf# a) (writeUnaligned a)
+{-# inline unaligned #-}
 
 -- | A 'Builder' for 'Word8'.
-buildWord8 :: Word8 -> Builder
-buildWord8 = buildUnaligned
-{-# inline buildWord8 #-}
+word8 :: Word8 -> Builder
+word8 = unaligned
+{-# inline word8 #-}
 
 -- | A 'Builder' for 'Word16'.
-buildWord16 :: Word16 -> Builder
-buildWord16 = buildUnaligned
-{-# inline buildWord16 #-}
+word16 :: Word16 -> Builder
+word16 = unaligned
+{-# inline word16 #-}
 
 -- | A 'Builder' for 'Word32'.
-buildWord32 :: Word32 -> Builder
-buildWord32 = buildUnaligned
-{-# inline buildWord32 #-}
+word32 :: Word32 -> Builder
+word32 = unaligned
+{-# inline word32 #-}
 
 -- | A 'Builder' for 'Word64'.
-buildWord64 :: Word64 -> Builder
-buildWord64 = buildUnaligned
-{-# inline buildWord64 #-}
+word64 :: Word64 -> Builder
+word64 = unaligned
+{-# inline word64 #-}
 
 -- | A 'Builder' for 'Word'.
-buildWord :: Word -> Builder
-buildWord = buildUnaligned
-{-# inline buildWord #-}
+word :: Word -> Builder
+word = unaligned
+{-# inline word #-}
 
 -- | A 'Builder' for 'Int8'.
-buildInt8 :: Int8 -> Builder
-buildInt8 = buildUnaligned
-{-# inline buildInt8 #-}
+int8 :: Int8 -> Builder
+int8 = unaligned
+{-# inline int8 #-}
 
 -- | A 'Builder' for 'Int16'.
-buildInt16 :: Int16 -> Builder
-buildInt16 = buildUnaligned
-{-# inline buildInt16 #-}
+int16 :: Int16 -> Builder
+int16 = unaligned
+{-# inline int16 #-}
 
 -- | A 'Builder' for 'Int32'.
-buildInt32 :: Int32 -> Builder
-buildInt32 = buildUnaligned
-{-# inline buildInt32 #-}
+int32 :: Int32 -> Builder
+int32 = unaligned
+{-# inline int32 #-}
 
 -- | A 'Builder' for 'Int64'.
-buildInt64 :: Int64 -> Builder
-buildInt64 = buildUnaligned
-{-# inline buildInt64 #-}
+int64 :: Int64 -> Builder
+int64 = unaligned
+{-# inline int64 #-}
 
 -- | A 'Builder' for 'Int'.
-buildInt :: Int -> Builder
-buildInt = buildUnaligned
-{-# inline buildInt #-}
+int :: Int -> Builder
+int = unaligned
+{-# inline int #-}
 
 -- | A 'Builder' for 'Char'.
-buildChar :: Char -> Builder
-buildChar = buildUnaligned
-{-# inline buildChar #-}
+char :: Char -> Builder
+char = unaligned
+{-# inline char #-}
 
 -- | A 'Builder' for a 'ByteArray' slice.
-buildByteArray :: ()
+bytearray :: ()
   => ByteArray -- ^ source array
   -> Int -- ^ offset into source array
   -> Int -- ^ number of bytes to copy
   -> Builder
-buildByteArray b o n = Builder (BI n (writeByteArray b o n))
-{-# inline buildByteArray #-}
+bytearray b o n@(I# n#) = Builder n# (writeByteArray b o n)
+{-# inline bytearray #-}
 
 -- | A 'Builder' for 'Float'.
-buildFloat :: Float -> Builder
-buildFloat = buildUnaligned
-{-# inline buildFloat #-}
+float :: Float -> Builder
+float = unaligned
+{-# inline float #-}
 
 -- | A 'Builder' for 'Double'.
-buildDouble :: Double -> Builder
-buildDouble = buildUnaligned
-{-# inline buildDouble #-}
+double :: Double -> Builder
+double = unaligned
+{-# inline double #-}
 
 -- | A 'Builder' for @'Ptr' a@.
-buildPtr :: Ptr a -> Builder
-buildPtr = buildUnaligned
-{-# inline buildPtr #-}
+ptr :: Ptr a -> Builder
+ptr = unaligned
+{-# inline ptr #-}
 
 -- | A 'Builder' for @'Fixed' b a@
 --   This provides better control over endianness when writing.
-buildFixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a)
+fixed :: (FixedOrdering b, Bytes a, Prim a, PrimUnaligned a)
   => Fixed b a
   -> Builder
-buildFixed = buildUnaligned
-{-# inline buildFixed #-}
+fixed = unaligned
+{-# inline fixed #-}
