diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/bench/Bench.hs b/bench/Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench/Bench.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Main where
+
+import qualified Control.Lens as L
+import           Criterion.Main
+import qualified Data.Aeson.Lens as AL
+import qualified Data.ByteString.Char8 as BS
+import qualified Data.ByteString.Lazy.Char8 as BL
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import           Lens.Micro
+import           Lens.Micro.Aeson
+
+---
+
+main :: IO ()
+main = defaultMain
+  [ bgroup "First elem in Array"
+    [ bench "microlens-aeson (String)"  $ nf (^? nth 0 . _Number) ("[1, \"x\"]" :: String)
+    , bench "microlens-aeson (T.Text)"  $ nf (^? nth 0 . _Number) ("[1, \"x\"]" :: T.Text)
+    , bench "microlens-aeson (TL.Text)" $ nf (^? nth 0 . _Number) ("[1, \"x\"]" :: TL.Text)
+    , bench "microlens-aeson (BS)"      $ nf (^? nth 0 . _Number) ("[1, \"x\"]" :: BS.ByteString)
+    , bench "microlens-aeson (BL)"      $ nf (^? nth 0 . _Number) ("[1, \"x\"]" :: BL.ByteString)
+    , bench "lens-aeson (String)"  $ nf (L.^? AL.nth 0 . AL._Number) ("[1, \"x\"]" :: String)
+    , bench "lens-aeson (T.Text)"  $ nf (L.^? AL.nth 0 . AL._Number) ("[1, \"x\"]" :: T.Text)
+    , bench "lens-aeson (TL.Text)" $ nf (L.^? AL.nth 0 . AL._Number) ("[1, \"x\"]" :: TL.Text)
+    , bench "lens-aeson (BS)"      $ nf (L.^? AL.nth 0 . AL._Number) ("[1, \"x\"]" :: BS.ByteString)
+    , bench "lens-aeson (BL)"      $ nf (L.^? AL.nth 0 . AL._Number) ("[1, \"x\"]" :: BL.ByteString) ]
+  , bgroup "Getting via `key`"
+    [ bench "microlens-aeson (Text)" $ nf (^? key "a")      ("{\"a\": 100, \"b\": 200}" :: T.Text)
+    , bench "lens-aeson (Text)"      $ nf (L.^? AL.key "a") ("{\"a\": 100, \"b\": 200}" :: T.Text) ]
+  , bgroup "Setting via `key`"
+    [ bench "microlens-aeson (Text)" $ nf (& key "a" . _Number %~ (* 10)) ("{\"a\": 100, \"b\": 200}" :: T.Text)
+    , bench "lens-aeson (Text)" $ nf (& AL.key "a" . AL._Number L.%~ (* 10)) ("{\"a\": 100, \"b\": 200}" :: T.Text) ]
+  ]
diff --git a/microlens-aeson.cabal b/microlens-aeson.cabal
--- a/microlens-aeson.cabal
+++ b/microlens-aeson.cabal
@@ -1,21 +1,23 @@
--- This file has been generated from package.yaml by hpack version 0.17.0.
+-- This file has been generated from package.yaml by hpack version 0.20.0.
 --
 -- see: https://github.com/sol/hpack
+--
+-- hash: 5c22982c3b1a50a2115914efc79c8e7576f350c249526dc8c1bcd6984e34de77
 
-name:          microlens-aeson
-category:      Numeric
-version:       2.2.0.2
-license:       MIT
-cabal-version: >= 1.10
-license-file:  LICENSE
-author:        Colin Woodbury
-maintainer:    Colin Woodbury <colingw@gmail.com>
-homepage:      http://github.com/fosskers/microlens-aeson/
-bug-reports:   http://github.com/fosskers/microlens-aeson/issues
-copyright:     Copyright (C) 2012 Paul Wilson, (C) 2013 Edward A. Kmett, (C) 2015 Colin Woodbury
-build-type:    Simple
-synopsis:      Law-abiding lenses for Aeson, using microlens.
-description:   Law-abiding lenses for Aeson, using microlens.
+name:           microlens-aeson
+version:        2.3.0
+synopsis:       Law-abiding lenses for Aeson, using microlens.
+description:    Law-abiding lenses for Aeson, using microlens.
+category:       Numeric
+homepage:       http://github.com/fosskers/microlens-aeson/
+bug-reports:    http://github.com/fosskers/microlens-aeson/issues
+author:         Colin Woodbury
+maintainer:     Colin Woodbury <colingw@gmail.com>
+copyright:      Copyright (C) 2012 Paul Wilson, (C) 2013 Edward A. Kmett, (C) 2015 Colin Woodbury
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
 
 extra-source-files:
     AUTHORS.md
@@ -29,41 +31,71 @@
   location: git://github.com/fosskers/microlens-aeson.git
 
 library
+  hs-source-dirs:
+      src
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns
   build-depends:
-      base >=4.8 && <5
-    , aeson >=0.7.0.5 && <1.3
-    , text >=0.11.1.10 && <1.3
+      aeson >=0.7.0.5 && <1.4
+    , attoparsec >=0.10 && <0.14
+    , base >=4.8 && <5
+    , bytestring
+    , deepseq
+    , hashable
     , microlens >=0.3 && <0.5
-    , bytestring >=0.9 && <0.11
+    , scientific >=0.3.2 && <0.4
+    , text >=0.11.1.10 && <1.3
     , unordered-containers >=0.2.3 && <0.3
     , vector >=0.9 && <0.13
-    , attoparsec >=0.10 && <0.14
-    , scientific >=0.3.2 && <0.4
   exposed-modules:
       Lens.Micro.Aeson
   other-modules:
       Lens.Micro.Aeson.Internal
       Paths_microlens_aeson
-  ghc-options: -fwarn-tabs -O2
-  hs-source-dirs:
-      src
   default-language: Haskell2010
 
 test-suite microlens-aeson-test
   type: exitcode-stdio-1.0
+  main-is: Test.hs
+  hs-source-dirs:
+      test
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns -threaded
   build-depends:
-      base >=4.8 && <5
-    , aeson >=0.7.0.5 && <1.3
-    , text >=0.11.1.10 && <1.3
+      aeson >=0.7.0.5 && <1.4
+    , base >=4.8 && <5
+    , bytestring
+    , deepseq
+    , hashable
     , microlens >=0.3 && <0.5
-    , bytestring >=0.9 && <0.11
-    , unordered-containers >=0.2.3 && <0.3
-    , vector >=0.9 && <0.13
+    , microlens-aeson
     , tasty >=0.10.1.2
     , tasty-hunit >=0.9.2
-    , microlens-aeson
+    , text >=0.11.1.10 && <1.3
+    , unordered-containers >=0.2.3 && <0.3
+    , vector >=0.9 && <0.13
+  other-modules:
+      Paths_microlens_aeson
+  default-language: Haskell2010
+
+benchmark microlens-aeson-bench
+  type: exitcode-stdio-1.0
+  main-is: Bench.hs
   hs-source-dirs:
-      test
-  main-is: Test.hs
+      bench
+  ghc-options: -fwarn-unused-imports -fwarn-unused-binds -fwarn-name-shadowing -fwarn-unused-matches -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns -threaded -O2
+  build-depends:
+      aeson >=0.7.0.5 && <1.4
+    , base >=4.8 && <5
+    , bytestring
+    , criterion >=1.2 && <1.5
+    , deepseq
+    , hashable
+    , lens >=4.15 && <4.17
+    , lens-aeson >=1.0
+    , microlens >=0.3 && <0.5
+    , microlens-aeson
+    , text >=0.11.1.10 && <1.3
+    , unordered-containers >=0.2.3 && <0.3
+    , vector >=0.9 && <0.13
+  other-modules:
+      Paths_microlens_aeson
   default-language: Haskell2010
-  ghc-options: -threaded
diff --git a/src/Lens/Micro/Aeson.hs b/src/Lens/Micro/Aeson.hs
--- a/src/Lens/Micro/Aeson.hs
+++ b/src/Lens/Micro/Aeson.hs
@@ -1,22 +1,16 @@
-{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
 {-# LANGUAGE DefaultSignatures #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
 
 -- |
 -- Module    :  Lens.Micro.Aeson
--- Copyright :  (c) Colin Woodbury 2015, (c) Edward Kmett 2013-2014, (c) Paul Wilson 2012
+-- Copyright :  (c) Colin Woodbury 2015 - 2018, (c) Edward Kmett 2013-2014, (c) Paul Wilson 2012
 -- License   :  BSD3
 -- Maintainer:  Colin Woodbury <colingw@gmail.com>
 --
 -- Traversals for Data.Aeson, based on microlens for minimal dependencies.
--- 
+--
 -- For basic manipulation of Aeson values, full `Prism` functionality
 -- isn't necessary. Since all Prisms are inherently Traversals, we provide
 -- Traversals that mimic the behaviour of the Prisms found in the original
@@ -39,12 +33,13 @@
   , AsJSON(..)
   ) where
 
+import           Control.DeepSeq (NFData)
 import           Data.Aeson
 import           Data.Attoparsec.ByteString.Lazy (maybeResult, parse)
 import qualified Data.ByteString as Strict
-import           Data.ByteString.Lazy.Char8 as Lazy hiding (putStrLn)
-import           Data.Data
+import           Data.ByteString.Lazy.Char8 as Lazy
 import           Data.HashMap.Strict (HashMap)
+import           Data.Hashable
 import           Data.Scientific (Scientific)
 import qualified Data.Scientific as Scientific
 import           Data.Text as Text
@@ -52,14 +47,10 @@
 import qualified Data.Text.Lazy as LazyText
 import qualified Data.Text.Lazy.Encoding as LazyText
 import           Data.Vector (Vector)
+import           GHC.Generics
 import           Lens.Micro
 import           Lens.Micro.Aeson.Internal ()
-import           Prelude hiding (null)
-
--- $setup
--- >>> import Data.ByteString.Char8 as Strict.Char8
--- >>> import qualified Data.Vector as Vector
--- >>> :set -XOverloadedStrings
+import           Prelude
 
 ------------------------------------------------------------------------------
 -- Scientific Traversals
@@ -142,7 +133,7 @@
   | NumberPrim !Scientific
   | BoolPrim !Bool
   | NullPrim
-  deriving (Eq,Ord,Show,Data,Typeable)
+  deriving (Eq, Ord, Show, Generic, NFData, Hashable)
 
 instance AsNumber Primitive where
   _Number f (NumberPrim n) = NumberPrim <$> f n
@@ -383,7 +374,7 @@
   {-# INLINE _JSON #-}
 
 instance AsJSON Lazy.ByteString where
-  _JSON f b = maybe (pure b) (\v' -> encode <$> f v') v
+  _JSON f b = maybe (pure b) (fmap encode . f) v
     where v = maybeResult (parse json b) >>= \x -> case fromJSON x of
             Success x' -> Just x'
             _ -> Nothing
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -3,9 +3,6 @@
 module Main where
 
 import           Data.Aeson
-import           Data.ByteString.Char8 as Strict.Char8
-import           Data.ByteString.Lazy.Char8 as Lazy
-import qualified Data.Vector as Vector
 import           Lens.Micro
 import           Lens.Micro.Aeson
 import           Test.Tasty
