diff --git a/nixos/doc/manual/from_md/configuration/bootloader-external.section.xml b/nixos/doc/manual/from_md/configuration/bootloader-external.section.xml
new file mode 100644
index 00000000000..9b7ed6ccdac
--- /dev/null
+++ b/nixos/doc/manual/from_md/configuration/bootloader-external.section.xml
@@ -0,0 +1,41 @@
+
+ External Bootloader Backends
+
+ NixOS has support for several bootloader backends by default:
+ systemd-boot, grub, uboot, etc. The built-in bootloader backend
+ support is generic and supports most use cases. Some users may
+ prefer to create advanced workflows around managing the bootloader
+ and bootable entries.
+
+
+ You can replace the built-in bootloader support with your own
+ tooling using the external bootloader option.
+
+
+ Imagine you have created a new packaged called FooBoot. FooBoot
+ provides a program at
+ ${pkgs.fooboot}/bin/fooboot-install which takes
+ the system closure’s path as its only argument and configures the
+ system’s bootloader.
+
+
+ You can enable FooBoot like this:
+
+
+{ pkgs, ... }: {
+ boot.loader.external = {
+ enable = true;
+ installHook = "${pkgs.fooboot}/bin/fooboot-install";
+ };
+}
+
+
+ Developing Custom Bootloader Backends
+
+ Bootloaders should use
+ RFC-0125’s
+ Bootspec format and synthesis tools to identify the key properties
+ for bootable system generations.
+
+
+
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 24dd30e1575..b2723f8df9a 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1256,6 +1256,7 @@
./system/boot/loader/grub/grub.nix
./system/boot/loader/grub/ipxe.nix
./system/boot/loader/grub/memtest.nix
+ ./system/boot/loader/external/external.nix
./system/boot/loader/init-script/init-script.nix
./system/boot/loader/loader.nix
./system/boot/loader/raspberrypi/raspberrypi.nix
diff --git a/nixos/modules/system/boot/loader/external/external.md b/nixos/modules/system/boot/loader/external/external.md
new file mode 100644
index 00000000000..a53ab55baf5
--- /dev/null
+++ b/nixos/modules/system/boot/loader/external/external.md
@@ -0,0 +1,26 @@
+# External Bootloader Backends {#sec-bootloader-external}
+
+NixOS has support for several bootloader backends by default: systemd-boot, grub, uboot, etc.
+The built-in bootloader backend support is generic and supports most use cases.
+Some users may prefer to create advanced workflows around managing the bootloader and bootable entries.
+
+You can replace the built-in bootloader support with your own tooling using the "external" bootloader option.
+
+Imagine you have created a new packaged called FooBoot.
+FooBoot provides a program at `${pkgs.fooboot}/bin/fooboot-install` which takes the system closure's path as its only argument and configures the system's bootloader.
+
+You can enable FooBoot like this:
+
+```nix
+{ pkgs, ... }: {
+ boot.loader.external = {
+ enable = true;
+ installHook = "${pkgs.fooboot}/bin/fooboot-install";
+ };
+}
+```
+
+## Developing Custom Bootloader Backends
+
+Bootloaders should use [RFC-0125](https://github.com/NixOS/rfcs/pull/125)'s Bootspec format and synthesis tools to identify the key properties for bootable system generations.
+
diff --git a/nixos/modules/system/boot/loader/external/external.nix b/nixos/modules/system/boot/loader/external/external.nix
new file mode 100644
index 00000000000..86f4eaaeba4
--- /dev/null
+++ b/nixos/modules/system/boot/loader/external/external.nix
@@ -0,0 +1,38 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.boot.loader.external;
+in
+{
+ meta = {
+ maintainers = with maintainers; [ cole-h grahamc ];
+ # Don't edit the docbook xml directly, edit the md and generate it:
+ # `pandoc external.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > external.xml`
+ doc = ./external.xml;
+ };
+
+ options.boot.loader.external = {
+ enable = mkEnableOption "use an external tool to install your bootloader";
+
+ installHook = mkOption {
+ type = with types; path;
+ description = ''
+ The full path to a program of your choosing which performs the bootloader installation process.
+
+ The program will be called with an argument pointing to the output of the system's toplevel.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ boot.loader = {
+ grub.enable = mkDefault false;
+ systemd-boot.enable = mkDefault false;
+ supportsInitrdSecrets = false;
+ };
+
+ system.build.installBootLoader = cfg.installHook;
+ };
+}
diff --git a/nixos/modules/system/boot/loader/external/external.xml b/nixos/modules/system/boot/loader/external/external.xml
new file mode 100644
index 00000000000..b024e7dd403
--- /dev/null
+++ b/nixos/modules/system/boot/loader/external/external.xml
@@ -0,0 +1,41 @@
+
+ External Bootloader Backends
+
+ NixOS has support for several bootloader backends by default:
+ systemd-boot, grub, uboot, etc. The built-in bootloader backend
+ support is generic and supports most use cases. Some users may
+ prefer to create advanced workflows around managing the bootloader
+ and bootable entries.
+
+
+ You can replace the built-in bootloader support with your own
+ tooling using the external bootloader option.
+
+
+ Imagine you have created a new packaged called FooBoot. FooBoot
+ provides a program at
+ ${pkgs.fooboot}/bin/fooboot-install which takes
+ the system closure’s path as its only argument and configures the
+ system’s bootloader.
+
+
+ You can enable FooBoot like this:
+
+
+{ pkgs, ... }: {
+ boot.loader.external = {
+ enable = true;
+ installHook = "${pkgs.fooboot}/bin/fooboot-install";
+ };
+}
+
+
+ Developing Custom Bootloader Backends
+
+ Bootloaders should use
+ RFC-0125’s
+ Bootspec format and synthesis tools to identify the key properties
+ for bootable system generations.
+
+
+