diff --git a/README.md b/README.md
index 13b74de..03d2252 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,51 @@
-# kefir-test-utils
+# [≡](#contents) [kefir-test-utils](#kefir-test-utils) · [![npm](https://img.shields.io/npm/dm/kefir-test-utils.svg)](https://www.npmjs.com/package/kefir-test-utils)
-Framework-agnostic testing tool for Kefir.
+Framework-agnostic testing tool for [Kefir](https://kefirjs.github.io/kefir/).
+[![npm version](https://badge.fury.io/js/kefir-test-utils.svg)](http://badge.fury.io/js/kefir-test-utils)
[![Build Status](https://github.com/kefirjs/kefir-test-utils/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/kefirjs/kefir-test-utils/actions?query=workflow%3ACI)
----
+## [≡](#contents) [Contents](#contents)
+
+* [Plugin helpers](#plugin-helpers)
+ * [`activate: (obs: Kefir.Observable) => void`](#activate)
+ * [`deactivate: (obs: Kefir.Observable) => void`](#deactivate)
+ * [`send: (obs: Kefir.Observable, values: Array>) => obs`](#send)
+ * [`value: (value, options: ?{ current }) => Event`](#value)
+ * [`error: (error, options: ?{ current }) => Event`](#error)
+ * [`end: (options: ?{ current }) => Event`](#end)
+ * [`stream: () => Kefir.Stream`](#stream)
+ * [`prop: () => Kefir.Property`](#prop)
+ * [`pool: () => Kefir.Pool`](#pool)
+
+### [≡](#contents) [Plugin helpers](#plugin-helpers)
+
+#### [≡](#contents) [`activate: (obs: Kefir.Observable) => void`](#activate)
+
+`activate` is a simple helper function to turn a stream on.
+
+#### [≡](#contents) [`deactivate: (obs: Kefir.Observable) => void`](#deactivate)
+
+`deactivate` is a simple helper function to turn a stream off. It can turn off streams that were activated with `activate`. Streams turned on through other means (direct call to `on{Value|Error|End|Any}`, use of `observe`, etc.) need to be deactivated through their complementary mechanisms.
+
+#### [≡](#contents) [`send: (obs: Kefir.Observable, values: Array>) => obs`](#send)
+
+`send` is a helper function for emitting values into a given observable. Note that the second parameter is an array of values to emit from the observable. The `Event` is generated by the `value`, `error`, and `end` functions. For all three of these functions, the optional `options` object is not needed.
+
+#### [≡](#contents) [`value: (value, options: ?{ current }) => Event`](#value)
+
+#### [≡](#contents) [`error: (error, options: ?{ current }) => Event`](#error)
+
+#### [≡](#contents) [`end: (options: ?{ current }) => Event`](#end)
+
+`value` and `error` take a value or error and an optional `options` object and return an `Event` object that can be passed to `send`, `emit`, or `emitInTime`. `end` does not take this value, as the `end` event in Kefir does not send a value with it.
+
+When passing to `send`, the `options` object is ignored. `options` is used by `emit` and `emitInTime` (both described below) to determine whether the event should be treated as a `Kefir.Property`'s current event, error, or end.
+
+#### [≡](#contents) [`stream: () => Kefir.Stream`](#stream)
+
+#### [≡](#contents) [`prop: () => Kefir.Property`](#prop)
+
+#### [≡](#contents) [`pool: () => Kefir.Pool`](#pool)
+
+`stream`, `prop`, and `pool` are helper functions to create empty streams, properties, and pools. These can be used as mock sources to send values into. They have no other behavior.