diff --git a/home/adrielus/features/desktop/common/firefox.nix b/home/adrielus/features/desktop/common/firefox.nix
index 1148eef..b2687c0 100644
--- a/home/adrielus/features/desktop/common/firefox.nix
+++ b/home/adrielus/features/desktop/common/firefox.nix
@@ -104,4 +104,11 @@ in
       };
     };
   };
+
+  firefox.apps.asana = {
+    url = "https://app.asana.com/";
+    icon = ./icons/asana.png;
+    displayName = "Asana";
+    id = 1;
+  };
 }
diff --git a/home/adrielus/features/desktop/common/icons/asana.png b/home/adrielus/features/desktop/common/icons/asana.png
new file mode 100644
index 0000000..e47a612
Binary files /dev/null and b/home/adrielus/features/desktop/common/icons/asana.png differ
diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix
index 42bfe95..83e43d5 100644
--- a/modules/home-manager/default.nix
+++ b/modules/home-manager/default.nix
@@ -4,4 +4,5 @@
   # example = import ./example.nix;
   discord = import ./discord.nix;
   fonts = import ./fonts.nix;
+  firefox = import ./firefox;
 }
diff --git a/modules/home-manager/firefox/default.nix b/modules/home-manager/firefox/default.nix
new file mode 100644
index 0000000..89815a4
--- /dev/null
+++ b/modules/home-manager/firefox/default.nix
@@ -0,0 +1,72 @@
+{ lib, pkgs, config, ... }:
+let cfg = config.firefox.apps;
+in
+{
+  options.firefox.apps = lib.mkOption {
+    type = lib.types.attrsOf
+      (lib.types.submodule ({ name, ... }: {
+        options = {
+          name = lib.mkOption {
+            type = lib.types.str;
+            description = "The name of the app";
+            default = name;
+          };
+
+          id = lib.mkOption {
+            type = lib.types.int;
+            description = "The id of the firefox profile for the app";
+            example = 3;
+          };
+
+          displayName = lib.mkOption {
+            type = lib.types.str;
+            description = "The name of the app in stuff like menus";
+            default = name;
+          };
+
+          url = lib.mkOption {
+            type = lib.types.str;
+            description = "The url the app should point to";
+            example = "https://example.com";
+          };
+
+          icon = lib.mkOption {
+            type = lib.types.path;
+            description = "The icon to use for the app";
+          };
+        };
+      }));
+
+    description = "Attr set of firefox web apps to install as desktop apps";
+  };
+
+  config =
+    let
+      mkProfile = app: {
+        settings = {
+          # Customize css
+          "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
+
+          # Set language to english
+          "general.useragent.locale" = "en-GB";
+        };
+
+        userChrome = builtins.readFile ./theme.css;
+
+        isDefault = false;
+        id = app.id;
+      };
+
+      mkDesktopEntry = app: {
+        terminal = false;
+        name = app.displayName;
+        type = "Application";
+        exec = "firefox --name=${app.displayName} --no-remote -P \"${app.name}\" \"${app.url}\"";
+        icon = app.icon;
+      };
+    in
+    {
+      programs.firefox.profiles = lib.mapAttrs (_: mkProfile) cfg;
+      xdg.desktopEntries = lib.mapAttrs (_: mkDesktopEntry) cfg;
+    };
+}
diff --git a/modules/home-manager/firefox/theme.css b/modules/home-manager/firefox/theme.css
new file mode 100644
index 0000000..405bfe1
--- /dev/null
+++ b/modules/home-manager/firefox/theme.css
@@ -0,0 +1,19 @@
+/* This file should hide the firefox ui!  */
+
+TabsToolbar {
+  visibility: collapse;
+}
+
+:root:not([customizing]) #navigator-toolbox:not(:hover):not(:focus-within) {
+  max-height: 1px;
+  min-height: calc(0px);
+  overflow: hidden;
+}
+
+#navigator-toolbox::after {
+  display: none !important;
+}
+
+#main-window[sizemode="maximized"] #content-deck {
+  padding-top: 8px;
+}