diff --git a/docs/design-concept/events.md b/docs/design-concept/events.md
new file mode 100644
index 0000000000000000000000000000000000000000..da02fac8e5b72934e4df7c6706b6722527630a93
--- /dev/null
+++ b/docs/design-concept/events.md
@@ -0,0 +1,4 @@
+---
+title: Events
+---
+
diff --git a/docs/design-concept/intro.md b/docs/design-concept/intro.md
new file mode 100644
index 0000000000000000000000000000000000000000..3c5a41b71da29d5bb4dccf70233d902b73ccc5a8
--- /dev/null
+++ b/docs/design-concept/intro.md
@@ -0,0 +1,24 @@
+---
+title: Design Concept
+---
+
+Mongoose is a multi-protocol networking library that implements non-blocking,
+asyncronous IO and provides event-based API. It has three basic data structures:
+
+- [`struct mg_mgr`](#TODO) is an event manager that holds all active
+  connections
+- [`struct mg_connection`](#TODO) describes a connection
+- [`struct mbuf`](#TODO) describes data buffer (received or sent data)
+
+Connections could be either *listening*, *outbound* or *inbound*.  Outbound
+connections are created by [`mg_connect()`](#TODO) call.  Listening connections
+are created by [`mg_bind()`](#TODO) call.  Inbound connections are those
+accepted by a listening connection.  Each connection is described by [`struct
+mg_connection`](#TODO) structure, which has a number of fields like socket,
+event handler function, send/receive buffer, flags, et cetera.
+
+Mongoose usage pattern is to declare and initialize event manager, create
+connections and create an event loop by calling [`mg_mgr_poll()`](#TODO) in a
+loop.  [`mg_mgr_poll()`](#TODO) iterates over all sockets, accepts new
+connections, sends and receives data, closes connections, and calls event
+handler functions for the respective events.
diff --git a/docs/design-concept/items.json b/docs/design-concept/items.json
new file mode 100644
index 0000000000000000000000000000000000000000..50ffece2e3e178c073b90597eddb2e46419b75a0
--- /dev/null
+++ b/docs/design-concept/items.json
@@ -0,0 +1,6 @@
+{
+  "items": [
+    { "type": "markdown", "name": "intro.md" },
+    { "type": "markdown", "name": "memory-buffers.md" }
+  ]
+}
diff --git a/docs/design-concept/memory-buffers.md b/docs/design-concept/memory-buffers.md
new file mode 100644
index 0000000000000000000000000000000000000000..6cb41548ea43c614cb107b69e098f8b9b3844afd
--- /dev/null
+++ b/docs/design-concept/memory-buffers.md
@@ -0,0 +1,20 @@
+---
+title: Memory buffers
+---
+
+Each connection has send and receive buffer,
+[`struct mg_connection::send_mbuf`](#TODO)
+and
+[`struct mg_connection::recv_mbuf`](#ODO) respectively.
+When data arrives,
+Mongoose appends received data to the `recv_mbuf` and
+triggers `MG_EV_RECV` event. User may send data back by calling one of the
+output functions, like [`mg_send()`](#TODO) or
+[`mg_printf()`](#TODO). Output functions append data to the
+`send_mbuf`. When Mongoose
+successfully writes data to the socket, it discards data from
+[`mg_connection::send_mbuf`](#TODO) and
+sends `MG_EV_SEND` event. When connection is closed, `MG_EV_CLOSE` event is sent.
+
+![](../../static/img/mongoose/mbuf.png)
+
diff --git a/docs/img/mbuf.png b/docs/img/mbuf.png
new file mode 100644
index 0000000000000000000000000000000000000000..a162abc3d6ce0df95ad9fa725cc54337b1ceb64f
Binary files /dev/null and b/docs/img/mbuf.png differ
diff --git a/docs/items.json b/docs/items.json
new file mode 100644
index 0000000000000000000000000000000000000000..d3394c8bb868df706fc5a37b17d72ce09392a7be
--- /dev/null
+++ b/docs/items.json
@@ -0,0 +1,6 @@
+{
+  "items": [
+    { "type": "section", "name": "usage-example" },
+    { "type": "section", "name": "design-concept" }
+  ]
+}
diff --git a/docs/usage-example/intro.md b/docs/usage-example/intro.md
new file mode 100644
index 0000000000000000000000000000000000000000..410e0657ab39f4d1591285961b0d60ead21c6874
--- /dev/null
+++ b/docs/usage-example/intro.md
@@ -0,0 +1,44 @@
+---
+title: Usage Example
+---
+
+- Copy `mongoose.c` and `mongoose.h` to your build tree
+- Write code that uses Mongoose API, e.g. in `my_app.c`
+- Compile application: `$ cc my_app.c mongoose.c`
+
+```c
+#include "mongoose.h"  // Include Mongoose API definitions
+
+// Define an event handler function
+static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
+  struct mbuf *io = &nc->recv_mbuf;
+
+  switch (ev) {
+    case MG_EV_RECV:
+      // This event handler implements simple TCP echo server
+      mg_send(nc, io->buf, io->len);  // Echo received data back
+      mbuf_remove(io, io->len);      // Discard data from recv buffer
+      break;
+    default:
+      break;
+  }
+}
+
+int main(void) {
+  struct mg_mgr mgr;
+
+  mg_mgr_init(&mgr, NULL);  // Initialize event manager object
+
+  // Note that many connections can be added to a single event manager
+  // Connections can be created at any point, e.g. in event handler function
+  mg_bind(&mgr, "1234", ev_handler);  // Create listening connection and add it to the event manager
+
+  for (;;) {  // Start infinite event loop
+    mg_mgr_poll(&mgr, 1000);
+  }
+
+  mg_mgr_free(&mgr);
+  return 0;
+}
+```
+
diff --git a/docs/usage-example/items.json b/docs/usage-example/items.json
new file mode 100644
index 0000000000000000000000000000000000000000..bc7e70d8d0e561c3c4545aeb1aa07f6688f31bce
--- /dev/null
+++ b/docs/usage-example/items.json
@@ -0,0 +1,5 @@
+{
+  "items": [
+    { "type": "markdown", "name": "intro.md" }
+  ]
+}