diff --git a/Data/Abeson.hs b/Data/Abeson.hs
new file mode 100644
--- /dev/null
+++ b/Data/Abeson.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE LambdaCase #-}
+module Data.Abeson
+    ( AbesonConfig(..)
+    , toAeson, toAesonValue
+    , toBson,  toBsonValue
+    -- * reexport
+    , def
+    ) where
+
+import Data.Default.Class
+import qualified Data.Aeson as A
+import qualified Data.Bson  as B
+
+import qualified Data.ByteString as S
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Base64 as Base64
+
+import qualified Data.Text          as T
+import qualified Data.Text.Lazy     as TL
+import qualified Data.Text.Encoding as T
+import qualified Data.Text.Lazy.Builder as LB
+
+import qualified Data.HashMap.Strict as H
+import qualified Data.Vector as V
+import qualified Data.UUID as UUID
+import Data.Monoid
+import Data.Scientific
+import Data.Int
+import Data.Bits
+import Data.Time.Clock.POSIX
+
+data AbesonConfig = AbesonConfig
+    { binaryEncoding     :: AbesonConfig -> S.ByteString -> A.Value
+    , functionEncoding   :: AbesonConfig -> S.ByteString -> A.Value
+    , userDefEncoding    :: AbesonConfig -> S.ByteString -> A.Value
+    , objectIdEncoding   :: AbesonConfig -> B.ObjectId   -> A.Value
+    , regexEncoding      :: AbesonConfig -> B.Regex      -> A.Value
+    , javascriptEncoding :: AbesonConfig -> B.Javascript -> A.Value
+    , stampEncoding      :: AbesonConfig -> Int64 -> A.Value
+    , minMaxKeyEncoding  :: AbesonConfig -> B.MinMaxKey -> A.Value
+    }
+
+-- | binary, function, userDef -> base64 encoding
+--
+-- objectid -> show
+--
+-- regex -> \/pat\/mod
+--
+-- javascript -> {environment: env, code: code}
+--
+-- stamp -> {t: time_t, i: ordinal}
+--
+-- minkey -> -1, maxkey -> 1
+instance Default AbesonConfig where
+    def = AbesonConfig
+        { binaryEncoding   = const $ A.String . T.decodeUtf8 . Base64.encode
+        , functionEncoding = const $ A.String . T.decodeUtf8 . Base64.encode
+        , userDefEncoding  = const $ A.String . T.decodeUtf8 . Base64.encode
+        , objectIdEncoding = const $ A.String . T.pack . show
+        , regexEncoding    = \_ (B.Regex p m) ->
+            A.String . TL.toStrict . LB.toLazyText $
+            LB.singleton '/' <> LB.fromText p <> LB.singleton '/' <> LB.fromText m
+        , javascriptEncoding = \c (B.Javascript env bdy) ->
+            A.object [ "environment" A..= A.Object (toAeson c env)
+                     , "code"        A..= A.String bdy
+                     ]
+        , stampEncoding = const defaultStampEncode
+        , minMaxKeyEncoding = const $ \case
+            B.MinKey -> A.toJSON (-1 :: Int)
+            B.MaxKey -> A.toJSON ( 1 :: Int)
+        }
+
+defaultStampEncode :: Int64 -> A.Value
+defaultStampEncode i = A.object
+    [ "t" A..= posixSecondsToUTCTime (fromIntegral $ shiftR i 32)
+    , "i" A..= (i .&. 0xffff)
+    ]
+
+toAeson :: AbesonConfig -> B.Document -> A.Object
+toAeson c d = H.fromList $
+    map (\(label B.:= value) -> (label, toAesonValue c value)) d
+
+toAesonValue :: AbesonConfig -> B.Value -> A.Value
+toAesonValue _ (B.Float  b) = A.Number $ fromFloatDigits b
+toAesonValue _ (B.String b) = A.String b
+toAesonValue c (B.Doc    b) = A.Object $ toAeson c b
+toAesonValue c (B.Array  b) = A.Array . V.fromList $ map (toAesonValue c) b
+toAesonValue c (B.Bin (B.Binary   b)) = binaryEncoding   c c b
+toAesonValue c (B.Fun (B.Function b)) = functionEncoding c c b
+toAesonValue _ (B.Uuid (B.UUID b)) = case UUID.fromByteString (L.fromStrict b) of
+    Nothing -> error ""
+    Just ui -> (A.String . T.decodeUtf8 . UUID.toASCIIBytes) ui
+toAesonValue _ (B.Md5 (B.MD5 b)) = A.String $ T.decodeUtf8 b
+toAesonValue c (B.UserDef (B.UserDefined b)) = userDefEncoding c c b
+toAesonValue c (B.ObjId b) = objectIdEncoding c c b
+toAesonValue _ (B.Bool  b) = A.Bool b
+toAesonValue _ (B.UTC   b) = A.toJSON b
+toAesonValue _  B.Null     = A.Null
+toAesonValue c (B.RegEx b) = regexEncoding c c b
+toAesonValue c (B.JavaScr b) = javascriptEncoding c c b
+toAesonValue _ (B.Sym (B.Symbol b)) = A.String b
+toAesonValue _ (B.Int32 b) = A.toJSON b
+toAesonValue _ (B.Int64 b) = A.toJSON b
+toAesonValue c (B.Stamp (B.MongoStamp b)) = stampEncoding c c b
+toAesonValue c (B.MinMax b) = minMaxKeyEncoding c c b
+
+toBson :: A.Object -> B.Document
+toBson = map (\(k,v) -> k B.:= toBsonValue v) . H.toList
+
+toBsonValue :: A.Value -> B.Value
+toBsonValue (A.Object a) = B.Doc $ toBson a
+toBsonValue (A.Array  a) = B.Array $ map toBsonValue (V.toList a)
+toBsonValue (A.String a) = B.String a
+toBsonValue (A.Number a) = case floatingOrInteger a of
+    Left  f -> B.Float f
+    Right i -> B.Int64 i
+toBsonValue (A.Bool a)   = B.Bool a
+toBsonValue  A.Null      = B.Null
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Hirotomo Moriwaki
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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/abeson.cabal b/abeson.cabal
new file mode 100644
--- /dev/null
+++ b/abeson.cabal
@@ -0,0 +1,38 @@
+name:                abeson
+version:             0.1.0
+synopsis:            interconversion between aeson and bson.
+-- description:
+license:             MIT
+license-file:        LICENSE
+author:              HirotomoMoriwaki<philopon.dependence@gmail.com>
+maintainer:          HirotomoMoriwaki<philopon.dependence@gmail.com>
+Homepage:            https://github.com/philopon/abson
+Bug-reports:         https://github.com/philopon/abson/issues
+copyright:           (c) 2014 Hirotomo Moriwaki
+category:            Data
+build-type:          Simple
+stability:           experimental
+-- extra-source-files:
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.Abeson
+  -- other-modules:       
+  build-depends:       base                 >=4.6   && <4.8
+                     , data-default-class   >=0.0   && <0.1
+                     , aeson                >=0.7   && <0.9
+                     , bson                 >=0.3   && <0.4
+                     , bytestring           >=0.10  && <0.11
+                     , base64-bytestring    >=1.0   && <1.1
+                     , text                 >=1.1   && <1.3
+                     , unordered-containers >=0.2   && <0.3
+                     , vector               >=0.10  && <0.11
+                     , uuid                 >=1.3   && <1.4
+                     , scientific           >=0.3   && <0.4
+                     , time                 >=1.4   && <1.5
+  ghc-options:         -O2 -Wall
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: git://github.com/philopon/abson.git
