diff --git a/Data/Aeson/Transform.hs b/Data/Aeson/Transform.hs
--- a/Data/Aeson/Transform.hs
+++ b/Data/Aeson/Transform.hs
@@ -19,35 +19,43 @@
 -- output at various nodes in the tree.
 --
 data Builder =
-    Id
-  | At Text Builder
-  | Attr Text
-  | Attrs [Text]
-  | Map Builder
-  | Index Int Builder
-  | Obj (H.HashMap Text Builder)
+    Id                  -- ^ Pass input directly as output
+  | At Text Builder     -- ^ Move to value in current object
+  | Attr Text           -- ^ Get value in current object
+  | Keep [Text]         -- ^ Filter current object by keys
+  | Map Builder         -- ^ Map over input array
+  | Index Int           -- ^ Get value at index of current array
+  | AtIndex Int Builder -- ^ Move to index in current array
+  | Obj (H.HashMap Text Builder) -- ^ Produce object with given keys
+  | Merge Builder Builder  -- ^ Combine two objects
 
+
 -- | Generates new Aeson 'Value' guided by a 'Builder'
 --
-transform :: Builder -> Value -> Value
-transform (At k b)    (A.Object o) = transform b $ o H.! k
-transform (At _ _)    _            = error "Expecting object (At)"
-transform (Index i b) (Array a)    = transform b $ a Vec.! i
-transform (Index _ _) _            = error "Expecting array (Index)"
-transform (Map b)     (Array a)    = Array $ Vec.map (transform b) a
-transform (Map _)     _            = error "Expecting array (Map)"
-transform (Attr k)    (A.Object o) = o H.! k
-transform (Attr _)    _            = error "Expecting object (Attr)"
-transform (Attrs ks)  (A.Object o) = A.Object $ H.filterWithKey (const . (`elem` ks)) o
-transform (Attrs _)   _            = error "Expecting object (Attrs)"
-transform (Obj fs)    x            = A.Object $ H.map (`transform` x) fs
-transform Id          x            = x
+transform :: Builder -> Value       -> Value
+transform Id            x            = x
+transform (At k b)      (A.Object o) = transform b $ o H.! k
+transform (At _ _)      _            = error "Expecting object (At)"
+transform (AtIndex i b) (Array a)    = transform b $ a Vec.! i
+transform (AtIndex _ _) _            = error "Expecting array (AtIndex)"
+transform (Index i)     (Array a)    = a Vec.! i
+transform (Index _)     _            = error "Expecting array (Index)"
+transform (Map b)       (Array a)    = Array $ Vec.map (transform b) a
+transform (Map _)       _            = error "Expecting array (Map)"
+transform (Attr k)      (A.Object o) = o H.! k
+transform (Attr _)      _            = error "Expecting object (Keep)"
+transform (Keep ks)     (A.Object o) = A.Object $ H.filterWithKey (const . (`elem` ks)) o
+transform (Keep _)      _            = error "Expecting object (Keep)"
+transform (Obj fs)      x            = A.Object $ H.map (`transform` x) fs
+transform (Merge a b)   x            = case (transform a x, transform b x) of
+                                       (Object c, Object d) -> Object $ H.union c d
+                                       _ -> error "Expected two objects (Merge)"
 
 -- $use
 --
 -- Filter unwanted attributes from an object
 --
--- > Attrs ["nice", "good"]
+-- > Keep ["nice", "good"]
 -- >
 -- > -- { bad: 3, good: 1, nice: 500, evil: -3 }
 -- > -- => { good: 1, nice: 500 }
@@ -72,15 +80,29 @@
 --
 -- Extract indices
 --
--- > Map $ Index 0 Id
+-- > Map $ Index 0
 -- >
 -- > -- [[1,2], [3,4]] => [1, 3]
 --
 -- Create object
 --
 -- > Obj $ fromList [
--- >     ("first", Index 0 Id)
--- >   , ("second", Index 1 Id)
+-- >     ("first", Index 0)
+-- >   , ("second", Index 1)
 -- >   ]
 -- >
 -- > -- ["hi", "bye"] => { first:"hi", second:"bye" }
+--
+-- Transform position
+--
+-- > At "ranks" $ AtIndex 0 $ Attr "name"
+-- >
+-- > -- {ranks: [ { name:"winner", score:12 }, { name:"Loser", score: 3 ]}
+-- > -- => "winner"
+--
+-- Combine objects
+--
+-- > Merge (Attr "foo") (Attr "bar")
+-- >
+-- > -- { foo: { a:1, b:2 }, bar: { b:3, c:4 } }
+-- > -- => { a:1, b:2, c:4 }
diff --git a/aeson-t.cabal b/aeson-t.cabal
--- a/aeson-t.cabal
+++ b/aeson-t.cabal
@@ -1,13 +1,14 @@
 Name:                   aeson-t
-Version:                0.0.0
+Version:                0.0.2
 Author:                 Joe Nelson <cred+github@begriffs.com>
 Maintainer:             Joe Nelson <cred+github@begriffs.com>
 Category:               Data
 License:                MIT
 License-File:           LICENSE
 Synopsis:               Transform JSON
+Homepage:               https://github.com/begriffs/aeson-t
 Description:
-  Provides a DSL to succinctly transform one JSON document to another.
+  Provides a succinct DSL to transform one JSON document to another.
 Cabal-Version:          >= 1.10
 Build-Type:             Simple
 
@@ -17,11 +18,11 @@
   Exposed-Modules:      Data.Aeson.Transform
   Other-Modules:        Data.Aeson.Transform.Internal
   Build-Depends:        base >= 4 && < 5
-                      , aeson
-                      , unordered-containers
-                      , text
-                      , bytestring
-                      , vector
+                      , aeson == 0.8.*
+                      , unordered-containers == 0.2.*
+                      , text == 1.1.*
+                      , bytestring == 0.10.*
+                      , vector == 0.10.*
 
 Test-Suite spec
   Type:                 exitcode-stdio-1.0
@@ -32,11 +33,11 @@
   Build-Depends:        base
                       , aeson-t
                       , hspec2
-                      , aeson
-                      , unordered-containers
-                      , text
-                      , bytestring
-                      , vector
+                      , aeson == 0.8.*
+                      , unordered-containers == 0.2.*
+                      , text == 1.1.*
+                      , bytestring == 0.10.*
+                      , vector == 0.10.*
                       , aeson-qq
 
 Source-Repository head
