diff --git a/doc/README.md b/doc/README.md
index 6860672a4d6b88d4ff19ace902725d1c8a1025eb..7b781413398320a7f4ff3f8b91927f95d0bf146a 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -6,22 +6,27 @@ It does not however contain API documentation, which is built separately in this
 ### Requirements
 
 The code is documented with [Doxygen][doxygen] JavaDoc style, a prettified documentation
-also requires [breathe][breathe] and [Sphinx][sphinx] for building sane documentation pages.
+also requires [breathe][breathe], [Sphinx][sphinx] and [Sphinx tabs][sphinx-tabs] for building sane documentation pages.
 It is not however required.
 
 [doxygen]:https://www.stack.nl/~dimitri/doxygen/manual/index.html
 [breathe]: https://github.com/michaeljones/breathe
 [sphinx]: http://sphinx-doc.org/
+[sphinx-tabs]: https://sphinx-tabs.readthedocs.io/
 
 You can get the extra dependencies with pip:
 
 ```sh
-pip install -U Sphinx breathe
+pip install -U Sphinx sphinx-tabs breathe
 # Alternatively
 pip -r doc/requirements.txt
 ```
 
 ### Building documentation
 
-If you satisfy the requirements, it's as easy as `make doc`, which builds the documentation in this folder.
+If you satisfy the requirements, it's as easy as `make doc`, which builds the documentation in this folder `doc/html`.
 
+```sh
+$ meson build_dir -Ddoc=enabled
+$ ninja -C build_dir doc
+```
diff --git a/doc/conf.py b/doc/conf.py
index 05e0d8de9fd220f1249aeb547df03f23ddd3438e..27bce230c38bde46b42b80f45ac99679b8f59442 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -13,7 +13,12 @@ if os.environ.get('READTHEDOCS', None) == 'True':
     subprocess.call('doxygen')
 
 # Add any Sphinx extension module names here, as strings.
-extensions = ['sphinx.ext.todo', 'sphinx.ext.viewcode', 'breathe']
+extensions = [
+    'sphinx.ext.todo',
+    'sphinx.ext.viewcode',
+    'sphinx_tabs.tabs',
+    'breathe'
+]
 
 # Breathe configuration
 breathe_projects = {"libkres": "doxyxml"}
diff --git a/doc/meson.build b/doc/meson.build
index 72a8a7b03cb003685b90e7d22cc27539619b02aa..16f7da130dcba4e1f7bad628ed82ce4255458645 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -39,7 +39,11 @@ if get_option('doc') == 'enabled'
     else
       python_sphinx_rtd_theme = run_command('python2', '-c', 'import sphinx_rtd_theme', check: false)
       if python_sphinx_rtd_theme.returncode() != 0
-	error('missing doc dependency: python sphinx_rtd_theme')
+	      error('missing doc dependency: python sphinx_rtd_theme')
+      endif
+      python_sphinx_tabs = run_command('python2', '-c', 'import sphinx_tabs', check: false)
+      if python_sphinx_tabs.returncode() != 0
+        error('missing doc dependency: python python-sphinx-tabs')
       endif
     endif
   else
@@ -47,6 +51,10 @@ if get_option('doc') == 'enabled'
     if python_sphinx_rtd_theme.returncode() != 0
       error('missing doc dependency: python sphinx_rtd_theme')
     endif
+    python_sphinx_tabs = run_command('python3', '-c', 'import sphinx_tabs', check: false)
+    if python_sphinx_tabs.returncode() != 0
+      error('missing doc dependency: python python-sphinx-tabs')
+    endif
   endif
   message('------------------------')
 
diff --git a/doc/quickstart-config.rst b/doc/quickstart-config.rst
index df0fed4e067e20b857e3aadd5d2f8ab7f26a1b32..c5a31e0c88c1e08e95f7bbe43565d970e953c08c 100644
--- a/doc/quickstart-config.rst
+++ b/doc/quickstart-config.rst
@@ -30,16 +30,34 @@ Detailed configuration of daemon and implemented modules can be found in configu
 Listening on network interfaces
 ===============================
 
-Network interfaces to listen on and supported protocols are configured using :func:`net.listen()` function.
-
 The following configuration instructs Knot Resolver to receive standard unencrypted DNS queries on IP addresses `192.0.2.1` and `2001:db8::1`. Encrypted DNS queries are accepted using DNS-over-TLS protocol on all IP addresses configured on network interface `eth0`, TCP port 853.
 
-.. code-block:: lua
 
-    -- unencrypted DNS on port 53 is default
-    net.listen('192.0.2.1')
-    net.listen('2001:db8::1')
-    net.listen(net.eth0, 853, { kind = 'tls' })
+.. tabs::
+
+    .. tab:: yaml
+
+        .. code-block:: yaml
+
+            network:
+                listen:
+                  - interface: ['192.0.2.1', '2001:db8::1'] # unencrypted DNS on port 53 is default
+                  - interface: 'eth0'
+                    port: 853
+                    kind: 'dot'
+
+
+    .. tab:: lua legacy
+
+        Network interfaces to listen on and supported protocols are configured using :func:`net.listen()` function.
+
+        .. code-block:: lua
+
+            -- unencrypted DNS on port 53 is default
+            net.listen('192.0.2.1')
+            net.listen('2001:db8::1')
+            net.listen(net.eth0, 853, { kind = 'tls' })
+
 
 .. warning::
 
diff --git a/doc/requirements.txt b/doc/requirements.txt
index 3da3c237ccf93c26198a5f3d83c45bef7a832abc..bc396166dc5db27420f1532c1dd3b4db9137ad2b 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,2 +1,3 @@
 Sphinx>=3.0.0
+sphinx-tabs
 breathe