diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -11,3 +11,4 @@
 * [Ozgun Ataman](http://github.com/ozataman)
 * [fisx](http://github.com/fisx)
 * [Timo von Holtz](http://github.com/tvh)
+* [Brendan Hay](http://github.com/brendanhay)
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+0.1.7
+* Add bytestring serialization functions. This is a common use case
+  and exporting these prevents the user from directly depending on
+  blaze-builder and re-implementing these functions in every application.
+
 0.1.6
 * Add Ord instances
 
diff --git a/src/URI/ByteString.hs b/src/URI/ByteString.hs
--- a/src/URI/ByteString.hs
+++ b/src/URI/ByteString.hs
@@ -41,9 +41,19 @@
     -- * Parsing
     , parseURI
     , parseRelativeRef
+    , uriParser
+    , relativeRefParser
     -- * Serializing
     , serializeURI
+    , serializeURI'
     , serializeRelativeRef
+    , serializeRelativeRef'
+    -- * Low level utility functions
+    , urlDecode
+    , urlDecodeQuery
+    , urlEncodeQuery
+    , urlEncodePath
+    , urlEncode
     -- * Lenses
     -- ** Lenses over 'Scheme'
     , schemeBSL
diff --git a/src/URI/ByteString/Internal.hs b/src/URI/ByteString/Internal.hs
--- a/src/URI/ByteString/Internal.hs
+++ b/src/URI/ByteString/Internal.hs
@@ -52,9 +52,10 @@
 -- | URI Serializer
 -------------------------------------------------------------------------------
 
--- | Serialize a URI into a strict ByteString
--- Example:
+-- | Serialize a URI into a Builder.
 --
+-- Example of serializing + converting to a lazy "Data.ByteString.Lazy.ByteString":
+--
 -- >>> BB.toLazyByteString $ serializeURI $ URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar","baz")]}, uriFragment = Just "quux"}
 -- "http://www.example.org/foo?bar=baz#quux"
 serializeURI :: URI -> Builder
@@ -64,6 +65,10 @@
     scheme = bs $ schemeBS uriScheme
     rr = RelativeRef uriAuthority uriPath uriQuery uriFragment
 
+-- | Like 'serializeURI', with conversion into a strict 'ByteString'.
+serializeURI' :: URI -> ByteString
+serializeURI' = BB.toByteString . serializeURI
+
 -- | Like 'serializeURI', but do not render scheme.
 serializeRelativeRef :: RelativeRef -> Builder
 serializeRelativeRef RelativeRef {..} = authority <> path <> query <> fragment
@@ -74,6 +79,9 @@
     query = serializeQuery rrQuery
     fragment = maybe mempty (\s -> c8 '#' <> bs s) rrFragment
 
+-- | Like 'serializeRelativeRef', with conversion into a strict 'ByteString'.
+serializeRelativeRef' :: URI -> ByteString
+serializeRelativeRef' = BB.toByteString . serializeURI
 
 -------------------------------------------------------------------------------
 serializeQuery :: Query -> Builder
@@ -134,11 +142,11 @@
 -- >>> parseURI myLaxOptions "http://www.example.org/foo?bar[]=baz"
 -- Right (URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar[]","baz")]}, uriFragment = Nothing})
 parseURI :: URIParserOptions -> ByteString -> Either URIParseError URI
-parseURI opts = parseOnly' OtherError (uriParser opts)
+parseURI opts = parseOnly' OtherError (uriParser' opts)
 
 -- | Like 'parseURI', but do not parse scheme.
 parseRelativeRef :: URIParserOptions -> ByteString -> Either URIParseError RelativeRef
-parseRelativeRef opts = parseOnly' OtherError (relativeRefParser opts)
+parseRelativeRef opts = parseOnly' OtherError (relativeRefParser' opts)
 
 
 -------------------------------------------------------------------------------
@@ -147,19 +155,31 @@
 
 
 -------------------------------------------------------------------------------
+-- | Underlying attoparsec parser. Useful for composing with your own parsers.
+uriParser :: URIParserOptions -> Parser URI
+uriParser = unParser' . uriParser'
+
+
+-------------------------------------------------------------------------------
 -- | Toplevel parser for URIs
-uriParser :: URIParserOptions -> URIParser URI
-uriParser opts = do
+uriParser' :: URIParserOptions -> URIParser URI
+uriParser' opts = do
   scheme <- schemeParser
   void $ word8 colon `orFailWith` MalformedScheme MissingColon
-  RelativeRef authority path query fragment <- relativeRefParser opts
+  RelativeRef authority path query fragment <- relativeRefParser' opts
   return $ URI scheme authority path query fragment
 
 
 -------------------------------------------------------------------------------
+-- | Underlying attoparsec parser. Useful for composing with your own parsers.
+relativeRefParser :: URIParserOptions -> Parser RelativeRef
+relativeRefParser = unParser' . relativeRefParser'
+
+
+-------------------------------------------------------------------------------
 -- | Toplevel parser for relative refs
-relativeRefParser :: URIParserOptions -> URIParser RelativeRef
-relativeRefParser opts = do
+relativeRefParser' :: URIParserOptions -> URIParser RelativeRef
+relativeRefParser' opts = do
   (authority, path) <- hierPartParser <|> rrPathParser
   query <- queryParser opts
   frag  <- mFragmentParser
@@ -564,7 +584,7 @@
 
 -------------------------------------------------------------------------------
 -- | Decoding specifically for the query string, which decodes + as
--- space.
+-- space. Shorthand for @urlDecode True@
 urlDecodeQuery :: ByteString -> ByteString
 urlDecodeQuery = urlDecode plusToSpace
   where
@@ -590,7 +610,7 @@
 -- programmatically without doing something silly like parsing error
 -- messages. This wrapper attempts to concentrate these errors into
 -- one type.
-newtype Parser' e a = Parser' (Parser a)
+newtype Parser' e a = Parser' { unParser' :: Parser a}
                     deriving ( Functor
                              , Applicative
                              , Alternative
@@ -688,10 +708,11 @@
 
 
 -------------------------------------------------------------------------------
--- | This function was extract from the @http-types@ package. The
+-- | This function was extracted from the @http-types@ package. The
 -- license can be found in licenses/http-types/LICENSE
 urlDecode
-    :: Bool -- ^ Whether to decode '+' to ' '
+    :: Bool
+    -- ^ Whether to decode '+' to ' '
     -> BS.ByteString
     -> BS.ByteString
 urlDecode replacePlus z = fst $ BS.unfoldrN (BS.length z) go z
@@ -718,9 +739,11 @@
 
 -------------------------------------------------------------------------------
 --TODO: keep an eye on perf here. seems like a good use case for a DList. the word8 list could be a set/hashset
--- | Percent-encoding for URLs.
-urlEncode' :: [Word8] -> ByteString -> Builder
-urlEncode' extraUnreserved = mconcat . map encodeChar . BS.unpack
+
+-- | Percent-encoding for URLs. Specify a list of additional
+-- unreserved characters to permit.
+urlEncode :: [Word8] -> ByteString -> Builder
+urlEncode extraUnreserved = mconcat . map encodeChar . BS.unpack
     where
       encodeChar ch | unreserved' ch = BB.fromWord8 ch
                     | otherwise     = h2 ch
@@ -736,10 +759,12 @@
 
 
 -------------------------------------------------------------------------------
+-- | Encode a ByteString for use in the query section of a URL
 urlEncodeQuery :: ByteString -> Builder
-urlEncodeQuery = urlEncode' unreserved8
+urlEncodeQuery = urlEncode unreserved8
 
 
 -------------------------------------------------------------------------------
+-- | Encode a ByteString for use in the path section of a URL
 urlEncodePath :: ByteString -> Builder
-urlEncodePath = urlEncode' unreservedPath8
+urlEncodePath = urlEncode unreservedPath8
diff --git a/src/URI/ByteString/Lens.hs b/src/URI/ByteString/Lens.hs
--- a/src/URI/ByteString/Lens.hs
+++ b/src/URI/ByteString/Lens.hs
@@ -13,213 +13,141 @@
 -------------------------------------------------------------------------------
 
 
--- | @
--- schemeBSL :: Lens' 'Scheme' 'ByteString'
--- @
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
 schemeBSL
-  :: Functor f => (ByteString -> f ByteString) -> Scheme -> f Scheme
+  :: Lens' Scheme ByteString
 schemeBSL =
   lens schemeBS (\a b -> a { schemeBS = b})
 {-# INLINE schemeBSL #-}
 
 -------------------------------------------------------------------------------
--- | @
--- hostBSL :: Lens' 'Host' 'ByteString'
--- @
 hostBSL
-  :: Functor f => (ByteString -> f ByteString) -> Host -> f Host
+  :: Lens' Host ByteString
 hostBSL =
   lens hostBS (\a b -> a { hostBS = b})
 {-# INLINE hostBSL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- portNumberL :: Lens' 'Port' 'Int'
--- @
 portNumberL
-  :: Functor f => (Int -> f Int) -> Port -> f Port
+  :: Lens' Port Int
 portNumberL =
   lens portNumber (\a b -> a { portNumber = b})
 {-# INLINE portNumberL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- authorityUserInfoL :: Lens' 'Authority' ('Maybe' 'UserInfo')
--- @
 authorityUserInfoL
-  :: Functor f =>
-     (Maybe UserInfo -> f (Maybe UserInfo)) -> Authority -> f Authority
+  :: Lens' Authority (Maybe UserInfo)
 authorityUserInfoL =
   lens authorityUserInfo (\a b -> a { authorityUserInfo = b})
 {-# INLINE authorityUserInfoL #-}
 
 -------------------------------------------------------------------------------
--- | @
--- authorityHostL :: Lens' 'Authority' 'Host'
--- @
 authorityHostL
-  :: Functor f => (Host -> f Host) -> Authority -> f Authority
+  :: Lens' Authority Host
 authorityHostL =
   lens authorityHost (\a b -> a { authorityHost = b})
 {-# INLINE authorityHostL #-}
 
 -------------------------------------------------------------------------------
--- | @
--- authorityPortL :: Lens' 'Authority' ('Maybe' 'Port')
--- @
 authorityPortL
-  :: Functor f =>
-     (Maybe Port -> f (Maybe Port)) -> Authority -> f Authority
+  :: Lens' Authority (Maybe Port)
 authorityPortL =
   lens authorityPort (\a b -> a { authorityPort = b})
 {-# INLINE authorityPortL #-}
 
 -------------------------------------------------------------------------------
--- | @
--- uiUsernameL :: Lens' 'UserInfo' 'ByteString'
--- @
 uiUsernameL
-  :: Functor f =>
-     (ByteString -> f ByteString) -> UserInfo -> f UserInfo
+  :: Lens' UserInfo ByteString
 uiUsernameL =
   lens uiUsername (\a b -> a { uiUsername = b})
 {-# INLINE uiUsernameL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- uiPasswordL :: Lens' 'UserInfo' 'ByteString'
--- @
 uiPasswordL
-  :: Functor f =>
-     (ByteString -> f ByteString) -> UserInfo -> f UserInfo
+  :: Lens' UserInfo ByteString
 uiPasswordL =
   lens uiPassword (\a b -> a { uiPassword = b})
 {-# INLINE uiPasswordL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- queryPairsL :: Lens' 'Query' [('ByteString', 'ByteString')]
--- @
 queryPairsL
-  :: Functor f
-  => ([(ByteString, ByteString)] -> f [(ByteString, ByteString)])
-  -> Query
-  -> f Query
+  :: Lens' Query [(ByteString, ByteString)]
 queryPairsL =
   lens queryPairs (\a b -> a { queryPairs = b})
 {-# INLINE queryPairsL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- uriSchemeL :: Lens' 'URI' 'Scheme'
--- @
-uriSchemeL :: Functor f => (Scheme -> f Scheme) -> URI -> f URI
+uriSchemeL :: Lens' URI Scheme
 uriSchemeL =
   lens uriScheme (\a b -> a { uriScheme = b})
 {-# INLINE uriSchemeL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- uriAuthorityL :: Lens' 'URI' ('Maybe' 'Authority')
--- @
-uriAuthorityL
-  :: Functor f =>
-     (Maybe Authority -> f (Maybe Authority)) -> URI -> f URI
+uriAuthorityL :: Lens' URI (Maybe Authority)
 uriAuthorityL =
   lens uriAuthority (\a b -> a { uriAuthority = b})
 {-# INLINE uriAuthorityL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- uriPathL :: Lens' 'URI' 'ByteString'
--- @
-uriPathL
-  :: Functor f => (ByteString -> f ByteString) -> URI -> f URI
+uriPathL :: Lens' URI ByteString
 uriPathL =
   lens uriPath (\a b -> a { uriPath = b})
 {-# INLINE uriPathL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- uriQueryL :: Lens' 'URI' 'Query'
--- @
-uriQueryL :: Functor f => (Query -> f Query) -> URI -> f URI
+uriQueryL :: Lens' URI Query
 uriQueryL =
   lens uriQuery (\a b -> a { uriQuery = b})
 {-# INLINE uriQueryL #-}
 
+
 -------------------------------------------------------------------------------
--- | @
--- uriFragmentL :: Lens' 'URI' ('Maybe' 'ByteString')
--- @
-uriFragmentL
-  :: Functor f =>
-     (Maybe ByteString -> f (Maybe ByteString)) -> URI -> f URI
+uriFragmentL :: Lens' URI (Maybe ByteString)
 uriFragmentL =
   lens uriFragment (\a b -> a { uriFragment = b})
 {-# INLINE uriFragmentL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- rrAuthorityL :: Lens' 'RelativeRef' ('Maybe' 'Authority')
--- @
-rrAuthorityL
-  :: Functor f =>
-     (Maybe Authority -> f (Maybe Authority)) -> RelativeRef -> f RelativeRef
+rrAuthorityL :: Lens' RelativeRef (Maybe Authority)
 rrAuthorityL =
   lens rrAuthority (\a b -> a { rrAuthority = b})
 {-# INLINE rrAuthorityL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- rrPathL :: Lens' 'RelativeRef' 'ByteString'
--- @
-rrPathL
-  :: Functor f => (ByteString -> f ByteString) -> RelativeRef -> f RelativeRef
+rrPathL :: Lens' RelativeRef ByteString
 rrPathL =
   lens rrPath (\a b -> a { rrPath = b})
 {-# INLINE rrPathL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- rrQueryL :: Lens' 'RelativeRef' 'Query'
--- @
-rrQueryL :: Functor f => (Query -> f Query) -> RelativeRef -> f RelativeRef
+rrQueryL :: Lens' RelativeRef Query
 rrQueryL =
   lens rrQuery (\a b -> a { rrQuery = b})
 {-# INLINE rrQueryL #-}
 
+
 -------------------------------------------------------------------------------
--- | @
--- rrFragmentL :: Lens' 'RelativeRef' ('Maybe' 'ByteString')
--- @
-rrFragmentL
-  :: Functor f =>
-     (Maybe ByteString -> f (Maybe ByteString)) -> RelativeRef -> f RelativeRef
+rrFragmentL :: Lens' RelativeRef (Maybe ByteString)
 rrFragmentL =
   lens rrFragment (\a b -> a { rrFragment = b})
 {-# INLINE rrFragmentL #-}
 
 
 -------------------------------------------------------------------------------
--- | @
--- upoValidQueryCharL :: Lens' URIParserOptions (Word8 -> Bool)
--- @
-upoValidQueryCharL
-  :: Functor f =>
-     ((Word8 -> Bool) -> f (Word8 -> Bool))
-     -> URIParserOptions -> f URIParserOptions
+upoValidQueryCharL :: Lens' URIParserOptions (Word8 -> Bool)
 upoValidQueryCharL =
   lens upoValidQueryChar (\a b -> a { upoValidQueryChar = b})
 {-# INLINE upoValidQueryCharL #-}
@@ -228,7 +156,11 @@
 -------------------------------------------------------------------------------
 -- Lens machinery
 -------------------------------------------------------------------------------
+-- Unexported type aliases to clean up the documentation
 type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
+
+type Lens' s a = Lens s s a a
+
 
 -------------------------------------------------------------------------------
 lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
diff --git a/uri-bytestring.cabal b/uri-bytestring.cabal
--- a/uri-bytestring.cabal
+++ b/uri-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                uri-bytestring
-version:             0.1.6
+version:             0.1.7
 synopsis:            Haskell URI parsing as ByteStrings
 description: uri-bytestring aims to be an RFC3986 compliant URI parser that uses efficient ByteStrings for parsing and representing the URI data.
 license:             BSD3
