diff --git a/doc/release-notes/rl-2009.adoc b/doc/release-notes/rl-2009.adoc
index 7740646a9..c1939ab5a 100644
--- a/doc/release-notes/rl-2009.adoc
+++ b/doc/release-notes/rl-2009.adoc
@@ -52,3 +52,46 @@ will automatically include these options, when necessary.
 _module.args.pkgsPath = <nixpkgs>;
 +
 to your Home Manager configuration.
+
+* The options `wayland.windowManager.sway.config.bars` and `opt-xsession.windowManager.i3.config.bars` have been changed so that most of the suboptions are now nullable and default to `null`. The default for these two options has been changed to manually set the old defaults for each suboption. The overall effect is that if the `bars` options is not set, then the default remains the same. On the other hand, something like:
++
+--
+[source,nix]
+----
+bars = [ {
+  command = "waybar";
+} ];
+----
+will now create the config:
+....
+bar {
+  swaybar_command waybar
+}
+....
+instead of
+....
+bar {
+
+  font pango:monospace 8
+  mode dock
+  hidden_state hide
+  position bottom
+  status_command /nix/store/h7s6i9q1z5fxrlyyw5ls8vqxhf5bcs5a-i3status-2.13/bin/i3status
+  swaybar_command waybar
+  workspace_buttons yes
+  strip_workspace_numbers no
+  tray_output primary
+  colors {
+    background #000000
+    statusline #ffffff
+    separator #666666
+    focused_workspace #4c7899 #285577 #ffffff
+    active_workspace #333333 #5f676a #ffffff
+    inactive_workspace #333333 #222222 #888888
+    urgent_workspace #2f343a #900000 #ffffff
+    binding_mode #2f343a #900000 #ffffff
+  }
+
+}
+....
+--
diff --git a/modules/services/window-managers/i3-sway/i3.nix b/modules/services/window-managers/i3-sway/i3.nix
index 540025055..f7124e6fd 100644
--- a/modules/services/window-managers/i3-sway/i3.nix
+++ b/modules/services/window-managers/i3-sway/i3.nix
@@ -7,7 +7,7 @@ let
   cfg = config.xsession.windowManager.i3;
 
   commonOptions = import ./lib/options.nix {
-    inherit lib cfg pkgs;
+    inherit config lib cfg pkgs;
     moduleName = "i3";
     isGaps = cfg.package == pkgs.i3-gaps;
   };
diff --git a/modules/services/window-managers/i3-sway/lib/functions.nix b/modules/services/window-managers/i3-sway/lib/functions.nix
index ea2938e6f..9391e6e92 100644
--- a/modules/services/window-managers/i3-sway/lib/functions.nix
+++ b/modules/services/window-managers/i3-sway/lib/functions.nix
@@ -41,31 +41,66 @@ rec {
 
   barStr = { id, fonts, mode, hiddenState, position, workspaceButtons
     , workspaceNumbers, command, statusCommand, colors, trayOutput, extraConfig
-    , ... }: ''
+    , ... }:
+    let colorsNotNull = lib.filterAttrs (n: v: v != null) colors != { };
+    in ''
       bar {
         ${optionalString (id != null) "id ${id}"}
-        font pango:${concatStringsSep ", " fonts}
-        mode ${mode}
-        hidden_state ${hiddenState}
-        position ${position}
+        ${
+          optionalString (fonts != [ ])
+          "font pango:${concatStringsSep ", " fonts}"
+        }
+        ${optionalString (mode != null) "mode ${mode}"}
+        ${optionalString (hiddenState != null) "hidden_state ${hiddenState}"}
+        ${optionalString (position != null) "position ${position}"}
         ${
           optionalString (statusCommand != null)
           "status_command ${statusCommand}"
         }
         ${moduleName}bar_command ${command}
-        workspace_buttons ${if workspaceButtons then "yes" else "no"}
-        strip_workspace_numbers ${if !workspaceNumbers then "yes" else "no"}
-        tray_output ${trayOutput}
-        colors {
-          background ${colors.background}
-          statusline ${colors.statusline}
-          separator ${colors.separator}
-          focused_workspace ${barColorSetStr colors.focusedWorkspace}
-          active_workspace ${barColorSetStr colors.activeWorkspace}
-          inactive_workspace ${barColorSetStr colors.inactiveWorkspace}
-          urgent_workspace ${barColorSetStr colors.urgentWorkspace}
-          binding_mode ${barColorSetStr colors.bindingMode}
+        ${
+          optionalString (workspaceButtons != null)
+          "workspace_buttons ${if workspaceButtons then "yes" else "no"}"
         }
+        ${
+          optionalString (workspaceNumbers != null)
+          "strip_workspace_numbers ${if !workspaceNumbers then "yes" else "no"}"
+        }
+        ${optionalString (trayOutput != null) "tray_output ${trayOutput}"}
+        ${optionalString colorsNotNull "colors {"}
+          ${
+            optionalString (colors.background != null)
+            "background ${colors.background}"
+          }
+          ${
+            optionalString (colors.statusline != null)
+            "statusline ${colors.statusline}"
+          }
+          ${
+            optionalString (colors.separator != null)
+            "separator ${colors.separator}"
+          }
+          ${
+            optionalString (colors.focusedWorkspace != null)
+            "focused_workspace ${barColorSetStr colors.focusedWorkspace}"
+          }
+          ${
+            optionalString (colors.activeWorkspace != null)
+            "active_workspace ${barColorSetStr colors.activeWorkspace}"
+          }
+          ${
+            optionalString (colors.inactiveWorkspace != null)
+            "inactive_workspace ${barColorSetStr colors.inactiveWorkspace}"
+          }
+          ${
+            optionalString (colors.urgentWorkspace != null)
+            "urgent_workspace ${barColorSetStr colors.urgentWorkspace}"
+          }
+          ${
+            optionalString (colors.bindingMode != null)
+            "binding_mode ${barColorSetStr colors.bindingMode}"
+          }
+        ${optionalString colorsNotNull "}"}
         ${extraConfig}
       }
     '';
diff --git a/modules/services/window-managers/i3-sway/lib/options.nix b/modules/services/window-managers/i3-sway/lib/options.nix
index b5216f8ca..edfdcd4fe 100644
--- a/modules/services/window-managers/i3-sway/lib/options.nix
+++ b/modules/services/window-managers/i3-sway/lib/options.nix
@@ -1,4 +1,5 @@
-{ lib, moduleName, cfg, pkgs, capitalModuleName ? moduleName, isGaps ? true }:
+{ config, lib, moduleName, cfg, pkgs, capitalModuleName ? moduleName
+, isGaps ? true }:
 
 with lib;
 
@@ -49,8 +50,23 @@ let
   };
 
   barModule = types.submodule {
-    options = {
-      inherit fonts;
+    options = let
+      versionAtLeast2009 = versionAtLeast config.home.stateVersion "20.09";
+      mkNullableOption = { type, default, ... }@args:
+        mkOption (args // optionalAttrs versionAtLeast2009 {
+          type = types.nullOr type;
+          default = null;
+          example = default;
+        } // {
+          defaultText = literalExample ''
+            ${
+              if isString default then default else "See code"
+            } for state version < 20.09,
+            null for state version ≥ 20.09
+          '';
+        });
+    in {
+      fonts = fonts // optionalAttrs versionAtLeast2009 { default = [ ]; };
 
       extraConfig = mkOption {
         type = types.lines;
@@ -68,31 +84,31 @@ let
         '';
       };
 
-      mode = mkOption {
+      mode = mkNullableOption {
         type = types.enum [ "dock" "hide" "invisible" ];
         default = "dock";
         description = "Bar visibility mode.";
       };
 
-      hiddenState = mkOption {
+      hiddenState = mkNullableOption {
         type = types.enum [ "hide" "show" ];
         default = "hide";
         description = "The default bar mode when 'bar.mode' == 'hide'.";
       };
 
-      position = mkOption {
+      position = mkNullableOption {
         type = types.enum [ "top" "bottom" ];
         default = "bottom";
         description = "The edge of the screen ${moduleName}bar should show up.";
       };
 
-      workspaceButtons = mkOption {
+      workspaceButtons = mkNullableOption {
         type = types.bool;
         default = true;
         description = "Whether workspace buttons should be shown or not.";
       };
 
-      workspaceNumbers = mkOption {
+      workspaceNumbers = mkNullableOption {
         type = types.bool;
         default = true;
         description =
@@ -112,32 +128,34 @@ let
 
       statusCommand = mkOption {
         type = types.nullOr types.str;
-        default = "${pkgs.i3status}/bin/i3status";
+        default =
+          if versionAtLeast2009 then null else "${pkgs.i3status}/bin/i3status";
+        example = "i3status";
         description = "Command that will be used to get status lines.";
       };
 
       colors = mkOption {
         type = types.submodule {
           options = {
-            background = mkOption {
+            background = mkNullableOption {
               type = types.str;
               default = "#000000";
               description = "Background color of the bar.";
             };
 
-            statusline = mkOption {
+            statusline = mkNullableOption {
               type = types.str;
               default = "#ffffff";
               description = "Text color to be used for the statusline.";
             };
 
-            separator = mkOption {
+            separator = mkNullableOption {
               type = types.str;
               default = "#666666";
               description = "Text color to be used for the separator.";
             };
 
-            focusedWorkspace = mkOption {
+            focusedWorkspace = mkNullableOption {
               type = barColorSetModule;
               default = {
                 border = "#4c7899";
@@ -149,7 +167,7 @@ let
               '';
             };
 
-            activeWorkspace = mkOption {
+            activeWorkspace = mkNullableOption {
               type = barColorSetModule;
               default = {
                 border = "#333333";
@@ -161,7 +179,7 @@ let
               '';
             };
 
-            inactiveWorkspace = mkOption {
+            inactiveWorkspace = mkNullableOption {
               type = barColorSetModule;
               default = {
                 border = "#333333";
@@ -174,7 +192,7 @@ let
               '';
             };
 
-            urgentWorkspace = mkOption {
+            urgentWorkspace = mkNullableOption {
               type = barColorSetModule;
               default = {
                 border = "#2f343a";
@@ -187,7 +205,7 @@ let
               '';
             };
 
-            bindingMode = mkOption {
+            bindingMode = mkNullableOption {
               type = barColorSetModule;
               default = {
                 border = "#2f343a";
@@ -210,7 +228,7 @@ let
         '';
       };
 
-      trayOutput = mkOption {
+      trayOutput = mkNullableOption {
         type = types.str;
         default = "primary";
         description = "Where to output tray.";
@@ -573,7 +591,47 @@ in {
 
   bars = mkOption {
     type = types.listOf barModule;
-    default = [ { } ];
+    default = if versionAtLeast config.home.stateVersion "20.09" then [{
+      mode = "dock";
+      hiddenState = "hide";
+      position = "bottom";
+      workspaceButtons = true;
+      workspaceNumbers = true;
+      statusCommand = "${pkgs.i3status}/bin/i3status";
+      fonts = [ "monospace 8" ];
+      trayOutput = "primary";
+      colors = {
+        background = "#000000";
+        statusline = "#ffffff";
+        separator = "#666666";
+        focusedWorkspace = {
+          border = "#4c7899";
+          background = "#285577";
+          text = "#ffffff";
+        };
+        activeWorkspace = {
+          border = "#333333";
+          background = "#5f676a";
+          text = "#ffffff";
+        };
+        inactiveWorkspace = {
+          border = "#333333";
+          background = "#222222";
+          text = "#888888";
+        };
+        urgentWorkspace = {
+          border = "#2f343a";
+          background = "#900000";
+          text = "#ffffff";
+        };
+        bindingMode = {
+          border = "#2f343a";
+          background = "#900000";
+          text = "#ffffff";
+        };
+      };
+    }] else
+      [ { } ];
     description = ''
       ${capitalModuleName} bars settings blocks. Set to empty list to remove bars completely.
     '';
diff --git a/modules/services/window-managers/i3-sway/sway.nix b/modules/services/window-managers/i3-sway/sway.nix
index 83c8afd6c..8f0ee6081 100644
--- a/modules/services/window-managers/i3-sway/sway.nix
+++ b/modules/services/window-managers/i3-sway/sway.nix
@@ -7,7 +7,7 @@ let
   cfg = config.wayland.windowManager.sway;
 
   commonOptions = import ./lib/options.nix {
-    inherit lib cfg pkgs;
+    inherit config lib cfg pkgs;
     moduleName = "sway";
     capitalModuleName = "Sway";
   };
diff --git a/tests/modules/services/window-managers/sway/default.nix b/tests/modules/services/window-managers/sway/default.nix
index 6b545a26a..b9c0ab5e0 100644
--- a/tests/modules/services/window-managers/sway/default.nix
+++ b/tests/modules/services/window-managers/sway/default.nix
@@ -1,5 +1,6 @@
 {
   sway-default = ./sway-default.nix;
+  sway-post-2003 = ./sway-post-2003.nix;
   sway-followmouse = ./sway-followmouse.nix;
   sway-followmouse-legacy = ./sway-followmouse-legacy.nix;
 }
diff --git a/tests/modules/services/window-managers/sway/sway-post-2003.nix b/tests/modules/services/window-managers/sway/sway-post-2003.nix
new file mode 100644
index 000000000..3eab6538e
--- /dev/null
+++ b/tests/modules/services/window-managers/sway/sway-post-2003.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  config = {
+    home.stateVersion = "20.09";
+
+    wayland.windowManager.sway = {
+      enable = true;
+      package = pkgs.runCommandLocal "dummy-package" { } "mkdir $out" // {
+        outPath = "@sway";
+      };
+      # overriding findutils causes issues
+      config.menu = "${pkgs.dmenu}/bin/dmenu_run";
+    };
+
+    nixpkgs.overlays = [
+      (self: super: {
+        dummy-package = super.runCommandLocal "dummy-package" { } "mkdir $out";
+        dmenu = self.dummy-package // { outPath = "@dmenu@"; };
+        rxvt-unicode-unwrapped = self.dummy-package // {
+          outPath = "@rxvt-unicode-unwrapped@";
+        };
+        i3status = self.dummy-package // { outPath = "@i3status@"; };
+      })
+    ];
+
+    nmt.script = ''
+      assertFileExists home-files/.config/sway/config
+      assertFileContent home-files/.config/sway/config \
+        ${./sway-default.conf}
+    '';
+  };
+}