diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,24 @@
+0.3.0.2
+-------
+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.2>
+
+*   Lowered bounds on *text* dependency.
+*   Added `CHANGELOG.md` and `README.md` to extra source dependecy fields, to
+    count them in the cabal package.
+
+0.3.0.1
+-------
+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.1>
+
+*   Fixed the "other-modules" cabal file field to include non-exported but
+    important modules.
+
+0.3.0.0
+-------
+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.0>
+
+*   First official release.  API more or less stabilized.  Library is more or
+    less stable, but there are still some extra aspects of the javascript
+    websockets API to hook onto for more power/information, and some
+    javascript errors to be handled on edge cases.
+
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,144 @@
+ghcjs-websockets
+================
+
+*ghcjs-websockets* aims to provide a clean, idiomatic, efficient, low-level,
+out-of-your-way, bare bones, concurrency-aware interface with minimal
+abstractions over the [Javascript Websockets API][jsapi], inspired by common
+Haskell idioms found in libraries like [io-stream][] and the server-side
+[websockets][] library, targeting compilation to Javascript with `ghcjs`.
+
+The interface abstracts websockets as simple IO/file handles, with additional
+access to the natively "typed" (text vs binary) nature of the Javascript
+Websockets API.  There are also convenience functions to directly decode
+serialized data (serialized with [binary][]) sent through channels.
+
+The library is mostly intended to be a low-level FFI library, with the hopes
+that other, more advanced libraries maybe build on the low-level FFI bindings
+in order to provide more advanced and powerful abstractions.  Most design
+decisions were made with the intent of keeping things as simple as possible in
+order for future libraries to abstract over it.
+
+Most of the necessary functionality is in hopefully in
+`JavaScript.WebSockets`; more of the low-level API is exposed in
+`JavaScript.WebSockets.Internal` if you need it for library construction.
+
+Documenation is [online on github pages][documentation].
+
+[jsapi]: http://www.w3.org/TR/websockets/
+[io-stream]: http://hackage.haskell.org/package/io-streams
+[websockets]: http://hackage.haskell.org/package/websockets
+[binary]: http://hackage.haskell.org/package/binary
+[documentation]: http://mstksg.github.io/ghcjs-websockets/JavaScript-WebSockets.html
+
+Usage
+-----
+
+```haskell
+import Data.Text (unpack)
+
+-- A simple echo client, echoing all incoming text data
+main :: IO ()
+main = withUrl "ws://my-server.com" $ \conn ->
+    forever $ do
+        t <- receiveText conn
+        putStrLn (unpack t)
+        sendText conn t
+```
+
+The above code will attempt to interpret all incoming data as UTF8-encoded
+Text, and throw away data that does not.
+
+`conn` is a `Connection`, which encapsulates a websocket channel.
+
+You can also do the same thing to interpret all incoming data as any instance
+of `Binary` --- say, `Int`s:
+
+```haskell
+-- A simple client waiting for connections and outputting the running sum
+main :: IO ()
+main = withUrl "ws://my-server.com" (runningSum 0)
+
+runningSum :: Int -> Connection -> IO ()
+runningSum n conn = do
+    i <- receiveData conn
+    print (n + i)
+    runningSum (n + i) conn
+```
+
+`receiveData` will block until the `Connection` receives data that is
+decodable as whatever type you expect, and will throw away all nondecodable
+data (including `Text` data).
+
+The `receive` function is provided as an over-indulgent layer of abstraction
+where you can receive both `Text` and instances of `Binary` with the same
+function using typeclass magic --- for the examples above, you could use
+`receive` in place of both `receiveText` and `receiveData`.
+
+`send` works the same way for `sendText` and `sendData`.
+
+If you want to, you can access the incoming data directly using the
+`SocketMsg` sum type, which exposes either a `Text` or a lazy `ByteString`:
+
+```haskell
+import Data.Text (unpack, append)
+import qualified Data.ByteString.Base64.Lazy as B64
+
+main :: IO ()
+main = withUrl "ws://my-server.com" $ \conn ->
+    forever $ do
+        msg <- receiveMessage
+        putStrLn $ case msg of
+            SocketMsgText t ->
+                unpack $ append "Received text: " t
+            SocketMsgData d ->
+                "Received data: " ++ show (B64.encode d)
+```
+
+You can talk to multiple connections by nesting `withUrl`:
+
+```haskell
+-- Act as a relay between two servers
+main :: IO ()
+main =  withUrl "ws://server-1.com" $ \conn1 ->
+        withUrl "ws://server-2.com" $ \conn2 ->
+            forever $ do
+                msg <- receiveMessage conn1
+                sendMessage conn2 msg
+```
+
+And also alternatively, you can manually open and close connections:
+
+```haskell
+-- Act as a relay between two servers
+main :: IO ()
+main = do
+    conn1 <- openConnection "ws://server-1.com"
+    conn2 <- openConnection "ws://server-2.com"
+    forever $ do
+        msg <- receiveMessage conn1
+        sendMessage conn2 msg
+    closeConnection conn2
+    closeConnection conn1
+```
+
+`receiveMessage` and its varieties will all throw an exception if the
+connection closes while they're waiting or if you attempt to receive on a
+closed connection.  You can handle these with mechanisms from
+`Control.Exception`, or you can use their "maybe"-family counterparts,
+`receiveMessageMaybe`, etc., who will return results in `Just` on a success,
+or return a `Nothing` if the connection is closed or if receiving on a closed
+connection.
+
+You can use also `connectionClosed :: Connection -> IO Bool` to check if the
+given `Connection` object is closed (or `connectionCloseReason` to see *why*).
+
+When closing connections, there might be some messages that were received by
+the socket but never processed on the Haskell side with a `receive` method.
+These will normally be deleted; however, you can use
+`closeConnectionLeftovers` or `withUrlLeftovers` to grab a list of the raw
+`SocketMsg`s remaining after closing.
+
+### Copyright
+
+Copyright (c) Justin Le 2015
+
diff --git a/ghcjs-websockets.cabal b/ghcjs-websockets.cabal
--- a/ghcjs-websockets.cabal
+++ b/ghcjs-websockets.cabal
@@ -1,5 +1,5 @@
 name:                ghcjs-websockets
-version:             0.3.0.1
+version:             0.3.0.2
 synopsis:            GHCJS interface for the Javascript Websocket API
 description:
                      Documentation online at
@@ -82,7 +82,8 @@
 copyright:           Copyright (c) Justin Le 2015
 category:            Web
 build-type:          Simple
--- extra-source-files:  
+extra-source-files:  CHANGELOG.md
+                   , README.md
 cabal-version:       >=1.10
 
 source-repository head
@@ -95,13 +96,13 @@
   -- ghcjs-options: -O2
   other-modules:       JavaScript.Blob
                      , JavaScript.WebSockets.FFI
-  -- other-extensions:    
+  -- other-extensions:
   ghc-options:         -Wall
   build-depends:       base              >= 4.7      && < 5
                      , base64-bytestring >= 1
                      , binary            >= 0.7
                      , bytestring        >= 0.10
                      , ghcjs-base        >= 0.1
-                     , text              >= 1.2
+                     , text              >= 1
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/JavaScript/Blob.hs b/src/JavaScript/Blob.hs
--- a/src/JavaScript/Blob.hs
+++ b/src/JavaScript/Blob.hs
@@ -32,6 +32,3 @@
 
 isBlob :: JSRef a -> IO Bool
 isBlob ref = ffi_blobCheck ref
-
-
-
diff --git a/src/JavaScript/WebSockets.hs b/src/JavaScript/WebSockets.hs
--- a/src/JavaScript/WebSockets.hs
+++ b/src/JavaScript/WebSockets.hs
@@ -438,4 +438,3 @@
 -- | Returns the origin url of the given 'Connection'.
 connectionOrigin :: Connection -> Text
 connectionOrigin = _connOrigin
-
diff --git a/src/JavaScript/WebSockets/Internal.hs b/src/JavaScript/WebSockets/Internal.hs
--- a/src/JavaScript/WebSockets/Internal.hs
+++ b/src/JavaScript/WebSockets/Internal.hs
@@ -395,4 +395,3 @@
       else do
         let blob = unsafeCoerce msg :: JSString
         return . Just . SocketMsgText . fromJSString $ blob
-
