diff --git a/bin/notify-battery.sh b/bin/notify-battery.sh
new file mode 100755
index 00000000..e6297f4c
--- /dev/null
+++ b/bin/notify-battery.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+set -o nounset
+set -o pipefail
+
+export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
+export DISPLAY=:0
+
+# Battery percentage at which to notify.
+BATTERY_DISCHARGING=$(acpi -b | grep "Battery 0" | grep -c "Discharging")
+BATTERY_LEVEL=$(acpi -b | grep "Battery 0" | grep -P -o '[0-9]+(?=%)')
+WARNING_LEVEL=20
+
+# Use two files to store whether we've shown a notification or not (to prevent multiple notifications).
+EMPTY_FILE=/tmp/battery-empty
+FULL_FILE=/tmp/battery-full
+
+# Reset notifications if the computer is charging/discharging.
+if [ "$BATTERY_DISCHARGING" -eq 1 ] && [ -f $FULL_FILE ]; then
+  rm $FULL_FILE
+elif [ "$BATTERY_DISCHARGING" -eq 0 ] && [ -f $EMPTY_FILE ]; then
+  rm $EMPTY_FILE
+fi
+
+# If the battery is charging and is full (and has not shown notification yet).
+if [ "$BATTERY_LEVEL" -gt 95 ] && [ "$BATTERY_DISCHARGING" -eq 0 ] && [ ! -f $FULL_FILE ]; then
+  notify-send "Battery Charged" "Battery is fully charged." -r 9991
+  touch $FULL_FILE
+# If the battery is low and is not charging (and has not shown notification yet).
+elif [ "$BATTERY_LEVEL" -le $WARNING_LEVEL ] && [ "$BATTERY_DISCHARGING" -eq 1 ] && [ ! -f $EMPTY_FILE ]; then
+  notify-send "Low Battery" "${BATTERY_LEVEL}% of battery remaining." -u critical -r 9991 -t 0
+  touch $EMPTY_FILE
+fi
diff --git a/system/nixos/configuration.nix b/system/nixos/configuration.nix
index 0ee76704..090b50f8 100644
--- a/system/nixos/configuration.nix
+++ b/system/nixos/configuration.nix
@@ -1,4 +1,4 @@
-{ inputs, pkgs, system }:
+{ inputs, desktop ? false, pkgs, system }:
 
 let
   pkgsUnstable = inputs.nixpkgs-unstable.legacyPackages."${system}";
@@ -133,6 +133,10 @@ in
       xfce.thunar
       xfce.thunar-volman
       xfce.tumbler
+    ] ++ pkgs.lib.optionals desktop [
+      acpi
+      dunst
+      libnotify
 
       # Games.
       zeroad
@@ -258,10 +262,13 @@ in
     };
   };
 
-  services.udev.extraRules = ''
-    KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0660", TAG+="uaccess", TAG+="udev-acl", GROUP="realet"
-  '';
+  services.cron = {
+    enable = true;
+
+    systemCronJobs = [
+      "* * * * * opdavies /home/opdavies/.config/bin/notify-battery.sh"
+    ];
+  };
 
   services.auto-cpufreq.enable = true;
 }
-
diff --git a/system/nixos/default.nix b/system/nixos/default.nix
index a7790070..4a4f96ef 100644
--- a/system/nixos/default.nix
+++ b/system/nixos/default.nix
@@ -3,7 +3,7 @@
 { desktop ? false }:
 
 let
-  configuration = import ./configuration.nix { inherit inputs pkgs system; };
+  configuration = import ./configuration.nix { inherit desktop inputs pkgs system; };
   hardware-configuration = import ./hardware-configuration.nix;
 in
 inputs.nixpkgs.lib.nixosSystem {
diff --git a/system/nixos/home-manager/desktop.nix b/system/nixos/home-manager/desktop.nix
index 91bfeb10..6cc8746e 100644
--- a/system/nixos/home-manager/desktop.nix
+++ b/system/nixos/home-manager/desktop.nix
@@ -8,6 +8,16 @@
     ./modules/i3.nix
   ];
 
+  services.dunst = {
+    enable = true;
+
+    settings = {
+      global = {
+        follow = "keyboard";
+      };
+    };
+  };
+
   xdg.configFile.wallpaper = {
     source = ../../../config/wallpaper;
     recursive = true;