diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,126 @@
+# Codec [![Build Status](https://travis-ci.org/chpatrick/codec.svg?branch=master)](https://travis-ci.org/chpatrick/codec) [![Hackage](https://img.shields.io/hackage/v/codec.svg)](http://hackage.haskell.org/package/codec)
+
+Codec makes it simple to write composable bidirectional serializers with a consistent interface.
+
+Just define your data type normally:
+
+```haskell
+data RecordB = RecordB
+  { recordBString :: String
+  , recordBDouble :: Double
+  } deriving (Eq, Ord, Show)
+```
+
+and then associate each field with a codec using the `=.` operator:
+
+```haskell
+recordBObjCodec :: JSONCodec RecordB
+recordBObjCodec = asObject "RecordB" $
+  RecordB
+    <$> recordBString =. field "string"
+    <*> recordBDouble =. field "double"
+```
+
+That's it! If you want, you can now define `ToJSON` and `FromJSON` instances, or just use it directly:
+
+```haskell
+instance ToJSON RecordB where
+  toJSON = toJSONCodec recordBObjCodec
+  toEncoding = toEncodingCodec recordBObjCodec
+
+instance FromJSON RecordB where
+  parseJSON = parseJSONCodec recordBObjCodec
+```
+
+Support can be added for almost any serialization library, but `aeson` and `binary` support is included.
+
+JSON example:
+```haskell
+data RecordA = RecordA
+  { recordAInt :: Int
+  , recordANestedObj :: RecordB
+  , recordANestedArr :: RecordB
+  , recordANestedObjs :: [ RecordB ]
+  } deriving (Eq, Ord, Show)
+
+data RecordB = RecordB
+  { recordBString :: String
+  , recordBDouble :: Double
+  } deriving (Eq, Ord, Show)
+
+recordACodec :: JSONCodec RecordA
+recordACodec = asObject "RecordA" $
+  RecordA
+    <$> recordAInt =. field "int"
+    <*> recordANestedObj =. field' "nestedObj" recordBObjCodec
+    <*> recordANestedArr =. field' "nestedArr" recordBArrCodec
+    <*> recordANestedObjs =. field' "nestedObjs" (arrayOf' id id recordBObjCodec)
+
+recordBObjCodec :: JSONCodec RecordB
+recordBObjCodec = asObject "RecordB" $
+  RecordB
+    <$> recordBString =. field "string"
+    <*> recordBDouble =. field "double"
+
+-- serialize to array elements
+recordBArrCodec :: JSONCodec RecordB
+recordBArrCodec = asArray "RecordB" $
+  RecordB
+    <$> recordBString =. element
+    <*> recordBDouble =. element
+```
+
+Binary example:
+```haskell
+data RecordA = RecordA
+  { recordAInt64 :: Int64
+  , recordAWord8 :: Word8
+  , recordANestedB :: RecordB
+  } deriving (Eq, Ord, Show)
+
+data RecordB = RecordB
+  { recordBWord16 :: Word16
+  , recordBByteString64 :: BS.ByteString
+  } deriving (Eq, Ord, Show)
+
+recordACodec :: BinaryCodec RecordA
+recordACodec =
+  RecordA
+    <$> recordAInt64 =. int64le
+    <*> recordAWord8 =. word8
+    <*> recordANestedB =. recordBCodec
+
+recordBCodec :: BinaryCodec RecordB
+recordBCodec =
+  RecordB
+    <$> recordBWord16 =. word16host
+    <*> recordBByteString64 =. byteString 64
+```
+
+A `Codec` is just a combination of a deserializer `r a`, and a serializer `c -> w a`.
+```haskell
+data CodecFor r w c a = Codec
+  { codecIn :: r a
+  , codecOut :: c -> w a
+  }
+  
+type Codec r w a = CodecFor r w a a
+```
+With `binary` for example, `r` is `Get` and `w` is `PutM`. The reason we have an extra parameter `c` is so that we can associate a `Codec` with a particular field using the `=.` operator:
+
+`(=.) :: (c' -> c) -> CodecFor r w c a -> CodecFor r w c' a`
+
+`Codec` is an instance of `Functor`, `Applicative`, `Monad` and `Profunctor`. You can serialize in any order you like, regardless of field order in the data type:
+
+```haskell
+recordBCodecFlipped :: BinaryCodec RecordB
+recordBCodecFlipped = do
+  bs64 <- recordBByteString64 =. byteString 64
+  RecordB
+    <$> recordBWord16 =. word16host
+    <*> pure bs64
+```
+
+### Contributors
+
+`=.` operator and `Profunctor` approach thanks to [Xia Li-yao](https://github.com/lysxia)
diff --git a/codec.cabal b/codec.cabal
--- a/codec.cabal
+++ b/codec.cabal
@@ -1,9 +1,9 @@
 name:                codec
-version:             0.2
+version:             0.2.1
 license:             BSD3
 license-file:        LICENSE
 synopsis:            Simple bidirectional serialization
-description:         See README.md
+description:         See the README
 author:              Patrick Chilton
 maintainer:          chpatrick@gmail.com
 -- copyright:
@@ -12,6 +12,7 @@
 -- extra-source-files:
 cabal-version:       >=1.10
 homepage:            https://github.com/chpatrick/codec
+extra-source-files:    README.md
 
 source-repository head
   type:                git
