diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Changelog for aeson-with
+
+## v0.0.1.0
+
+* Dirty aeson-with lenses for quickly adding fields to objects.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Author name here (c) 2020
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# aeson-with
+
+Silly little `withXField` combinators for adding fields to an existing JSON value.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/aeson-with.cabal b/aeson-with.cabal
new file mode 100644
--- /dev/null
+++ b/aeson-with.cabal
@@ -0,0 +1,41 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.33.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 60d1cd77eef3980b26cefd6eb07c1b9e0ff54dcfa96838bfd6666cab0e858f6a
+
+name:           aeson-with
+version:        0.0.1.0
+synopsis:       withXField combinators for aeson
+description:    Silly little withXField combinators for adding fields to an existing JSON value.
+category:       Data
+author:         Daniel Firth
+maintainer:     dan.firth@homotopic.tech
+copyright:      2020 Daniel Firth
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+library
+  exposed-modules:
+      Data.Aeson.With
+  other-modules:
+      Paths_aeson_with
+  hs-source-dirs:
+      src
+  build-depends:
+      aeson
+    , base >=4.7 && <5
+    , hashmap
+    , lens
+    , lens-aeson
+    , scientific
+    , text
+    , unordered-containers
+    , vector
+  default-language: Haskell2010
diff --git a/src/Data/Aeson/With.hs b/src/Data/Aeson/With.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aeson/With.hs
@@ -0,0 +1,58 @@
+{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
+module Data.Aeson.With (
+  withJSON
+, withValue
+, withValueMaybe
+, withStringField
+, withArrayField
+, withObjectField
+, withNumberField
+, withBoolField
+, withNullField
+)where
+
+import           Control.Lens
+import           Data.Aeson      as A
+import           Data.Aeson.Lens
+import qualified Data.HashMap.Lazy     as HML
+import           Data.Scientific
+import           Data.Text
+import qualified Data.Vector      as V
+
+-- | Union two JSON values together.
+withJSON :: (ToJSON a) => a -> Value -> Value
+withJSON x (Object obj) = Object $ HML.union obj y
+  where Object y = toJSON x
+withJSON _ _ =  error "Can ony add a new TOJSON object to objects"
+
+-- | Add  Null field to a JSON value.
+withNullField :: Text -> Value -> Value
+withNullField f = _Object . at f ?~ Null
+
+-- | Add a String field to a JSON value.
+withStringField :: Text -> Text -> Value -> Value
+withStringField f v =  _Object  . at f ?~ String v
+
+-- | Add an Array field to a JSON value.
+withArrayField :: Text -> [Value] -> Value -> Value
+withArrayField f v = _Object . at f ?~ Array (V.fromList v)
+
+-- | Add an Value field to a JSON value.
+withValue :: Text -> Value -> Value -> Value
+withValue f v = _Object . at f ?~ v
+
+-- | Maybe add a Value to a JSON object.
+withValueMaybe :: Text -> Maybe Value -> Value -> Value
+withValueMaybe f v = _Object . at f .~ v
+
+-- | Add an Number field to a JSON value.
+withNumberField :: Text -> Scientific -> Value -> Value
+withNumberField f v = _Object . at f ?~ Number v
+
+-- | Add a Bool field to a JSON value.
+withBoolField :: Text -> Bool -> Value -> Value
+withBoolField f v = _Object . at f ?~ Bool v
+
+-- | Add an Object field to a JSON value.
+withObjectField :: Text -> Object -> Value -> Value
+withObjectField f v = _Object . at f ?~ Object v
