diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -2,6 +2,8 @@
 
 All rights reserved.
 
+See  http://hackage.haskell.org/package/json-builder  for original sources
+
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 
diff --git a/json-builder.cabal b/json-builder.cabal
--- a/json-builder.cabal
+++ b/json-builder.cabal
@@ -1,5 +1,5 @@
 Name:                json-builder
-Version:             0.1.0
+Version:             0.1.1
 Synopsis:            Data structure agnostic JSON serialization
 License:             BSD3
 License-file:        LICENSE
@@ -44,4 +44,4 @@
 source-repository this
   type:     git
   location: http://github.com/lpsmith/json-builder
-  tag:      v0.1.0
+  tag:      v0.1.1
diff --git a/src/Data/Json/Builder.hs b/src/Data/Json/Builder.hs
--- a/src/Data/Json/Builder.hs
+++ b/src/Data/Json/Builder.hs
@@ -85,55 +85,15 @@
 toJsonLazyByteString :: Value a => a -> BL.ByteString
 toJsonLazyByteString = toLazyByteString . toBuilder
 
-type CommaTracker = (Bool -> Builder) -> Bool -> Builder
-
-comma :: Builder -> CommaTracker
-comma b f True  =                 b ++ f False
-comma b f False = fromChar ',' ++ b ++ f False
-{-# INLINE comma #-}
-
--- |  The 'Object' type represents syntax for a json object.  It has a singleton
--- constructor 'row', and an instance of 'Monoid', so that 'mempty' represents the
--- empty object and 'mappend' concatinates two objects.  Arbitrary objects can
--- be constructed using these operators.
---
--- Note that duplicate field names will appear in the output, so it is up
--- to the user of this interface to avoid duplicate field names.
-
-newtype Object = Object CommaTracker
-
-instance Value Object where
-  toJson (Object f) = Json (fromChar '{' ++ f (\_ -> fromChar '}') True)
-
-instance Monoid Object where
-  mempty = Object id
-  mappend (Object f) (Object g) = Object (f . g)
-
 -- |  The 'row' function constructs a json object consisting of exactly
 -- one field.  These objects can be concatinated using 'mappend'.
 row :: (JsString k, Value a) => k -> a -> Object
-row k a = Object syntax
-  where
-    syntax = comma (mconcat [ toBuilder k, fromChar ':',  toBuilder a ])
-
--- |  The 'Array' type represents syntax for a json array.  It has been given
--- a singleton constructor 'element' and an instance of 'Monoid',  so that
--- 'mempty' represents the empty array and 'mappend' concatinates two arrays.
--- Arbitrary arrays can be constructed using these operators.
-
-newtype Array = Array CommaTracker
-
-instance Value Array where
-  toJson (Array f) = Json (fromChar '[' ++ f (\_ -> fromChar ']') True)
-
-instance Monoid Array where
-  mempty = Array id
-  mappend (Array f) (Array g) = Array (f . g)
+row   k a = Object (Comma (toBuilder k ++ fromChar ':' ++ toBuilder a))
 
 -- |  The 'element' function constructs a json array consisting of exactly
 -- one value.  These arrays can be concatinated using 'mappend'.
 element :: Value a => a -> Array
-element a = Array $ comma (toBuilder a)
+element a = Array  (Comma (toBuilder a))
 
 -- Primitive instances for json-builder
 
@@ -186,6 +146,8 @@
   toJson True  = Json (copyByteString "true")
   toJson False = Json (copyByteString "false")
 
+-- | must be UTF-8 encoded
+
 instance JsString BS.ByteString where
   escape x = Escaped (loop x)
     where
@@ -197,6 +159,8 @@
 
 instance Value BS.ByteString where
   toJson = toJson . escape
+
+-- | must be UTF-8 encoded
 
 instance JsString BL.ByteString where
   escape x = Escaped (loop x)
diff --git a/src/Data/Json/Builder/Internal.hs b/src/Data/Json/Builder/Internal.hs
--- a/src/Data/Json/Builder/Internal.hs
+++ b/src/Data/Json/Builder/Internal.hs
@@ -10,6 +10,7 @@
 -- invalid Json syntax the constructors provided in this module.
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 
 module Data.Json.Builder.Internal
@@ -17,6 +18,9 @@
      , Json    (..)
      , JsString(..)
      , Escaped (..)
+     , Object(..)
+     , Array(..)
+     , CommaMonoid(..)
      ) where
 
 import Prelude hiding ((++))
@@ -24,6 +28,7 @@
 import Blaze.ByteString.Builder
 import Blaze.ByteString.Builder.Char.Utf8 ( fromChar )
 import Data.ByteString(ByteString)
+import Data.ByteString.Char8()
 import Data.Monoid
 
 (++) :: Monoid a => a -> a -> a
@@ -69,3 +74,40 @@
 instance JsString Escaped where
   escape = id
 
+-- |  The 'Object' type represents syntax for a json object.  It has a singleton
+-- constructor 'row', and an instance of 'Monoid', so that 'mempty' represents the
+-- empty object and 'mappend' concatinates two objects.  Arbitrary objects can
+-- be constructed using these operators.
+--
+-- Note that duplicate field names will appear in the output, so it is up
+-- to the user of this interface to avoid duplicate field names.
+newtype Object = Object CommaMonoid deriving (Monoid)
+
+instance Value Object where
+  toJson (Object xs) = case xs of
+                         Empty    -> Json (copyByteString "{}")
+                         Comma ys -> Json (fromChar '{' ++ ys ++ fromChar '}')
+
+-- |  The 'Array' type represents syntax for a json array.  It has been given
+-- a singleton constructor 'element' and an instance of 'Monoid',  so that
+-- 'mempty' represents the empty array and 'mappend' concatinates two arrays.
+-- Arbitrary arrays can be constructed using these operators.
+
+newtype Array = Array CommaMonoid deriving (Monoid)
+
+instance Value Array where
+  toJson (Array xs) = case xs of
+                        Empty     -> Json (copyByteString "[]")
+                        Comma  ys -> Json (fromChar '[' ++ ys ++ fromChar ']')
+
+data CommaMonoid
+   = Empty
+   | Comma !Builder
+
+instance Monoid CommaMonoid where
+  mempty = Empty
+  mappend Empty     x = x
+  mappend (Comma a) x
+        = Comma (a ++ case x of
+                        Empty   -> mempty
+                        Comma b -> fromChar ',' ++ b)
