diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,16 +1,21 @@
 # Changelog
 
+### v0.4.0
+
+Update dependencies, in particular, aeson v2.
+
+
 ### v0.3.11
 
-- Add CHANGELOG and README to the stack tarball
+Add CHANGELOG and README to the stack tarball.
 
 ### v0.3.10
 
-- Added missing test files to the stack tarball
+Added missing test files to the stack tarball.
 
 ### v0.3.9
 
-- Adjusted version ranges for test dependencies
+Adjusted version ranges for test dependencies.
 
 ### v0.3.8
 
@@ -52,6 +57,7 @@
 - Added `listRelative` and it's flipped relative
 - Updated dependencies
 
+
 ### v0.2.1
 
 - Fix order of the `list` function parameters
@@ -61,6 +67,7 @@
 - Split up `Utilities` to internal and non-internal
 - Add more `Utilities` (sequence utils, metadata helpers, etc.)
 - Clean up code
+
 
 ### v0.1.3
 
diff --git a/shikensu.cabal b/shikensu.cabal
--- a/shikensu.cabal
+++ b/shikensu.cabal
@@ -1,11 +1,11 @@
--- This file has been generated from package.yaml by hpack version 0.28.2.
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.34.4.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 3e5fa4dbe1f3a9d4a9e68e3ec0daa63d1370d25cba8d17b46dbb270d7d970cb7
 
 name:           shikensu
-version:        0.3.11
+version:        0.4.0
 synopsis:       Run a sequence of functions on in-memory representations of files
 description:    See README at <https://github.com/icidasset/shikensu#readme>
 category:       Filesystem
@@ -15,7 +15,6 @@
 license:        MIT
 license-file:   LICENSE
 build-type:     Simple
-cabal-version:  >= 1.10
 extra-source-files:
     CHANGELOG.md
     README.md
@@ -26,19 +25,6 @@
   location: https://github.com/icidasset/shikensu
 
 library
-  hs-source-dirs:
-      src
-  default-extensions: DisambiguateRecordFields DuplicateRecordFields OverloadedStrings
-  build-depends:
-      Glob >=0.7 && <1
-    , aeson ==1.*
-    , base >=4.9 && <5
-    , bytestring ==0.10.*
-    , directory ==1.*
-    , filepath ==1.*
-    , flow ==1.*
-    , text ==1.*
-    , unordered-containers ==0.2.*
   exposed-modules:
       Shikensu
       Shikensu.Contrib
@@ -50,27 +36,25 @@
       Shikensu.Utilities
   other-modules:
       Paths_shikensu
-  default-language: Haskell2010
-
-test-suite spec
-  type: exitcode-stdio-1.0
-  main-is: Test.hs
   hs-source-dirs:
-      tests
       src
-  default-extensions: DisambiguateRecordFields DuplicateRecordFields OverloadedStrings
+  default-extensions:
+      DisambiguateRecordFields DuplicateRecordFields OverloadedStrings
   build-depends:
       Glob >=0.7 && <1
-    , aeson ==1.*
+    , aeson ==2.*
     , base >=4.9 && <5
-    , bytestring ==0.10.*
+    , bytestring >=0.10 && <0.12
     , directory ==1.*
     , filepath ==1.*
     , flow ==1.*
-    , tasty ==1.*
-    , tasty-hunit ==0.*
     , text ==1.*
     , unordered-containers ==0.2.*
+  default-language: Haskell2010
+
+test-suite spec
+  type: exitcode-stdio-1.0
+  main-is: Test.hs
   other-modules:
       Test.Contrib
       Test.Example
@@ -86,4 +70,21 @@
       Shikensu.Sorting
       Shikensu.Utilities
       Paths_shikensu
+  hs-source-dirs:
+      tests
+      src
+  default-extensions:
+      DisambiguateRecordFields DuplicateRecordFields OverloadedStrings
+  build-depends:
+      Glob >=0.7 && <1
+    , aeson ==2.*
+    , base >=4.9 && <5
+    , bytestring >=0.10 && <0.12
+    , directory ==1.*
+    , filepath ==1.*
+    , flow ==1.*
+    , tasty ==1.*
+    , tasty-hunit ==0.*
+    , text ==1.*
+    , unordered-containers ==0.2.*
   default-language: Haskell2010
diff --git a/src/Shikensu.hs b/src/Shikensu.hs
--- a/src/Shikensu.hs
+++ b/src/Shikensu.hs
@@ -20,7 +20,7 @@
 import Shikensu.Internal.Utilities
 import System.FilePath
 
-import qualified Data.HashMap.Strict as HashMap (empty)
+import qualified Data.Aeson.KeyMap as KeyMap (empty)
 import qualified Data.List as List (concatMap, map, zip)
 import qualified System.Directory as Dir (canonicalizePath)
 import qualified System.FilePath.Glob as Glob (compile, globDir1)
@@ -115,7 +115,7 @@
 >     , workingDirname = "example"
 >
 >     , content = Nothing
->     , metadata = HashMap.empty
+>     , metadata = KeyMap.empty
 >     , parentPath = "../"
 >     , pathToRoot = "../../"
 >     }
@@ -140,7 +140,7 @@
 
             -- Additional properties
             , content         = Nothing
-            , metadata        = HashMap.empty
+            , metadata        = KeyMap.empty
             , parentPath      = compileParentPath $ takeDirName theLocalPath
             , pathToRoot      = compilePathToRoot $ takeDirName theLocalPath
             }
diff --git a/src/Shikensu/Contrib.hs b/src/Shikensu/Contrib.hs
--- a/src/Shikensu/Contrib.hs
+++ b/src/Shikensu/Contrib.hs
@@ -36,7 +36,7 @@
 import Shikensu.Metadata (transposeToMetadata)
 import System.FilePath (FilePath, combine)
 
-import qualified Data.HashMap.Strict as HashMap (empty, union)
+import qualified Data.Aeson.KeyMap as KeyMap (empty, union)
 
 
 {-| Clear metadata.
@@ -50,7 +50,7 @@
 
 clearMetadataDef :: Definition -> Definition
 clearMetadataDef def =
-    def { metadata = HashMap.empty }
+    def { metadata = KeyMap.empty }
 
 
 
@@ -87,7 +87,7 @@
 copyPropsToMetadataDef :: Definition -> Definition
 copyPropsToMetadataDef def =
     def
-        { metadata = HashMap.union (transposeToMetadata def) (metadata def) }
+        { metadata = KeyMap.union (transposeToMetadata def) (metadata def) }
 
 
 
@@ -112,7 +112,7 @@
 
 insertMetadataDef :: Metadata -> Definition -> Definition
 insertMetadataDef given def =
-    def { metadata = HashMap.union given (metadata def) }
+    def { metadata = KeyMap.union given (metadata def) }
 
 
 
diff --git a/src/Shikensu/Internal/Types.hs b/src/Shikensu/Internal/Types.hs
--- a/src/Shikensu/Internal/Types.hs
+++ b/src/Shikensu/Internal/Types.hs
@@ -5,11 +5,12 @@
 module Shikensu.Internal.Types where
 
 import Data.Aeson ((.=), toJSON)
+import Data.Aeson.KeyMap (KeyMap)
 import Data.ByteString (ByteString)
 import Data.Monoid ((<>))
 import System.FilePath (joinPath)
 
-import qualified Data.Aeson as Aeson (Object, ToJSON, object)
+import qualified Data.Aeson as Aeson (ToJSON, Value, object)
 
 
 {-| A file definition, along with some additional properties.
@@ -49,7 +50,7 @@
 
 
 type Dictionary = [Definition]
-type Metadata = Aeson.Object
+type Metadata = KeyMap Aeson.Value
 
 
 
diff --git a/src/Shikensu/Metadata.hs b/src/Shikensu/Metadata.hs
--- a/src/Shikensu/Metadata.hs
+++ b/src/Shikensu/Metadata.hs
@@ -10,7 +10,7 @@
 import Shikensu.Internal.Types
 
 import qualified Data.Aeson as Aeson (FromJSON, Result(..), ToJSON, fromJSON, toJSON)
-import qualified Data.HashMap.Strict as HashMap (empty)
+import qualified Data.Aeson.KeyMap as KeyMap (empty, fromList)
 
 
 {-| Transpose metadata.
@@ -22,15 +22,15 @@
 >     Example { some :: Text }
 >     deriving (Generic, FromJSON)
 >
-> hashMap     = HashMap.fromList [ ("some", "metadata") ]
+> keyMap      = KeyMap.fromList [ ("some", "metadata") ]
 > defaultEx   = Example { some = "default" }
-> example     = transposeMetadata hashMap defaultEx :: Example
+> example     = transposeMetadata keyMap defaultEx :: Example
 
 -}
 transposeMetadata :: Aeson.FromJSON a => Metadata -> a -> a
-transposeMetadata hashMap fallback =
+transposeMetadata keyMap fallback =
     let
-        result = hashMap
+        result = keyMap
             |> Aeson.toJSON
             |> Aeson.fromJSON :: Aeson.FromJSON b => Aeson.Result b
     in
@@ -50,4 +50,4 @@
     in
         case result of
             Aeson.Success x -> x
-            Aeson.Error _   -> HashMap.empty
+            Aeson.Error _   -> KeyMap.empty
diff --git a/src/Shikensu/Utilities.hs b/src/Shikensu/Utilities.hs
--- a/src/Shikensu/Utilities.hs
+++ b/src/Shikensu/Utilities.hs
@@ -14,7 +14,8 @@
 import Shikensu.Internal.Types
 
 import qualified Data.Aeson as Json (Object, Result(..), encode)
-import qualified Data.HashMap.Strict as HashMap (lookup)
+import qualified Data.Aeson.KeyMap as KeyMap (lookup)
+import qualified Data.Aeson.Key as Key (fromText)
 import qualified Data.List as List (unzip, zip)
 import qualified Data.Text as Text (unpack)
 import qualified Data.Text.Lazy as Lazy.Text (unpack)
@@ -72,7 +73,8 @@
 -}
 (~>) :: (FromJSON a, ToJSON a) => Metadata -> Text -> Maybe a
 (~>) obj key =
-    HashMap.lookup key obj
+    obj
+        |> KeyMap.lookup (Key.fromText key)
         |> fmap fromJSON
         |> fmap fromJSONResult
 
diff --git a/tests/Test/Contrib.hs b/tests/Test/Contrib.hs
--- a/tests/Test/Contrib.hs
+++ b/tests/Test/Contrib.hs
@@ -11,9 +11,10 @@
 import Test.Tasty.HUnit
 
 import qualified Data.Aeson.Types as Aeson (Value(..))
+import qualified Data.Aeson.Key as Key (fromText)
 import qualified Data.ByteString as B (empty)
 import qualified Data.ByteString.Char8 as BS (intercalate, pack)
-import qualified Data.HashMap.Strict as HashMap (fromList, lookup)
+import qualified Data.Aeson.KeyMap as KeyMap (fromList, lookup)
 import qualified Data.List as List (head, reverse)
 import qualified Data.Text as Text (pack, unpack)
 import qualified Data.Text.Encoding as Text (decodeUtf8, encodeUtf8)
@@ -100,16 +101,16 @@
 testMetadata :: TestTree
 testMetadata =
     let
-        keyA        = Text.pack "title"
+        keyA        = Key.fromText (Text.pack "title")
         valueA      = Aeson.String (Text.pack "Hello world!")
 
-        keyB        = Text.pack "hello"
+        keyB        = Key.fromText (Text.pack "hello")
         valueB      = Aeson.String (Text.pack "Guardian.")
 
-        keyC        = Text.pack "removed"
+        keyC        = Key.fromText (Text.pack "removed")
         valueC      = Aeson.String (Text.pack "Me.")
 
-        keyBase     = Text.pack "basename"
+        keyBase     = Key.fromText (Text.pack "basename")
         valueBase   = Aeson.String (Text.pack "example")
 
         -- 1. Insert C
@@ -117,19 +118,19 @@
         -- 3. Insert B
         dictionary = fmap
             ( id
-                .> Contrib.insertMetadata   (HashMap.fromList [ (keyC, valueC) ])
-                .> Contrib.replaceMetadata  (HashMap.fromList [ (keyA, valueA) ])
+                .> Contrib.insertMetadata   (KeyMap.fromList [ (keyC, valueC) ])
+                .> Contrib.replaceMetadata  (KeyMap.fromList [ (keyA, valueA) ])
                 .> Contrib.copyPropsToMetadata
-                .> Contrib.insertMetadata   (HashMap.fromList [ (keyB, valueB) ])
+                .> Contrib.insertMetadata   (KeyMap.fromList [ (keyB, valueB) ])
             )
             example_md
 
         definition          = fmap (List.reverse .> List.head) dictionary
 
-        lookupTitle     def = HashMap.lookup keyA (Shikensu.metadata def)
-        lookupHello     def = HashMap.lookup keyB (Shikensu.metadata def)
-        lookupRemoved   def = HashMap.lookup keyC (Shikensu.metadata def)
-        lookupBasename  def = HashMap.lookup keyBase (Shikensu.metadata def)
+        lookupTitle     def = KeyMap.lookup keyA (Shikensu.metadata def)
+        lookupHello     def = KeyMap.lookup keyB (Shikensu.metadata def)
+        lookupRemoved   def = KeyMap.lookup keyC (Shikensu.metadata def)
+        lookupBasename  def = KeyMap.lookup keyBase (Shikensu.metadata def)
     in
         testGroup
             "Metadata"
diff --git a/tests/Test/Utilities.hs b/tests/Test/Utilities.hs
--- a/tests/Test/Utilities.hs
+++ b/tests/Test/Utilities.hs
@@ -10,7 +10,7 @@
 import Test.Tasty
 import Test.Tasty.HUnit
 
-import qualified Data.HashMap.Strict as HashMap (singleton)
+import qualified Data.Aeson.KeyMap as KeyMap (singleton)
 import qualified Data.List as List (head)
 import qualified Data.Tuple as Tuple (fst)
 import qualified Shikensu.Contrib as Contrib
@@ -54,7 +54,7 @@
         definition =
             "."
                 |> define thePattern
-                |> fmap (Contrib.insertMetadataDef $ HashMap.singleton "a" "Hi!")
+                |> fmap (Contrib.insertMetadataDef $ KeyMap.singleton "a" "Hi!")
 
         resultExisting =
             fmap (\d -> metadata d ~> "a" :: Maybe String) definition
