diff --git a/README.md b/README.md
index c4568ac..89d6eaa 100644
--- a/README.md
+++ b/README.md
@@ -22,3 +22,111 @@ features made available by `ocaml-lsp-server`. Its aim is to offer a
user experience as close as possible to that offered by the Emacs mode
[Merlin](https://ocaml.github.io/merlin/editor/emacs/).
+## Features
+
+### Browsing errors
+
+Eglot relies on
+[Flymake](https://www.gnu.org/software/emacs/manual/html_node/emacs/Flymake.html)
+for error diagnosis. OCaml-eglot offers two functions for quickly
+navigating through errors:
+
+- `ocaml-eglot-error-next` (C-c C-x): jump to
+ the next error
+- `ocaml-eglot-error-prev` (C-c C-c): jump to
+ the previous error
+
+![Error navigation example](media/error-navigation.gif)
+
+### Jump to definition
+
+Eglot relies on
+[Xref](https://www.gnu.org/software/emacs/manual/html_node/emacs/Xref.html)
+to index cross-references. OCaml-eglot provides a shortcut to quickly
+jump to the definition:
+
+- `ocaml-eglot-locate` (C-c C-l): jump to
+ definition
+
+![Jump to definition example](media/locate.gif)
+
+### Infer Interface
+
+Used to infer the type of an interface file. If the buffer is not
+empty, a prompt will ask for confirmation to overwrite the buffer
+contents:
+
+- `ocaml-eglot-infer-interface`: infer the interface for the current implementation file
+
+![Infer Interface example](media/infer-interface.gif)
+
+### Find Alternate file
+
+OCaml-eglot allows you to quickly switch from the implementation file
+to the interface file and _vice versa_. If the interface file does not
+exist, a prompt can be used to generate it (using type inference,
+based on `ocaml-eglot-infer-inteface`):
+
+- `ocaml-eglot-alternate-file` (C-c C-a): switch
+ from the implementation file to the interface file and _vice versa_
+
+![Find Alternate File example](media/alternate-file.gif)
+
+### Get Documentation
+
+Although the `Hover` primitive in the LSP protocol can be used to
+conveniently display value documentation, it is also possible to query for it
+specifically:
+
+- `ocaml-eglot-document` (C-c C-d): documents
+ the expression below the cursor.
+- `ocaml-eglot-document-identifier`: enables you to enter an
+ identifier (present in the environment) and return its
+ documentation.
+
+![Get Documentation Example](media/document.gif)
+
+### Construct Expression
+
+Enables you to navigate between the different typed-holes (`_`) in a
+document and interactively substitute them:
+
+- `ocaml-eglot-hole-next`: jump to the next hole
+- `ocaml-eglot-hole-prev`: jump to the previous hole
+- `ocaml-eglot-construct`: open up a list of valid substitutions to
+ fill the hole
+
+![Construct Example](media/construct.gif)
+
+If the `ocaml-eglot-construct` command is prefixed by an argument, ie:
+`C-u M-x ocaml-eglot-construct`, the command will also search for
+valid candidates in the current environment:
+
+![Construct with prefix-arg Example](media/construct2.gif)
+
+### Source Browsing
+
+OCaml-eglot allows you to navigate semantically in a buffer, passing
+from an expression to the parent `let`, the parent `module`, the
+parent `fun` and the parent `match` expression. It is also possible to
+navigate between pattern matching cases:
+
+- `ocaml-eglot-jump`: jumps to the referenced expression
+
+![Construct with prefix-arg Example](media/jump.gif)
+
+### Search for values
+
+Search for values using a _by polarity_ query or a type expression. A
+polarity query prefixes the function arguments with `-` and the return
+with `+`. For example, to search for a function of this type: `int ->
+string`. Search for `-int +string`. Searching by polarity does not
+support type parameters. A search by type (modulo isomorphisms) uses a
+query closer to what you would write to describe a type. For example,
+to find the function `int_of_string_opt`, search for `string -> int
+option`:
+
+- `ocaml-eglot-search` searches for a value by its type or polarity
+ (the search type is defined by the input query)
+
+![Search Example](media/search.gif)
diff --git a/media/alternate-file.gif b/media/alternate-file.gif
new file mode 100644
index 0000000..bfbecd6
Binary files /dev/null and b/media/alternate-file.gif differ
diff --git a/media/construct.gif b/media/construct.gif
new file mode 100644
index 0000000..e7683fe
Binary files /dev/null and b/media/construct.gif differ
diff --git a/media/construct2.gif b/media/construct2.gif
new file mode 100644
index 0000000..2672db1
Binary files /dev/null and b/media/construct2.gif differ
diff --git a/media/document.gif b/media/document.gif
new file mode 100644
index 0000000..2e1e001
Binary files /dev/null and b/media/document.gif differ
diff --git a/media/error-navigation.gif b/media/error-navigation.gif
new file mode 100644
index 0000000..0adcd2b
Binary files /dev/null and b/media/error-navigation.gif differ
diff --git a/media/infer-interface.gif b/media/infer-interface.gif
new file mode 100644
index 0000000..68f2800
Binary files /dev/null and b/media/infer-interface.gif differ
diff --git a/media/jump.gif b/media/jump.gif
new file mode 100644
index 0000000..135e347
Binary files /dev/null and b/media/jump.gif differ
diff --git a/media/locate.gif b/media/locate.gif
new file mode 100644
index 0000000..878c9d8
Binary files /dev/null and b/media/locate.gif differ
diff --git a/media/search.gif b/media/search.gif
new file mode 100644
index 0000000..be4244c
Binary files /dev/null and b/media/search.gif differ