diff --git a/systemTests/README.md b/systemTests/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..fff65520f5ab3a0aaeb614565311202200652673
--- /dev/null
+++ b/systemTests/README.md
@@ -0,0 +1,32 @@
+# System tests based on NixOS
+
+For the tests, virtual machines are declaratively defined using NixOS.
+They are currently only used to test native notification on XFCE with libnotify installed
+and to manually test the behavior when libnotify is missing on the system.
+
+## How-To
+
+1. Generate the `notificationTest.jar`-file using `./gradlew :briar-desktop:notificationTest`
+2. Install [Nix](https://github.com/NixOS/nix) on your local machine by executing
+`sh <(curl -L https://nixos.org/nix/install) --no-daemon`
+3. Navigate to the `systemTests` folder and execute
+`$(nix-build -A driverInteractive vms.nix)/bin/nixos-test-driver --interactive`
+(this may take some time on the first run, but will be much faster later on)
+4. The interactive Python shell can be used to interact with the virtual machines that are defined in `vms.nix`
+
+### Automatic test of notifications
+
+Run `test_script()` in the interactive Python shell to automatically test working notifications on XFCE with libnotify installed.
+The corresponding virtual machine is called `xfce` and after the test has completed, `notifications.png` will show the desktop with the Briar notifications.
+
+### Manual test with missing libnotify
+
+The virtual machine is called `xfce_without`.
+Briar Desktop can be started from the interactive Python shell as follows,
+after the Compose Jar has been generated with `./gradlew :briar-desktop:packageUberJarForCurrentOS`.
+
+```python
+xfce_without.copy_from_host("../briar-desktop/build/compose/jars/Briar-linux-x64-0.2.1-snapshot.jar", "/tmp/test.jar")
+xfce_without.succeed("su - alice -c 'DISPLAY=:0.0 LD_LIBRARY_PATH=/run/current-system/sw/lib java -jar /tmp/test.jar &'")
+```
+
diff --git a/systemTests/vms.nix b/systemTests/vms.nix
new file mode 100644
index 0000000000000000000000000000000000000000..b6d5bf12d0886af8bf12d8449cd426bcfa5df22d
--- /dev/null
+++ b/systemTests/vms.nix
@@ -0,0 +1,114 @@
+let
+  # Pin nixpkgs, see pinning tutorial for more details
+  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/8b3398bc7587ebb79f93dfeea1b8c574d3c6dba1.tar.gz";
+  pkgs = import nixpkgs {};
+
+  username = "alice";
+
+  makeDesktopEnvironment = { envOptions }: pkgs.lib.recursiveUpdate {
+    virtualisation.qemu.options = [ "-display gtk" ]; # needed to display VM in window
+
+    services.xserver = {
+      enable = true;
+      desktopManager.xterm.enable = false;
+      displayManager = {
+        autoLogin = {
+          enable = true;
+          user = "${username}";
+        };
+      };
+    };
+
+    users = {
+      mutableUsers = false;
+      users = {
+        "${username}" = {
+          isNormalUser = true;
+          description = "Alice Foobar";
+          password = "foobar";
+          uid = 1000;
+        };
+      };
+    };
+
+    environment = {
+      systemPackages = [ pkgs.jdk pkgs.libnotify ];
+      variables."XAUTHORITY" = "/home/alice/.Xauthority";
+    };
+  } envOptions;
+in pkgs.nixosTest {
+  system = "x86_64-linux";
+
+  nodes = {
+    xfce = { ... }: makeDesktopEnvironment {
+      envOptions = {
+        services.xserver = {
+          displayManager.lightdm.enable = true;
+          desktopManager.xfce.enable = true;
+        };
+      };
+    };
+    xfce_without = { ... }: makeDesktopEnvironment {
+      envOptions = {
+        services.xserver = {
+          displayManager.lightdm.enable = true;
+          desktopManager.xfce.enable = true;
+        };
+        environment.systemPackages = [ pkgs.jdk ];
+      };
+    };
+
+    /*
+      Unfortunately, it was not straightforward to run the jar on the following desktop environments.
+      Enlightenment always starts a configuration dialog which somehow needs to be skipped,
+      Gnome and Plasma doesn't show the notifications when run from the test script, but does show them when run from the terminal (Konsole).
+      Additionally, Gnome only started with Wayland which is incompatible with the `wait_for_window()` function in the test script.
+      Therefore these machines are disabled for now.
+
+    enlightenment = { ... }: makeDesktopEnvironment {
+      envOptions = {
+        services.xserver = {
+          displayManager.lightdm.enable = true;
+          desktopManager.enlightenment.enable = true;
+        };
+      };
+    };
+    gnome = { ... }: makeDesktopEnvironment {
+      envOptions = {
+        services.xserver = {
+          displayManager.gdm.enable = true;
+          #displayManager.defaultSession = "gnome-xorg"; # todo: doesn't work with x11...
+          desktopManager.gnome.enable = true;
+        };
+        services.gnome.core-utilities.enable = false; # disable gnome tools
+      };
+    };
+    plasma = { ... }: makeDesktopEnvironment {
+      envOptions = {
+        services.xserver = {
+          displayManager.sddm.enable = true;
+          desktopManager.plasma5.enable = true;
+        };
+      };
+    };
+    */
+  };
+
+  # Disable linting for simpler debugging of the testScript
+  skipLint = true;
+  testScript = { nodes, ... }: let
+  in ''
+    def run(machine):
+      machine.wait_for_x()
+      machine.wait_for_window("xfce4-panel")
+      machine.sleep(20)
+      machine.copy_from_host("../briar-desktop/build/libs/briar-desktop-0.2.1-snapshot-notificationTest.jar", "/tmp/test.jar")
+      machine.succeed("su - alice -c 'DISPLAY=:0.0 LD_LIBRARY_PATH=/run/current-system/sw/lib java -jar /tmp/test.jar &'")
+
+    # test on system with libnotify installed
+    run(xfce)
+    xfce.sleep(1)
+    xfce.screenshot("notifications")
+    xfce.shutdown()
+    '';
+}