diff --git a/Utils.hs b/Utils.hs
--- a/Utils.hs
+++ b/Utils.hs
@@ -1,48 +1,41 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 module Utils
-  ( readFilesL, readFilesS, decodeFile, parseJSONFiles
+  ( readFiles, decodeFile, parseJSONFiles
   , systemWithStdin)
 where
 
-import Text.JSON.AttoJSON
+import Data.Aeson
+import Data.Maybe
 import Data.Functor
 import Control.Exception
-import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as L
 import System.IO (hClose)
 import System.Exit (ExitCode)
 import System.IO.Unsafe (unsafeInterleaveIO)
 import qualified System.Process as P
 
-readFilesL :: [String] -> IO [L.ByteString]
-readFilesL args
+readFiles :: [String] -> IO [L.ByteString]
+readFiles args
   | null args = fmap (:[]) L.getContents
   | otherwise = mapM file args
   where file "-" = L.getContents
         file xs  = L.readFile xs
 
-readFilesS :: [String] -> IO [S.ByteString]
-readFilesS args
-  | null args = fmap (:[]) S.getContents
-  | otherwise = mapM file args
-  where file "-" = S.getContents
-        file xs  = S.readFile xs
-
-decodeFile :: FilePath -> IO (Either String JSValue)
-decodeFile fp = parseJSON <$> S.readFile fp
+decodeFile :: FilePath -> IO (Maybe Value)
+decodeFile fp = decode' <$> L.readFile fp
 
-decErr :: String -> a
-decErr s = error $ "JSON decoding: " ++ s
+decErr :: a
+decErr = error "JSON decoding"
 
-parseJSONFiles :: [FilePath] -> IO [JSValue]
-parseJSONFiles [] = (:[]) . either decErr id . parseJSON <$> S.getContents
-parseJSONFiles xs = mapM (unsafeInterleaveIO . fmap (either decErr id) . decodeFile) xs
+parseJSONFiles :: [FilePath] -> IO [Value]
+parseJSONFiles [] = (:[]) . fromMaybe decErr . decode' <$> L.getContents
+parseJSONFiles xs = mapM (unsafeInterleaveIO . fmap (fromMaybe decErr) . decodeFile) xs
 
-systemWithStdin :: String -> S.ByteString -> IO ExitCode
+systemWithStdin :: String -> L.ByteString -> IO ExitCode
 systemWithStdin shellCmd input = do
   (Just stdinHdl, _, _, pHdl) <-
      P.createProcess (P.shell shellCmd){ P.std_in = P.CreatePipe }
   handle (\(_ :: IOException) -> return ()) $ do
-    S.hPutStr stdinHdl input
+    L.hPutStr stdinHdl input
     hClose stdinHdl
   P.waitForProcess pHdl
diff --git a/json-concat.hs b/json-concat.hs
--- a/json-concat.hs
+++ b/json-concat.hs
@@ -1,5 +1,7 @@
-import Text.JSON.AttoJSON
-import qualified Data.ByteString as S
+import Data.Aeson
+import qualified Data.Vector as V
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.Char8 as L8
 import Control.Monad (when)
 import System.IO (hPutStrLn, stderr)
 import System.Exit (exitFailure)
@@ -16,11 +18,11 @@
 main :: IO ()
 main = do args <- getArgs
           when (not . null $ args) usage
-          S.putStrLn . showJSON . jsonConcat . either err id . parseJSON
-            =<< S.getContents
-  where jsonConcat (JSArray a)  = JSArray (concatMap unJSArray a)
-        jsonConcat (JSObject _) = error "unexpected non-JSON array"
-        jsonConcat _            = error "not a JSON document (neither array, nor object)"
-        unJSArray (JSArray a)   = a
-        unJSArray _             = error "unexpected non-JSON array"
-        err s                   = error $ "JSON decoding: " ++ s
+          L8.putStrLn . encode . jsonConcat . maybe err id . decode'
+            =<< L.getContents
+  where jsonConcat (Array a)  = Array (V.concatMap unArray a)
+        jsonConcat (Object _) = error "unexpected non-JSON array"
+        jsonConcat _          = error "not a JSON document (neither array, nor object)"
+        unArray (Array a)     = a
+        unArray _             = error "unexpected non-JSON array"
+        err                   = error "JSON decoding error"
diff --git a/json-deep-select-key.hs b/json-deep-select-key.hs
--- a/json-deep-select-key.hs
+++ b/json-deep-select-key.hs
@@ -1,22 +1,25 @@
-import qualified Data.Map as M
-import Text.JSON.AttoJSON
+import qualified Data.HashMap.Strict as HM
+import Data.Aeson
+import qualified Data.Text as T
 import System.Environment (getArgs)
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Char8 as S8
+import qualified Data.Vector as V
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.Char8 as L8
 
-deepSelectKey :: S.ByteString -> JSValue -> [JSValue]
-deepSelectKey key (JSArray vs)
-  = concatMap (deepSelectKey key) vs
-deepSelectKey key (JSObject o)
-  = maybe (concatMap (deepSelectKey key) (map snd (M.toList o))) return . M.lookup key $ o
-deepSelectKey _ _ = []
+deepSelectKey :: T.Text -> Value -> V.Vector Value
+deepSelectKey key (Array vs)
+  = V.concatMap (deepSelectKey key) vs
+deepSelectKey key (Object o)
+  = maybe (V.concatMap (deepSelectKey key) (V.fromList $ HM.elems o)) return
+  . HM.lookup key $ o
+deepSelectKey _ _ = V.empty
 
 main :: IO ()
 main = do
   args <- getArgs
-  obj <- either fail return . parseJSON =<< S.getContents
+  obj <- maybe (fail "JSON decoding") return . decode' =<< L.getContents
   case args of
     [key] ->
-      S.putStrLn . showJSON . JSArray $ deepSelectKey (S8.pack key) obj
+      L8.putStrLn . encode . Array $ deepSelectKey (T.pack key) obj
     _ -> error "Usage: json-deep-select-key <key>"
 
diff --git a/json-iter.hs b/json-iter.hs
--- a/json-iter.hs
+++ b/json-iter.hs
@@ -2,16 +2,17 @@
 import System.IO (hPutStrLn, stderr)
 import System.Exit (exitFailure)
 import Control.Monad (when)
-import Text.JSON.AttoJSON
+import Data.Aeson
 import Utils (parseJSONFiles, systemWithStdin)
+import qualified Data.Vector as V
 
-unSequence :: JSValue -> [JSValue]
-unSequence (JSArray a) = a
-unSequence _           = error "unSequence: a JSON sequence was expected"
+unSequence :: Value -> [Value]
+unSequence (Array a) = V.toList a
+unSequence _         = error "unSequence: a JSON sequence was expected"
 
 iterJSON :: String -> [String] -> IO ()
 iterJSON cmd jsonfiles =
-  mapM_ (mapM_ (systemWithStdin cmd . showJSON) . unSequence)
+  mapM_ (mapM_ (systemWithStdin cmd . encode) . unSequence)
     =<< parseJSONFiles jsonfiles
 
 usage :: IO a
diff --git a/json-lines.hs b/json-lines.hs
--- a/json-lines.hs
+++ b/json-lines.hs
@@ -1,14 +1,16 @@
-import Text.JSON.AttoJSON
-import qualified Data.ByteString.Char8 as S
+import Data.Aeson
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.Char8 as L8
 import Control.Monad (when)
 import System.Environment (getArgs)
 import System.Exit (exitFailure)
 import System.IO (hPutStrLn,stderr)
-import Utils (readFilesS)
+import Utils (readFiles)
+import qualified Data.Vector as V
 
-jsonUnlines :: JSValue -> [JSValue]
-jsonUnlines (JSArray xs) = xs
-jsonUnlines _            = error "Unexpected JSON value, only an array was expected"
+jsonUnlines :: Value -> [Value]
+jsonUnlines (Array xs) = V.toList xs
+jsonUnlines _          = error "Unexpected JSON value, only an array was expected"
 
 usage :: IO a
 usage = mapM_ (hPutStrLn stderr)
@@ -23,13 +25,13 @@
 main =
  do args <- getArgs
     when ("--help"`elem`args) usage
-    S.putStr                  -- printing the output
-     . S.unlines              -- joining lines
-     . map showJSON           -- showing each item
+    L.putStr                  -- printing the output
+     . L8.unlines             -- joining lines
+     . map encode             -- showing each item
      . concat                 -- merge lines from all files
      . map (                  -- for each file
          jsonUnlines          -- main processing
-         . either err id      -- error handling
-         . parseJSON          -- parsing each file as JSON
-       ) =<< readFilesS args  -- reading the input
-  where err msg = error $ "JSON parsing: "++msg
+         . maybe err id       -- error handling
+         . decode'            -- parsing each file as JSON
+       ) =<< readFiles args   -- reading the input
+  where err = error "JSON decoding error"
diff --git a/json-quote.hs b/json-quote.hs
new file mode 100644
--- /dev/null
+++ b/json-quote.hs
@@ -0,0 +1,6 @@
+import Data.Aeson
+import Data.ByteString.Lazy.Char8 as L8
+import System.Environment
+
+main :: IO ()
+main = L8.putStrLn . encode =<< getArgs
diff --git a/json-select.hs b/json-select.hs
--- a/json-select.hs
+++ b/json-select.hs
@@ -1,52 +1,54 @@
 import Data.List
 import Data.Monoid
-import qualified Data.Map as M
+import qualified Data.HashMap.Strict as HM
 import Control.Arrow
-import Text.JSON.AttoJSON
+import Data.Aeson
 import System.Environment (getArgs)
 import System.IO (stderr, hPutStrLn)
 import System.Exit
-import qualified Data.ByteString as S
-
-type JSObject a = M.Map S.ByteString a
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.Char8 as L8
+import Data.Text (Text)
+import qualified Data.Vector as V
 
-data JSFrame = JSArrayFrm [JSValue] [JSValue]
-             | JSObjectFrm S.ByteString (JSObject JSValue)
+data Frame = ArrayFrm Array Array
+           | ObjectFrm Text Object
   deriving (Show)
 
-type JSContext = [JSFrame]
+type Context = [Frame]
 
-data JSSegment = JSArrayIndex Int
-               | JSObjectKey  S.ByteString
-type JSPath = [JSSegment]
+data Segment = ArrayIndex Int
+             | ObjectKey  Text
+type Path = [Segment]
 
-type JSMultiPath = [Maybe JSSegment] -- Nothing means '*'
+type MultiPath = [Maybe Segment] -- Nothing means '*'
 
-type JSCxtValue = (JSContext, JSValue)
+type CxtValue = (Context, Value)
 
-segmentFromFrame :: JSFrame -> JSSegment
-segmentFromFrame (JSArrayFrm prefix _) = JSArrayIndex (length prefix)
-segmentFromFrame (JSObjectFrm f _)     = JSObjectKey f
+segmentFromFrame :: Frame -> Segment
+segmentFromFrame (ArrayFrm prefix _) = ArrayIndex (V.length prefix)
+segmentFromFrame (ObjectFrm f _)     = ObjectKey f
 
-pathFromContext :: JSContext -> JSPath
+pathFromContext :: Context -> Path
 pathFromContext = map segmentFromFrame
 
-selectJSONSegment :: JSSegment -> JSValue -> Either String (JSFrame, JSValue)
-selectJSONSegment (JSArrayIndex ix) (JSArray vs)
-  = case splitAt ix vs of
-      (prefix, v : suffix) -> Right (JSArrayFrm prefix suffix, v)
-      (_, [])              -> Left msg
+selectJSONSegment :: Segment -> Value -> Either String (Frame, Value)
+selectJSONSegment (ArrayIndex ix) (Array vs)
+  = case V.splitAt ix vs of
+      (prefix, suffix)
+        | V.null suffix -> Left msg
+        | otherwise     -> Right (ArrayFrm prefix (V.tail suffix), V.head suffix)
   where msg = "An array with an index "++show ix++" was expected"
-selectJSONSegment (JSObjectKey   f) (JSObject o)
-  = maybe (Left msg) ok . M.lookup f $ o
+selectJSONSegment (ObjectKey f) (Object o)
+  = maybe (Left msg) ok . HM.lookup f $ o
   where msg   = "An object with a field "++show f++" was expected"
-        ok x  = Right (JSObjectFrm f (M.delete f o), x)
-selectJSONSegment (JSArrayIndex  _) _
+        ok x  = Right (ObjectFrm f (HM.delete f o), x)
+selectJSONSegment (ArrayIndex  _) _
   = Left "An array was expected"
-selectJSONSegment (JSObjectKey   _) _
+selectJSONSegment (ObjectKey   _) _
   = Left "An object was expected"
 
-selectJSON :: JSCxtValue -> JSPath -> (JSContext, Either String JSValue)
+selectJSON :: CxtValue -> Path -> (Context, Either String Value)
 selectJSON (cxt,val) [] = (cxt, Right val)
 selectJSON (cxt,val) (seg:path) =
   either ((,)cxt . Left) (flip selectJSON path . first (:cxt)) (selectJSONSegment seg val)
@@ -57,33 +59,34 @@
   where go sx x []                = [f (reverse sx) x []]
         go sx x xs@(xs'x : xs'xs) = f (reverse sx) x xs : go (x : sx) xs'x xs'xs
 
-allSubValues :: JSCxtValue -> [JSCxtValue]
-allSubValues (_,   JSArray []) = []
-allSubValues (cxt, JSArray vs) = zips f vs
-  where f prefix value suffix = (JSArrayFrm prefix suffix : cxt, value)
-allSubValues (cxt, JSObject o) = map (first f) . M.toList $ o
-  where f key = JSObjectFrm key (M.delete key o) : cxt
+allSubValues :: CxtValue -> [CxtValue]
+allSubValues (cxt, Array vs)
+    | V.null vs = []
+    | otherwise = zips f (V.toList vs)
+  where f prefix value suffix = (ArrayFrm (V.fromList prefix) (V.fromList suffix) : cxt, value)
+allSubValues (cxt, Object o) = map (first f) . HM.toList $ o
+  where f key = ObjectFrm key (HM.delete key o) : cxt
 allSubValues _ = []
 
-selectJSONMaybeSegment :: Maybe JSSegment -> JSCxtValue -> [JSCxtValue]
+selectJSONMaybeSegment :: Maybe Segment -> CxtValue -> [CxtValue]
 selectJSONMaybeSegment (Just seg) (cxt,val) = either (const []) (return . first (:cxt)) $ selectJSONSegment seg val
 selectJSONMaybeSegment Nothing    cxtval = allSubValues cxtval
 
-selectMultiJSON :: JSCxtValue -> JSMultiPath -> [JSCxtValue]
+selectMultiJSON :: CxtValue -> MultiPath -> [CxtValue]
 selectMultiJSON cxtval []        = return cxtval
 selectMultiJSON cxtval (mp : ps) = selectJSONMaybeSegment mp cxtval >>= flip selectMultiJSON ps
 
 type Reader a = String -> (a, String)
 
-readJSSegment :: Reader JSSegment
+readJSSegment :: Reader Segment
 readJSSegment xs@('"':_) = case reads xs of -- TODO maybe we should use the JSON syntax for literal strings
-                             [r] -> first JSObjectKey r
+                             [r] -> first ObjectKey r
                              _   -> error "Parse error: malformed string (when reading path segment)"
 readJSSegment xs         = case reads xs of
-                             [r] -> first JSArrayIndex r
+                             [r] -> first ArrayIndex r
                              _   -> error "Parse error: malformed integer (when reading path segment)"
 
-readJSMultiSegment :: Reader (Maybe JSSegment)
+readJSMultiSegment :: Reader (Maybe Segment)
 readJSMultiSegment ('*':xs) = (Nothing, xs)
 readJSMultiSegment xs       = first Just . readJSSegment $ xs
 
@@ -93,18 +96,18 @@
 readJSPathGen r ('/':xs) = let (seg, ys) = r xs in seg : readJSPathGen r ys
 readJSPathGen _ (x:_)    = error $ "Parse error: unexpected char "++show x++", '/' was expected"
 
-readJSPath :: String -> JSPath
+readJSPath :: String -> Path
 readJSPath = readJSPathGen readJSSegment
 
-readJSMultiPath :: String -> JSMultiPath
+readJSMultiPath :: String -> MultiPath
 readJSMultiPath = readJSPathGen readJSMultiSegment
 
-showJSPath :: JSPath -> ShowS
+showJSPath :: Path -> ShowS
 showJSPath = (('/':) .) . mconcat . intersperse ('/':) . map showJSSegment
 
-showJSSegment :: JSSegment -> ShowS
-showJSSegment (JSObjectKey f)   = shows f
-showJSSegment (JSArrayIndex ix) = shows ix
+showJSSegment :: Segment -> ShowS
+showJSSegment (ObjectKey f)   = shows f
+showJSSegment (ArrayIndex ix) = shows ix
 
 -- should already exists
 distrEitherPair :: (a, Either b c) -> Either (a, b) (a, c)
@@ -127,15 +130,15 @@
 main :: IO ()
 main = do
   args <- getArgs
-  let pobj = either fail return . parseJSON =<< S.getContents
+  let pobj = maybe (fail "JSON decoding") return . decode' =<< L.getContents
   case args of
     [] -> usage "Too few arguments"
     ["-m", path] ->
       do obj <- pobj
-         S.putStrLn . showJSON . JSArray . map snd . selectMultiJSON ([], obj) . readJSMultiPath $ path
+         L8.putStrLn . encode . Array . V.fromList . map snd . selectMultiJSON ([], obj) . readJSMultiPath $ path
     [path] ->
       do obj <- pobj
-         either err (S.putStrLn . showJSON . snd) . distrEitherPair $ selectJSON ([], obj) (readJSPath path)
+         either err (L8.putStrLn . encode . snd) . distrEitherPair $ selectJSON ([], obj) (readJSPath path)
       where err (cxt, msg) = hPutStrLn stderr $ (showString msg . showString "\nLocation in the structure: " . showJSPath (pathFromContext cxt)) ""
     _ -> usage "Too many arguments"
 
diff --git a/json-strings.hs b/json-strings.hs
--- a/json-strings.hs
+++ b/json-strings.hs
@@ -1,22 +1,26 @@
-import Text.JSON.AttoJSON
-import qualified Data.ByteString as S
+import Data.Aeson
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.Char8 as L8
 import Data.Monoid
+import Data.Maybe
 import Data.Foldable hiding (mapM_)
 import Control.Monad (when)
 import System.IO (hPutStrLn, stderr)
 import System.Environment (getArgs)
 import System.Exit (exitFailure)
+import qualified Data.Text as T
+import qualified Data.Vector as V
 
 -- NOTE that the map keys are not included
 
-jsonStrings :: JSValue -> [S.ByteString]
+jsonStrings :: Value -> [T.Text]
 jsonStrings x0 = appEndo (go x0) []
-  where go (JSString s) = Endo (s:)
-        go (JSNumber _) = mempty
-        go (JSBool   _) = mempty
-        go JSNull       = mempty
-        go (JSObject m) = foldMap go m
-        go (JSArray xs) = foldMap go xs
+  where go (String s) = Endo (s:)
+        go (Number _) = mempty
+        go (Bool   _) = mempty
+        go Null       = mempty
+        go (Object m) = foldMap go m
+        go (Array xs) = foldMap go xs
 
 usage :: IO a
 usage = mapM_ (hPutStrLn stderr)
@@ -30,9 +34,10 @@
 main = do
   args <- getArgs
   when (not . null $ args) usage
-  S.putStrLn . showJSON             -- printing the output
-     . JSArray . map JSString       -- building the result
+  L8.putStrLn . encode              -- printing the output
+     . Array . V.fromList           -- building the result
+     . map String                   -- building the elements
      . jsonStrings                  -- main processing
-     . either err id                -- error handling
-     . parseJSON =<< S.getContents  -- reading the input
-  where err = error . ("JSON parsing: "++)
+     . fromMaybe err                -- error handling
+     . decode' =<< L.getContents    -- reading the input
+  where err = error "JSON parsing"
diff --git a/json-tools.cabal b/json-tools.cabal
--- a/json-tools.cabal
+++ b/json-tools.cabal
@@ -1,6 +1,6 @@
 Name:           json-tools
 Cabal-Version:  >=1.6
-Version:        0.3.1
+Version:        0.4.0
 License:        BSD3
 License-File:   LICENSE
 Copyright:      (c) Nicolas Pouillard
@@ -14,34 +14,34 @@
 
 executable json-concat
     main-is: json-concat.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring
+    Build-depends: base>=3&&<5, aeson, bytestring
     ghc-options: -Wall -Odph
 
 executable json-deep-select-key
     main-is: json-deep-select-key.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring, containers
+    Build-depends: base>=3&&<5, aeson, bytestring, containers
     ghc-options: -Wall -Odph
 
 executable json-select
     main-is: json-select.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring, containers
+    Build-depends: base>=3&&<5, aeson, bytestring, containers
     ghc-options: -Wall -Odph
 
 executable json-iter
     main-is: json-iter.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring, process
+    Build-depends: base>=3&&<5, aeson, bytestring, process
     Other-modules: Utils
     ghc-options: -Wall -Odph
 
 executable json-lines
     main-is: json-lines.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring
+    Build-depends: base>=3&&<5, aeson, bytestring
     Other-modules: Utils
     ghc-options: -Wall -Odph
 
 executable json-strings
     main-is: json-strings.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring
+    Build-depends: base>=3&&<5, aeson, bytestring
     ghc-options: -Wall -Odph
 
 executable json-unlines
@@ -52,17 +52,23 @@
 
 executable json-wrap
     main-is: json-wrap.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring
+    Build-depends: base>=3&&<5, aeson, bytestring, vector
     ghc-options: -Wall -Odph
 
 executable json-xargs
     main-is: json-xargs.hs
-    Build-depends: base>=3&&<5, AttoJson, bytestring
+    Build-depends: base>=3&&<5, aeson, bytestring
     ghc-options: -Wall -Odph
 
 executable tar2json
     main-is: tar2json.hs
-    Build-depends: base>=3&&<5, bytestring, convertible-text, data-object, data-object-json, tar
+    Build-depends: base>=3&&<5, bytestring, aeson, unordered-containers,
+                   text, tar>=0.4.0
+    ghc-options: -Wall -Odph
+
+executable json-quote
+    main-is: json-quote.hs
+    Build-depends: base>=3&&<5, aeson, text
     ghc-options: -Wall -Odph
 
 source-repository head
diff --git a/json-unlines.hs b/json-unlines.hs
--- a/json-unlines.hs
+++ b/json-unlines.hs
@@ -4,7 +4,7 @@
 import System.Environment (getArgs)
 import System.Exit (exitFailure)
 import System.IO (hPutStrLn,stderr)
-import Utils (readFilesL)
+import Utils (readFiles)
 
 usage :: IO a
 usage = mapM_ (hPutStrLn stderr)
@@ -20,5 +20,5 @@
   args <- getArgs
   when ("--help"`elem`args) usage
   L.putStrLn . L.cons '[' . L.intercalate "\n," . L.lines . L.concat
-    =<< readFilesL args
+    =<< readFiles args
   L.putStrLn "]"
diff --git a/json-wrap.hs b/json-wrap.hs
--- a/json-wrap.hs
+++ b/json-wrap.hs
@@ -1,18 +1,22 @@
 {-# LANGUAGE OverloadedStrings #-}
 import Data.List (intersperse)
-import Data.Map (toList)
 import Data.Monoid
-import Text.JSON.AttoJSON
-import qualified Data.ByteString as S
+import Data.Aeson
+import Data.Maybe
+import qualified Data.HashMap.Strict as HM
+import qualified Data.Vector as V
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.Char8 as L8
 
 -- wrap, as in line-wrapping
 
 main :: IO ()
-main = mapM_ S.putStr . ($["\n"]) . f . either err id . parseJSON =<< S.getContents
-  where f (JSArray a)   = t"[" . cat (intersperse (t"\n,") (map (t . showJSON) a)) . t"]"
-        f (JSObject o)  = t"{" . cat (intersperse (t"\n,") (map g . toList $ o)) . t"}"
-        f _             = error "impossible by decodeStrict post-condition"
-        g (key, val)    = t key . t ":" . (t . showJSON) val
-        err s           = error $ "JSON decoding: " ++ s
-        t x             = (x:)
-        cat             = appEndo . mconcat . map Endo
+main = mapM_ L.putStr . ($["\n"]) . f . fromMaybe err . decode' =<< L.getContents
+  where f (Array a)   = t"[" . cat (intersperse (t"\n,") (map j . V.toList $ a)) . t"]"
+        f (Object o)  = t"{" . cat (intersperse (t"\n,") (map g . HM.toList $ o)) . t"}"
+        f _           = error "impossible by decodeStrict post-condition"
+        g (key, val)  = t (encode key) . t(L8.pack ":") . j val
+        j             = t . encode
+        err           = error "JSON decoding"
+        t x           = (x:)
+        cat           = appEndo . mconcat . map Endo
diff --git a/json-xargs.hs b/json-xargs.hs
--- a/json-xargs.hs
+++ b/json-xargs.hs
@@ -1,6 +1,8 @@
-import Text.JSON.AttoJSON
-import qualified Data.ByteString.Char8 as S
+import Data.Aeson
+import qualified Data.ByteString.Lazy as L
+import Data.Text as T
 import Data.Monoid
+import Data.Maybe
 import Data.Foldable
 import Data.Functor
 import System.Environment
@@ -9,20 +11,20 @@
 
 -- NOTE that the map keys are not included
 
-jsonArgs :: JSValue -> [String]
+jsonArgs :: Value -> [String]
 jsonArgs x0 = appEndo (go x0) []
-  where go (JSString s) = f (S.unpack s)
-        go (JSNumber n) = f (show n)
-        go (JSBool   b) = f (if b then "true" else "false")
-        go JSNull       = f "null"
-        go (JSObject m) = foldMap go m
-        go (JSArray xs) = foldMap go xs
+  where go (String s) = f (T.unpack s)
+        go (Number n) = f (show n)
+        go (Bool   b) = f (if b then "true" else "false")
+        go Null       = f "null"
+        go (Object m) = foldMap go m
+        go (Array xs) = foldMap go xs
         f x = Endo (x:)
 
 main :: IO ()
 main = do cmd:argv <- getArgs
-          args <- jsonArgs                     -- main processing
-                . either err id                -- error handling
-                . parseJSON <$> S.getContents  -- reading the input
+          args <- jsonArgs                   -- main processing
+                . fromMaybe err              -- error handling
+                . decode' <$> L.getContents  -- reading the input
           exitWith =<< rawSystem cmd (argv ++ args)
-  where err = error . ("JSON parsing: "++)
+  where err = error "Invalid JSON input"
diff --git a/tar2json.hs b/tar2json.hs
--- a/tar2json.hs
+++ b/tar2json.hs
@@ -1,26 +1,26 @@
 import Codec.Archive.Tar as Tar
-import Data.Convertible.Base (convertSuccess)
-import Data.Object
-import Data.Object.Json as Json
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Char8 as S8
+import qualified Data.HashMap.Strict as HM
+import qualified Data.Aeson as Aeson
+import qualified Data.Text as T
 import qualified Data.ByteString.Lazy as L
 import System.IO
 
-tar2json :: Tar.Entries -> JsonObject
-tar2json es0 = Mapping [(k,v) | (k,Just v) <- entries es0] where
+{-TODO currently does not work for binary files-}
 
-  entries :: Tar.Entries -> [(S.ByteString, Maybe JsonObject)]
+tar2json :: Tar.Entries FormatError -> Aeson.Value
+tar2json es0 = Aeson.Object $ HM.fromList [(k,v) | (k,Just v) <- entries es0] where
+
+  entries :: Tar.Entries FormatError -> [(T.Text, Maybe Aeson.Value)]
   entries Done         = []
-  entries (Fail s)     = error s
+  entries (Fail s)     = error . show $ s
   entries (Next e es)  = (path e, contents e) : entries es
 
-  path :: Tar.Entry -> S.ByteString
-  path = S8.pack {- Is this an encoding mistake? -} . entryPath
+  path :: Tar.Entry -> T.Text
+  path = T.pack . entryPath
 
-  contents :: Tar.Entry -> Maybe JsonObject
-  contents = fmap (Scalar . JsonString) . f . entryContent where
-    f (NormalFile s _) = Just (convertSuccess s)
+  contents :: Tar.Entry -> Maybe Aeson.Value
+  contents = fmap Aeson.toJSON . f . entryContent where
+    f (NormalFile s _) = Just s
     f _                = Nothing
 
 main :: IO ()
@@ -28,8 +28,8 @@
  = do hPutStrLn stderr "Reading standard input..."
       hSetEncoding stdin latin1
       hSetEncoding stdout latin1
-      S.putStr            -- printing output
-       . Json.encode      -- producing JSON
+      L.putStr            -- printing output
+       . Aeson.encode     -- producing JSON
        . tar2json         -- main translation
        . Tar.read         -- reading the archive
        =<< L.getContents  -- reading the input
