diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Li Meng Jun (c) 2017
+
+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 Li Meng Jun 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/aeson-helper.cabal b/aeson-helper.cabal
new file mode 100644
--- /dev/null
+++ b/aeson-helper.cabal
@@ -0,0 +1,29 @@
+name:                aeson-helper
+version:             0.1.0.0
+synopsis:            Aeson helper func
+description:         Aeson helper func: replace union difference pick
+homepage:            https://github.com/Lupino/yuntan-common/tree/master/aeson-helper#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Li Meng Jun
+maintainer:          lmjubuntu@gmail.com
+copyright:           MIT
+category:            Data,Aeson
+build-type:          Simple
+-- extra-source-files:
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+
+  exposed-modules:     Data.Aeson.Helper
+  build-depends:       base >= 4.7 && < 5
+                     , unordered-containers
+                     , text
+                     , aeson
+                     , vector
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/Lupino/yuntan-common
diff --git a/src/Data/Aeson/Helper.hs b/src/Data/Aeson/Helper.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Aeson/Helper.hs
@@ -0,0 +1,55 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Data.Aeson.Helper
+  ( replace
+  , union
+  , difference
+  , pick
+  ) where
+
+import           Data.Aeson          (Value (..))
+import           Data.Maybe          (catMaybes)
+import           Data.Text           (Text)
+import qualified Data.Text           as T (isPrefixOf, stripPrefix)
+import qualified Data.Vector         as V (map)
+
+import           Data.HashMap.Strict (delete, insert, lookupDefault,
+                                      mapMaybeWithKey)
+import qualified Data.HashMap.Strict as HM (difference, union)
+
+replace :: Text -> Text -> Value -> Value
+replace okey nkey (Object v) = Object . insert nkey ov $ delete okey v
+  where ov = lookupDefault Null okey v
+
+replace _ _ v = v
+
+union :: Value -> Value -> Value
+union (Object a) (Object b) = Object $ HM.union a b
+union (Object a) _          = Object a
+union _ (Object b)          = Object b
+union _ _                   = Null
+
+difference :: Value -> Value -> Value
+difference (Object a) (Object b) = Object $ HM.difference a b
+difference (Object a) _          = Object a
+difference _ _                   = Null
+
+-- key1.key2.key3
+pick :: [Text] -> Value -> Value
+pick [] v          = v
+pick ks (Object a) = Object $ mapMaybeWithKey (doMapMaybeWithKey ks) a
+pick ks (Array a)  = Array $ V.map (pick ks) a
+pick _ _           = Null
+
+doMapMaybeWithKey :: [Text] -> Text -> Value -> Maybe Value
+doMapMaybeWithKey ks k v = go ks
+  where go :: [Text] -> Maybe Value
+        go [] = Nothing
+        go (x:xs)
+          | k == x = Just v
+          | (k <> "." ) `T.isPrefixOf` x = Just $ pick (catMaybes $ nextKeys ks k) v
+          | otherwise = go xs
+
+nextKeys :: [Text] -> Text -> [Maybe Text]
+nextKeys [] _     = []
+nextKeys (x:xs) k = T.stripPrefix (k <> ".") x : nextKeys xs k
