diff --git a/bunz.cabal b/bunz.cabal
--- a/bunz.cabal
+++ b/bunz.cabal
@@ -1,5 +1,5 @@
 name:                bunz
-version:             0.0.5
+version:             0.0.6
 synopsis:            CLI tool to beautify JSON string.
 description:         CLI tool to beautify JSON string.
 homepage:            https://github.com/sendyhalim/bunz
@@ -42,7 +42,7 @@
                      , bunz
                      , doctest >= 0.11
                      , hspec == 2.4.4
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -O2
   default-language:    Haskell2010
 
 source-repository head
diff --git a/src/Beautifier.hs b/src/Beautifier.hs
--- a/src/Beautifier.hs
+++ b/src/Beautifier.hs
@@ -8,9 +8,10 @@
   , splitAtHead
   ) where
 
-import           Data.Int       (Int64)
-import           Data.Monoid    ((<>))
-import qualified Data.Text.Lazy as T
+import           Data.Int               (Int64)
+import           Data.Monoid            ((<>))
+import qualified Data.Text.Lazy         as T
+import qualified Data.Text.Lazy.Builder as B
 
 -- Doctest setup
 -- $setup
@@ -18,18 +19,49 @@
 
 type IndentationLevel = Int64
 
-indentation :: T.Text
-indentation = "  "
 
-newline :: T.Text
-newline = "\n"
+-- | Lift function that works with Data.Text.Lazy
+-- to be able to work with Data.Text.Lazy.Builder.
+-- There should be a better and faster way to manipulate builder. We're using
+-- this for now because it's a lot faster than just using plain Data.Text.Lazy when
+-- concatenating text.
+liftToBuilder :: (T.Text -> T.Text) -> (B.Builder -> B.Builder)
+liftToBuilder f = B.fromLazyText . f . B.toLazyText
 
-indent :: IndentationLevel -> T.Text -> T.Text
-indent level str = T.replicate level indentation <> str
+splitAt' :: Int64 -> B.Builder -> (B.Builder, B.Builder)
+splitAt' n str = (B.fromLazyText head, B.fromLazyText tail)
+  where (head, tail) = T.splitAt n (B.toLazyText str)
 
-trimmedTail :: T.Text -> T.Text
-trimmedTail = T.stripStart . T.tail
+head' :: B.Builder -> B.Builder
+head' = B.singleton . T.head . B.toLazyText
 
+tail' :: B.Builder -> B.Builder
+tail' = liftToBuilder T.tail
+
+drop' :: Int64 -> B.Builder -> B.Builder
+drop' length = liftToBuilder (T.drop length)
+
+length' :: B.Builder -> Int64
+length' = T.length . B.toLazyText
+
+stripStart' :: B.Builder -> B.Builder
+stripStart' =  liftToBuilder T.stripStart
+
+space :: T.Text
+space = " "
+
+indentation :: IndentationLevel -> B.Builder
+indentation level = B.fromLazyText (T.replicate level space)
+
+newline :: B.Builder
+newline = B.fromLazyText "\n"
+
+indent :: IndentationLevel -> B.Builder -> B.Builder
+indent level str = indentation level <> str
+
+trimmedTail :: B.Builder -> B.Builder
+trimmedTail = B.fromLazyText . T.stripStart . T.tail . B.toLazyText
+
 -- | Split the given string at its head while honouring escaped string.
 -- Examples:
 --
@@ -38,10 +70,10 @@
 --
 -- >>> splitAtHead "\nyeay"
 -- ("\n","yeay")
-splitAtHead :: T.Text -> (T.Text, T.Text)
+splitAtHead :: B.Builder -> (B.Builder, B.Builder)
 splitAtHead "" = ("", "")
-splitAtHead str@(T.head -> '\\') = T.splitAt 2 str
-splitAtHead str = T.splitAt 1 str
+splitAtHead str@(head' -> "\\") = splitAt' 2 str
+splitAtHead str = splitAt' 1 str
 
 -- | Extract string within double quotes `"` including the double quotes ignoring
 -- the suffix after closing quote `"`
@@ -50,13 +82,13 @@
 --
 -- >>> string False "\"test\"whatuppp"
 -- "\"test\""
-string :: Bool -> T.Text -> T.Text
-string False str@(T.head -> '"') = "\"" <> string True (T.tail str)
-string True str@(T.head -> '"') = "\""
+string :: Bool -> B.Builder -> B.Builder
+string False str@(head' -> "\"") = "\"" <> string True (tail' str)
+string True str@(head' -> "\"") = "\""
 string True str = let (head, tail) = splitAtHead str in head <> string True tail
 
 -- | Extract the first string value starting from the front.
-firstString :: T.Text -> T.Text
+firstString :: B.Builder -> B.Builder
 firstString str = string False str
 
 
@@ -85,30 +117,33 @@
 --
 -- >>> extractJsonValue "false,true,false]"
 -- "false"
-extractJsonValue :: T.Text -> T.Text
-extractJsonValue = T.takeWhile (not . isEndOfValue)
+extractJsonValue :: B.Builder -> B.Builder
+extractJsonValue = liftToBuilder $ T.takeWhile (not . isEndOfValue)
 
 -- |Beautify the given JSON text based on the current indentation level.
-beautifyText :: IndentationLevel -> T.Text -> T.Text
+beautifyText :: IndentationLevel -> B.Builder -> B.Builder
 beautifyText i str
   | str == "" = ""
-  | head == ' ' = stripStartThenParse str
-  | head == '\n' = stripStartThenParse str
-  | head == '\t' = stripStartThenParse str
-  | head == '{' = nextLineAfterOpening "{"
-  | head == '[' = nextLineAfterOpening "["
-  | head == '}' = nextLineAfterClosing "}"
-  | head == ']' = nextLineAfterClosing "]"
-  | head == ',' = "," <> newline <> indent i (beautifyText i (trimmedTail str))
-  | head == '"' = let groupedString = firstString str
-                      restOfTheString = T.drop (T.length groupedString) str
-                  in groupedString <> beautifyText i restOfTheString
-  | head == ':' = ": " <> beautifyText i (trimmedTail str)
-  | otherwise = let value = extractJsonValue str
-                in value <> beautifyText i (T.drop (T.length value) str)
+  | head == " " = stripStartThenParse str
+  | head == "\n" = stripStartThenParse str
+  | head == "\t" = stripStartThenParse str
+  | head == "{" = nextLineAfterOpening "{"
+  | head == "[" = nextLineAfterOpening "["
+  | head == "}" = nextLineAfterClosing "}"
+  | head == "]" = nextLineAfterClosing "]"
+  | head == "," = "," <> newline <> indent i (beautifyText i (trimmedTail str))
+  | head == "\"" =
+      let groupedString = firstString str
+          restOfTheString = drop' (length' groupedString) str
+          in groupedString <> beautifyText i restOfTheString
+  | head == ":" = ": " <> beautifyText i (trimmedTail str)
+  | otherwise =
+      let value = extractJsonValue str
+          valueLength = length' value
+          in value <> beautifyText i (drop' valueLength str)
   where
-    head = T.head str
-    stripStartThenParse = beautifyText i . T.stripStart
+    head = head' str
+    stripStartThenParse = beautifyText i . stripStart'
     nextLineAfterOpening token = token
       <> newline
       <> indent (i + 1) (beautifyText (i + 1) (trimmedTail str))
@@ -118,4 +153,4 @@
 
 
 beautify :: T.Text -> T.Text
-beautify = beautifyText 0
+beautify = B.toLazyText . beautifyText 0 . B.fromLazyText
