diff --git a/README.md b/README.md
index c9c06e0de..6745d40fb 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,148 @@
-# swift-nio-http-client
+# SwiftNIOHTTPClient
+This package provides simple HTTP Client library built on top of SwiftNIO.
-Swift HTTP Client library built on top of SwiftNIO
+This library provides the following:
+1. Asynchronous and non-blocking request methods
+2. Simple follow-redirects (cookie headers are dropped)
+3. Streaming body download
+4. TLS support
+5. Cookie parsing (but not storage)
+
+---
+
+**NOTE**: You will need [Xcode 10.2](https://itunes.apple.com/us/app/xcode/id497799835) or [Swift 5.0](https://swift.org/download/#swift-50) to try out `SwiftNIOHTTPClient`.
+
+---
+
+## Getting Started
+
+#### Adding the dependency
+Add the following entry in your Package.swift
to start using HTTPClient
:
+
+```swift
+// it's early days here so we haven't tagged a version yet, but will soon
+.package(url: "https://github.com/swift-server/swift-nio-http-client.git", .branch("master"))
+```
+and ```SwiftNIOHTTP``` dependency to your target:
+```swift
+.target(name: "MyApp", dependencies: ["NIOHTTPClient"]),
+```
+
+#### Request-Response API
+The code snippet below illustrates how to make a simple GET request to a remote server:
+
+```swift
+import HTTPClient
+
+let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+httpClient.get(url: "https://swift.org").whenComplete { result in
+ switch result {
+ case .failure(let error):
+ // process error
+ case .success(let response):
+ if let response.status == .ok {
+ // handle response
+ } else {
+ // handle remote error
+ }
+ }
+}
+```
+
+It is important to close client instance after use to cleanly shutdown underlying NIO ```EventLoopGroup```:
+```
+try? httpClient.syncShutdown()
+```
+Alternatively, you can provide shared ```EventLoopGroup```:
+```swift
+let httpClient = HTTPClient(eventLoopGroupProvider: .shared(userProvidedGroup))
+```
+In this case shutdown of the client is not neccecary.
+
+## Usage guide
+
+Most common HTTP methods are supported out of the box. In case you need to have more control over the method, or you want to add headers or body, use ```HTTPRequest``` struct:
+```swift
+import HTTPClient
+
+let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+defer {
+ try? httpClient.syncShutdown()
+}
+
+var request = try HTTPRequest(url: "https://swift.org", method: .POST)
+request.headers.add(name: "User-Agent", value: "Swift HTTPClient")
+request.body = .string("some-body")
+
+httpClient.execute(request: request).whenComplete { result in
+ switch result {
+ case .failure(let error):
+ // process error
+ case .success(let response):
+ if let response.status == .ok {
+ // handle response
+ } else {
+ // handle remote error
+ }
+ }
+}
+```
+
+### Redirects following
+Enable follow-redirects behavior using the client configuration:
+```swift
+let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
+ configuration: HTTPClientConfiguration(followRedirects: true))
+```
+
+### Timeouts
+Timeouts (connect and read) can also be set using the client configuration:
+```swift
+let timeout = Timeout(connectTimeout: .seconds(1), readTimeout: .seconds(1))
+let httpClient = HTTPClient(eventLoopGroupProvider: .createNew,
+ configuration: HTTPClientConfiguration(timeout: timeout))
+```
+or on per-request basis:
+```swift
+let timeout = Timeout(connectTimeout: .seconds(1), readTimeout: .seconds(1))
+httpClient.execute(request: request, timeout: timeout)
+```
+
+### Streaming
+When dealing with larger amount of data, it's critical to stream the response body instead of aggregating in-memory. Handling a response stream is done using a delegate protocol. The following example demonstrates how to count the number of bytes in a streaming response body:
+```swift
+class CountingDelegate: HTTPResponseDelegate {
+ typealias Response = Int
+
+ var count = 0
+
+ func didTransmitRequestBody() {
+ // this is executed when request is sent, called once
+ }
+
+ func didReceiveHead(_ head: HTTPResponseHead) {
+ // this is executed when we receive HTTP Reponse head part of the request (it contains response code and headers), called once
+ }
+
+ func didReceivePart(_ buffer: ByteBuffer) {
+ // this is executed when we receive parts of the response body, could be called zero or more times
+ count += buffer.readableBytes
+ }
+
+ func didFinishRequest() throws -> Int {
+ // this is called when request is fully read, called once, this is where you return a result or throw any errors you require to propagate to the client
+ return count
+ }
+
+ func didReceiveError(_ error: Error) {
+ // this is called when we receive any network-related error, called once
+ }
+}
+
+let request = try HTTPRequest(url: "https://swift.org")
+let delegate = CountingDelegate()
+
+try httpClient.execute(request: request, delegate: delegate).future.whenSuccess { count in
+ print(count)
+}
+```