diff --git a/nixosModules/ags/v2/.gitignore b/nixosModules/ags/v2/.gitignore
index 701427d2..be93e7dc 100644
--- a/nixosModules/ags/v2/.gitignore
+++ b/nixosModules/ags/v2/.gitignore
@@ -1,3 +1,3 @@
-@girs/
-node_modules/
+@girs
+node_modules
 tsconfig.json
diff --git a/nixosModules/ags/v2/app.ts b/nixosModules/ags/v2/app.ts
index 4dd48642..fc0508dc 100644
--- a/nixosModules/ags/v2/app.ts
+++ b/nixosModules/ags/v2/app.ts
@@ -1,10 +1,14 @@
 import { App } from 'astal';
+
 import style from 'inline:./style.scss';
-import Bar from './widget/Bar';
+
+import Bar from './widgets/bar/main';
+
 
 App.start({
     css: style,
-    main() {
-        Bar(0);
+
+    main: () => {
+        Bar();
     },
 });
diff --git a/nixosModules/ags/v2/default.nix b/nixosModules/ags/v2/default.nix
index ab7b3280..0268b736 100644
--- a/nixosModules/ags/v2/default.nix
+++ b/nixosModules/ags/v2/default.nix
@@ -1,8 +1,15 @@
-self: {pkgs, ...}: {
+self: {
+  lib,
+  pkgs,
+  ...
+}: {
   config = let
+    inherit (lib) attrValues removeAttrs;
+
     inherit (self.inputs) agsV2;
 
     agsV2Packages = agsV2.packages.${pkgs.system};
+    astalLibs = attrValues (removeAttrs agsV2.inputs.astal.packages.${pkgs.system} ["docs"]);
     configDir = "/home/matt/.nix/nixosModules/ags/v2";
   in {
     home = {
@@ -16,27 +23,43 @@ self: {pkgs, ...}: {
         })
       ];
 
-      file = {
-        "${configDir}/tsconfig.json".source = pkgs.writers.writeJSON "tsconfig.json" {
-          "$schema" = "https://json.schemastore.org/tsconfig";
-          "compilerOptions" = {
-            "target" = "ES2023";
-            "module" = "ES2022";
-            "lib" = ["ES2023"];
-            "strict" = true;
-            "moduleResolution" = "Bundler";
-            "skipLibCheck" = true;
-            "checkJs" = true;
-            "allowJs" = true;
-            "jsx" = "react-jsx";
-            "jsxImportSource" = "${agsV2Packages.astal}/share/astal/gjs/src/jsx";
-            "paths" = {
-              "astal" = ["${agsV2Packages.astal}/share/astal/gjs"];
-              "astal/*" = ["${agsV2Packages.astal}/share/astal/gjs/src/*"];
+      file = let
+        inherit
+          (import "${self}/lib" {inherit pkgs self;})
+          buildNodeModules
+          buildNodeTypes
+          ;
+      in (
+        (buildNodeTypes {
+          pname = "agsV2";
+          configPath = "${configDir}/@girs";
+          packages = astalLibs;
+        })
+        // {
+          "${configDir}/node_modules".source =
+            buildNodeModules ./. "sha256-WjCfS8iEw5Mjor/sQ2t+i0Q1pqVpSDEDbbgrKwK+3cg=";
+
+          "${configDir}/tsconfig.json".source = pkgs.writers.writeJSON "tsconfig.json" {
+            "$schema" = "https://json.schemastore.org/tsconfig";
+            "compilerOptions" = {
+              "target" = "ES2023";
+              "module" = "ES2022";
+              "lib" = ["ES2023"];
+              "strict" = true;
+              "moduleResolution" = "Bundler";
+              "skipLibCheck" = true;
+              "checkJs" = true;
+              "allowJs" = true;
+              "jsx" = "react-jsx";
+              "jsxImportSource" = "${agsV2Packages.astal}/share/astal/gjs/src/jsx";
+              "paths" = {
+                "astal" = ["${agsV2Packages.astal}/share/astal/gjs"];
+                "astal/*" = ["${agsV2Packages.astal}/share/astal/gjs/src/*"];
+              };
             };
           };
-        };
-      };
+        }
+      );
     };
   };
 
diff --git a/nixosModules/ags/v2/widget/Bar.tsx b/nixosModules/ags/v2/widget/Bar.tsx
deleted file mode 100644
index 83d93be3..00000000
--- a/nixosModules/ags/v2/widget/Bar.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { App, Variable, Astal, Gtk } from 'astal';
-
-const time = Variable<string>('').poll(1000, 'date');
-
-/**
- * @param monitor the id of the monitor on which we want the widget to appear
- * @returns the bar window
- */
-export default function Bar(monitor: number) {
-    return (
-        <window
-            className="Bar"
-            monitor={monitor}
-            exclusivity={Astal.Exclusivity.EXCLUSIVE}
-            anchor={
-                Astal.WindowAnchor.TOP |
-                Astal.WindowAnchor.LEFT |
-                Astal.WindowAnchor.RIGHT
-            }
-            application={App}
-        >
-            <centerbox>
-                <button
-                    onClicked="echo hello"
-                    halign={Gtk.Align.CENTER}
-                >
-                    Welcome to AGS!
-                </button>
-                <box />
-                <button
-                    onClick={() => print('hello')}
-                    halign={Gtk.Align.CENTER}
-                >
-                    <label label={time()} />
-                </button>
-            </centerbox>
-        </window>
-    );
-}
diff --git a/nixosModules/ags/v2/widgets/bar/main.tsx b/nixosModules/ags/v2/widgets/bar/main.tsx
new file mode 100644
index 00000000..0a950c6d
--- /dev/null
+++ b/nixosModules/ags/v2/widgets/bar/main.tsx
@@ -0,0 +1,30 @@
+import { App, Astal, Gtk, idle, Variable } from 'astal';
+
+
+const isVisible = Variable<boolean>(false);
+
+export default () => {
+    return (
+        <window
+            className="Bar"
+            exclusivity={Astal.Exclusivity.EXCLUSIVE}
+            anchor={
+                Astal.WindowAnchor.TOP |
+                Astal.WindowAnchor.LEFT |
+                Astal.WindowAnchor.RIGHT
+            }
+            application={App}
+            setup={() => idle(() => {
+                isVisible.set(true);
+            })}
+        >
+            <revealer
+                revealChild={isVisible()}
+                transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
+                transitionDuration={500}
+            >
+                <label label="hi" />
+            </revealer>
+        </window>
+    );
+};