diff --git a/client-tauri/package.json b/client-tauri/package.json
index 52322bec2..869ab4021 100644
--- a/client-tauri/package.json
+++ b/client-tauri/package.json
@@ -36,6 +36,7 @@
     "@vitejs/plugin-react": "^4.0.3",
     "typescript": "^5.0.2",
     "vite": "^4.4.4",
+    "vite-plugin-compile-time": "^0.2.1",
     "vite-plugin-dynamic-import": "^1.5.0"
   }
 }
diff --git a/client-tauri/src/components/fields/BuildFields.tsx b/client-tauri/src/components/fields/BuildFields.tsx
new file mode 100644
index 000000000..6e259dc8c
--- /dev/null
+++ b/client-tauri/src/components/fields/BuildFields.tsx
@@ -0,0 +1,15 @@
+import Joi from "@stirling-tools/joi";
+
+
+interface BuildFieldsProps {
+    /** The text to display inside the button */
+    schemaDescription: Joi.Description | undefined;
+}
+  
+
+export function BuildFields({ schemaDescription }: BuildFieldsProps) {
+    console.log("Render Build Fields", schemaDescription);
+    return (
+      <div>Description: {(schemaDescription?.flags as any)?.description}</div>
+    );
+}
\ No newline at end of file
diff --git a/client-tauri/src/components/fields/StringField.tsx b/client-tauri/src/components/fields/StringField.tsx
new file mode 100644
index 000000000..532092dbc
--- /dev/null
+++ b/client-tauri/src/components/fields/StringField.tsx
@@ -0,0 +1,12 @@
+interface StringFieldProps {
+    /** The text to display inside the button */
+    validValues: string[];
+    exampleValues: string;
+}
+  
+
+export function StringField({ validValues, exampleValues }: StringFieldProps) {
+    return (
+      <button>{validValues}</button>
+    );
+}
\ No newline at end of file
diff --git a/client-tauri/src/pages/Dynamic.tsx b/client-tauri/src/pages/Dynamic.tsx
index cff9f9678..bca30de1c 100644
--- a/client-tauri/src/pages/Dynamic.tsx
+++ b/client-tauri/src/pages/Dynamic.tsx
@@ -1,15 +1,23 @@
 import { Link } from "react-router-dom";
 
-import { BaseSyntheticEvent } from "react";
+import { BaseSyntheticEvent, createContext, useState } from "react";
 import { Operator } from "@stirling-pdf/shared-operations/src/functions";
 import i18next from "i18next";
+import Joi from "@stirling-tools/joi";
+import { BuildFields } from "../components/fields/BuildFields";
 
 function Dynamic() {
+    const [schemaDescription, setSchemaDescription] = useState<Joi.Description>();
+
+
     const operators = ["impose"]; // TODO: Make this dynamic
 
     function selectionChanged(s: BaseSyntheticEvent) {
         const selectedValue = s.target.value;
-        if(selectedValue == "none") return;
+        if(selectedValue == "none") {
+            setSchemaDescription(undefined);
+            return;
+        }
 
         i18next.loadNamespaces("impose", (err, t) => {
             if (err) throw err;
@@ -19,8 +27,8 @@ function Dynamic() {
                 const Operator = Module[capitalizeFirstLetter(selectedValue)];
                 const description = Operator.schema.describe();
 
+                setSchemaDescription(description); // This will update children
                 console.log(description);
-                // TODO: use description to generate fields
             });
         });
     }
@@ -35,21 +43,19 @@ function Dynamic() {
 
             <input type="file" id="pdfFile" accept=".pdf" multiple />
             <br />
-
-            <br />
-            <textarea name="workflow" id="workflow"></textarea>
-            <br />
             <select id="pdfOptions" onChange={selectionChanged}>
                 <option value="none">none</option>
                 { operators.map((operator, i) => {
                     return (<option value={operator}>{operator}</option>)
                 }) }
             </select>
-            <button id="loadButton">Load</button>
-            <br />
+
+            <div id="values">
+                <BuildFields schemaDescription={schemaDescription}></BuildFields>
+            </div>
 
             <br />
-            <button id="doneButton">Done</button>
+            <button id="processButton">Process process file with current settings</button>
 
             <p>
                 <Link to="/">Go back home...</Link>
diff --git a/client-tauri/vite.config.ts b/client-tauri/vite.config.ts
index 8b7accce2..596922d5c 100644
--- a/client-tauri/vite.config.ts
+++ b/client-tauri/vite.config.ts
@@ -2,6 +2,8 @@ import { defineConfig } from "vite";
 import react from "@vitejs/plugin-react";
 import topLevelAwait from "vite-plugin-top-level-await";
 import dynamicImport from 'vite-plugin-dynamic-import'
+import compileTime from "vite-plugin-compile-time"
+
 
 // https://vitejs.dev/config/
 export default defineConfig(async () => ({
@@ -13,6 +15,7 @@ export default defineConfig(async () => ({
             // The function to generate import names of top-level await promise in each chunk module
             promiseImportName: i => `__tla_${i}`
         }),
+        compileTime(),
         dynamicImport(),
     ],
 
diff --git a/package-lock.json b/package-lock.json
index d9a76f888..65aab4b7d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -50,6 +50,7 @@
         "@vitejs/plugin-react": "^4.0.3",
         "typescript": "^5.0.2",
         "vite": "^4.4.4",
+        "vite-plugin-compile-time": "^0.2.1",
         "vite-plugin-dynamic-import": "^1.5.0"
       }
     },
@@ -474,6 +475,21 @@
         "@jridgewell/sourcemap-codec": "^1.4.10"
       }
     },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
+      "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
+      "cpu": [
+        "ppc64"
+      ],
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/@esbuild/android-arm": {
       "version": "0.18.20",
       "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -790,9 +806,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.19.11",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz",
-      "integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==",
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
+      "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
       "cpu": [
         "x64"
       ],
@@ -1550,6 +1566,30 @@
         }
       }
     },
+    "node_modules/@rollup/plugin-dynamic-import-vars": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/@rollup/plugin-dynamic-import-vars/-/plugin-dynamic-import-vars-2.1.2.tgz",
+      "integrity": "sha512-4lr2oXxs9hcxtGGaK8s0i9evfjzDrAs7ngw28TqruWKTEm0+U4Eljb+F6HXGYdFv8xRojQlrQwV7M/yxeh3yzQ==",
+      "dev": true,
+      "dependencies": {
+        "@rollup/pluginutils": "^5.0.1",
+        "astring": "^1.8.5",
+        "estree-walker": "^2.0.2",
+        "fast-glob": "^3.2.12",
+        "magic-string": "^0.30.3"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@rollup/plugin-inject": {
       "version": "5.0.5",
       "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz",
@@ -2910,7 +2950,6 @@
       "version": "8.11.3",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
       "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
-      "dev": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -3118,6 +3157,15 @@
         "util": "^0.12.5"
       }
     },
+    "node_modules/astring": {
+      "version": "1.8.6",
+      "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz",
+      "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==",
+      "dev": true,
+      "bin": {
+        "astring": "bin/astring"
+      }
+    },
     "node_modules/async": {
       "version": "3.2.5",
       "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
@@ -3438,6 +3486,20 @@
       "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
       "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ=="
     },
+    "node_modules/bundle-require": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.2.tgz",
+      "integrity": "sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==",
+      "dependencies": {
+        "load-tsconfig": "^0.2.3"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "esbuild": ">=0.17"
+      }
+    },
     "node_modules/busboy": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -4233,6 +4295,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/devalue": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz",
+      "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg=="
+    },
     "node_modules/diff": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -4370,8 +4437,7 @@
     "node_modules/es-module-lexer": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
-      "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
-      "dev": true
+      "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w=="
     },
     "node_modules/esbuild": {
       "version": "0.18.20",
@@ -6098,6 +6164,14 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/load-tsconfig": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
+      "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      }
+    },
     "node_modules/locate-path": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -8970,11 +9044,376 @@
         }
       }
     },
+    "node_modules/vite-plugin-compile-time": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/vite-plugin-compile-time/-/vite-plugin-compile-time-0.2.1.tgz",
+      "integrity": "sha512-lRuoSO2wg2r0rWPLo9aeOH3s70FcuQZIhvcR7yGubbezFVsebljWf9Vtk/TlvuvBLLahfnEUyeV2FQM2sj2EYQ==",
+      "dependencies": {
+        "bundle-require": "^4.0.1",
+        "devalue": "^4.3.2",
+        "esbuild": "^0.19.1",
+        "magic-string": "^0.30.2"
+      },
+      "peerDependencies": {
+        "vite": ">=2"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/android-arm": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
+      "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/android-arm64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
+      "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/android-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
+      "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/darwin-arm64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
+      "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/darwin-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
+      "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
+      "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/freebsd-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
+      "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-arm": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
+      "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-arm64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
+      "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-ia32": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
+      "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-loong64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
+      "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
+      "cpu": [
+        "loong64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-mips64el": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
+      "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
+      "cpu": [
+        "mips64el"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-ppc64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
+      "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
+      "cpu": [
+        "ppc64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-riscv64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
+      "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-s390x": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
+      "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
+      "cpu": [
+        "s390x"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/linux-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
+      "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/netbsd-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
+      "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/openbsd-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
+      "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/sunos-x64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
+      "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/win32-arm64": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
+      "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/@esbuild/win32-ia32": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
+      "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/vite-plugin-compile-time/node_modules/esbuild": {
+      "version": "0.19.12",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
+      "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.19.12",
+        "@esbuild/android-arm": "0.19.12",
+        "@esbuild/android-arm64": "0.19.12",
+        "@esbuild/android-x64": "0.19.12",
+        "@esbuild/darwin-arm64": "0.19.12",
+        "@esbuild/darwin-x64": "0.19.12",
+        "@esbuild/freebsd-arm64": "0.19.12",
+        "@esbuild/freebsd-x64": "0.19.12",
+        "@esbuild/linux-arm": "0.19.12",
+        "@esbuild/linux-arm64": "0.19.12",
+        "@esbuild/linux-ia32": "0.19.12",
+        "@esbuild/linux-loong64": "0.19.12",
+        "@esbuild/linux-mips64el": "0.19.12",
+        "@esbuild/linux-ppc64": "0.19.12",
+        "@esbuild/linux-riscv64": "0.19.12",
+        "@esbuild/linux-s390x": "0.19.12",
+        "@esbuild/linux-x64": "0.19.12",
+        "@esbuild/netbsd-x64": "0.19.12",
+        "@esbuild/openbsd-x64": "0.19.12",
+        "@esbuild/sunos-x64": "0.19.12",
+        "@esbuild/win32-arm64": "0.19.12",
+        "@esbuild/win32-ia32": "0.19.12",
+        "@esbuild/win32-x64": "0.19.12"
+      }
+    },
     "node_modules/vite-plugin-dynamic-import": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/vite-plugin-dynamic-import/-/vite-plugin-dynamic-import-1.5.0.tgz",
       "integrity": "sha512-Qp85c+AVJmLa8MLni74U4BDiWpUeFNx7NJqbGZyR2XJOU7mgW0cb7nwlAMucFyM4arEd92Nfxp4j44xPi6Fu7g==",
-      "dev": true,
       "dependencies": {
         "acorn": "^8.8.2",
         "es-module-lexer": "^1.2.1",
@@ -9318,10 +9757,13 @@
         "pdf-lib": "^1.17.1",
         "rollup-plugin-copy": "^3.5.0",
         "tsconfig-paths": "^4.2.0",
+        "vite-plugin-compile-time": "^0.2.1",
+        "vite-plugin-dynamic-import": "^1.5.0",
         "vite-plugin-node-polyfills": "^0.19.0",
         "vite-plugin-top-level-await": "^1.4.1"
       },
       "devDependencies": {
+        "@rollup/plugin-dynamic-import-vars": "^2.1.2",
         "@rollup/plugin-run": "^3.0.2",
         "@rollup/plugin-typescript": "^11.1.6",
         "copyfiles": "^2.4.1",
diff --git a/server-node/package.json b/server-node/package.json
index 554d002a2..42733ddf0 100644
--- a/server-node/package.json
+++ b/server-node/package.json
@@ -36,10 +36,13 @@
         "pdf-lib": "^1.17.1",
         "rollup-plugin-copy": "^3.5.0",
         "tsconfig-paths": "^4.2.0",
+        "vite-plugin-compile-time": "^0.2.1",
+        "vite-plugin-dynamic-import": "^1.5.0",
         "vite-plugin-node-polyfills": "^0.19.0",
         "vite-plugin-top-level-await": "^1.4.1"
     },
     "devDependencies": {
+        "@rollup/plugin-dynamic-import-vars": "^2.1.2",
         "@rollup/plugin-run": "^3.0.2",
         "@rollup/plugin-typescript": "^11.1.6",
         "copyfiles": "^2.4.1",
diff --git a/server-node/rollup.config.js b/server-node/rollup.config.js
index 615b9a5d6..1ae3f5144 100644
--- a/server-node/rollup.config.js
+++ b/server-node/rollup.config.js
@@ -1,15 +1,16 @@
 import run from "@rollup/plugin-run";
 import typescript from '@rollup/plugin-typescript';
 import json from '@rollup/plugin-json';
-import copy from 'rollup-plugin-copy'
-
+import copy from 'rollup-plugin-copy';
+import compileTime from "vite-plugin-compile-time";
+import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
 
 const isDev = process.env.NODE_ENV !== "production";
 
 export default {
   input: "src/index.ts",
   output: {
-    file: "dist/bundle.js",
+    dir: "dist/",
     format: "es",
   },
   watch: {
@@ -18,6 +19,8 @@ export default {
   plugins: [
     json(),
     typescript(),
+    dynamicImportVars(),
+    compileTime(),
     copy({
         targets: [
             { src: '../shared-operations/public', dest: 'dist' },
diff --git a/server-node/src/index.ts b/server-node/src/index.ts
index 0e1a85c85..6fc4b44dc 100644
--- a/server-node/src/index.ts
+++ b/server-node/src/index.ts
@@ -6,6 +6,7 @@ const PORT = 8000;
 
 // server-node: backend api
 import api from "./routes/api/api-controller";
+import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
 app.use("/api", api);
 
 // serve
@@ -16,3 +17,5 @@ app.listen(PORT, () => {
 process.on('unhandledRejection', (reason, promise) => {
     console.error('Unhandled Rejection at:', promise, 'reason:', reason);
 });
+
+console.log("Available Modules: ", listOperatorNames())
\ No newline at end of file
diff --git a/server-node/src/routes/api/dynamic-operations-controller.ts b/server-node/src/routes/api/dynamic-operations-controller.ts
index 48a5708f7..b38d031d4 100644
--- a/server-node/src/routes/api/dynamic-operations-controller.ts
+++ b/server-node/src/routes/api/dynamic-operations-controller.ts
@@ -2,7 +2,7 @@ import express, { Request, Response } from "express";
 const router = express.Router();
 import multer from "multer";
 const upload = multer();
-import { getOperatorByName } from "@stirling-pdf/shared-operations/src/workflow/getOperatorByName";
+import { getOperatorByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
 import { Operator } from "@stirling-pdf/shared-operations/src/functions";
 
 import { PdfFile } from "@stirling-pdf/shared-operations/src/wrappers/PdfFile";
@@ -11,14 +11,14 @@ import { Action } from "@stirling-pdf/shared-operations/declarations/Action";
 import { JoiPDFFileSchema } from "@stirling-pdf/shared-operations/src/wrappers/PdfFileJoi";
 
 router.post("/:func", upload.array("file"), async function(req: Request, res: Response) {
-    handleEndpoint(req, res);
+    await handleEndpoint(req, res);
 });
 
 router.post("/:dir/:func", upload.array("file"), async function(req: Request, res: Response) {
-    handleEndpoint(req, res);
+    await handleEndpoint(req, res);
 });
 
-function handleEndpoint(req: Request, res: Response) {
+async function handleEndpoint(req: Request, res: Response) {
     if(!req.files || req.files.length == 0) {
         res.status(400).json({error: "no input file(s) were provided"});
         return;
@@ -31,7 +31,8 @@ function handleEndpoint(req: Request, res: Response) {
     }
     const pdfFiles: PdfFile[] = validationResults.value;
 
-    const operator = getOperatorByName(req.params.func);
+    const operator = await getOperatorByName(req.params.func);
+
     if(operator) {
         const action: Action = {type: req.params.func, values: req.body};
 
diff --git a/server-node/tsconfig.json b/server-node/tsconfig.json
index c32ef5428..86d3a8845 100644
--- a/server-node/tsconfig.json
+++ b/server-node/tsconfig.json
@@ -30,7 +30,7 @@
     "moduleResolution": "Node",                          /* Specify how TypeScript looks up a file from a given module specifier. */
     "baseUrl": "./src",                                  /* Specify the base directory to resolve non-relative module names. */
     "paths": {
-        "#pdfcpu": ["@stirling-pdf/shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.server"],
+        "#pdfcpu": ["../shared-operations/src/wasm/pdfcpu/pdfcpu-wrapper.server.js"],
         "@stirling-pdf/*": [ "../../*" ]
     },                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
     // "rootDirs": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
diff --git a/shared-operations/declarations/ImportMeta.d.ts b/shared-operations/declarations/ImportMeta.d.ts
new file mode 100644
index 000000000..9d1c2b246
--- /dev/null
+++ b/shared-operations/declarations/ImportMeta.d.ts
@@ -0,0 +1,3 @@
+declare interface ImportMeta {
+    compileTime: <T>(file: string) => T
+}
\ No newline at end of file
diff --git a/shared-operations/src/functions/arrangePages.ts b/shared-operations/src/functions/arrangePages.ts
index 9ad75b3c8..2c7f28c68 100644
--- a/shared-operations/src/functions/arrangePages.ts
+++ b/shared-operations/src/functions/arrangePages.ts
@@ -1,8 +1,7 @@
-
-import { PdfFile } from "../wrappers/PdfFile.js";
-import { Sorts } from "./common/pageIndexesSorting.js";
-import { getPages } from "./common/getPagesByIndex.js";
-import { parsePageIndexSpecification } from "./common/pageIndexesUtils.js";
+import { PdfFile } from "../wrappers/PdfFile";
+import { Sorts } from "./common/pageIndexesSorting";
+import { getPages } from "./common/getPagesByIndex";
+import { parsePageIndexSpecification } from "./common/pageIndexesUtils";
 
 export interface ArrangePagesParamsType {
     file: PdfFile;
diff --git a/shared-operations/src/workflow/getOperatorByName.ts b/shared-operations/src/workflow/getOperatorByName.ts
deleted file mode 100644
index 99bd9e9cd..000000000
--- a/shared-operations/src/workflow/getOperatorByName.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Operator } from "../functions";
-import i18next from "i18next";
-
-// TODO: Import other Operators (should make this dynamic imports)
-i18next.loadNamespaces("impose", (err, t) => { if (err) throw err; });
-import { Impose } from "../functions/impose";
-
-export const Operators = {
-    Impose: Impose
-};
-
-// TODO: Convert this to a map or similar
-export function getOperatorByName(name: string): typeof Operator | undefined {
-    let foundClass: typeof Operator | undefined = undefined;
-
-    // Loop over each default export
-    Object.entries(Operators).some(([className, exportedClass]) => {
-        // Check if the exported item is a class
-        if (typeof exportedClass === "function" && exportedClass.prototype) {
-            if (exportedClass.type === name) {
-                foundClass = exportedClass;
-                return true; // Stop the iteration
-            }
-        }
-        return false;
-    });
-    
-    return foundClass;
-}
-
-export function listOperatorNames(): string[] {
-    // TODO: Implement this
-    return ["impose"];
-}
diff --git a/shared-operations/src/workflow/listOperatorsInDir.ts b/shared-operations/src/workflow/listOperatorsInDir.ts
new file mode 100644
index 000000000..a0c28585b
--- /dev/null
+++ b/shared-operations/src/workflow/listOperatorsInDir.ts
@@ -0,0 +1,38 @@
+import fs from "fs";
+import path from "path";
+import {
+    CompileTimeFunctionArgs,
+    CompileTimeFunctionResult,
+  } from "vite-plugin-compile-time"
+
+function getAllJsFiles(directory) {
+    const jsFiles = [];
+
+    // Synchronously read the contents of the directory
+    const files = fs.readdirSync(directory);
+
+    // Iterate through the files and filter out the JavaScript files
+    files.forEach((file) => {
+        const filePath = path.join(directory, file)
+        const isJsFile = fs.statSync(filePath).isFile() && path.extname(filePath) === '.ts';
+
+        if (isJsFile) {
+            const baseName = path.basename(filePath, '.ts');
+            if(baseName != "index") {
+                jsFiles.push(baseName);
+            }
+        }
+    });
+
+    return jsFiles;
+}
+export default async (
+    args: CompileTimeFunctionArgs,
+  ): Promise<CompileTimeFunctionResult> => {
+    const jsFiles = getAllJsFiles(__dirname + "/../functions/");
+    return {
+        data: jsFiles,
+        // Trigger rebuild when watched files change
+        watchFiles: [__filename],
+    }
+  }
\ No newline at end of file
diff --git a/shared-operations/src/workflow/operatorAccessor.ts b/shared-operations/src/workflow/operatorAccessor.ts
new file mode 100644
index 000000000..faf5295ad
--- /dev/null
+++ b/shared-operations/src/workflow/operatorAccessor.ts
@@ -0,0 +1,24 @@
+import { Operator } from "../functions";
+import i18next from "i18next";
+
+function getCompileTimeOperatorList(): string[] {
+    return import.meta.compileTime("./listOperatorsInDir.ts");
+}
+
+export async function getOperatorByName(name: string): Promise<typeof Operator | undefined> {
+    // Check if exists
+    if(!getCompileTimeOperatorList().includes(name)) return;
+
+    i18next.loadNamespaces(name, (err, t) => { if (err) throw err; });
+    return (await import("../functions/" + name + ".ts"))[capitalizeFirstLetter(name)];
+}
+
+export function listOperatorNames(): string[] {
+    const availableOperators = getCompileTimeOperatorList();
+    // TODO: Implement this
+    return availableOperators;
+}
+
+function capitalizeFirstLetter(string: String) {
+    return string.charAt(0).toUpperCase() + string.slice(1);
+}
\ No newline at end of file
diff --git a/shared-operations/src/workflow/traverseOperations.ts b/shared-operations/src/workflow/traverseOperations.ts
index 4dd684aca..d8e7ab7bd 100644
--- a/shared-operations/src/workflow/traverseOperations.ts
+++ b/shared-operations/src/workflow/traverseOperations.ts
@@ -3,10 +3,10 @@ import { Action, WaitAction } from "../../declarations/Action";
 import { PdfFile } from "../wrappers/PdfFile";
 import { Progress } from "../functions";
 import { validateOperations } from "./validateOperations";
-import { getOperatorByName } from "./getOperatorByName";
+import { getOperatorByName } from "./operatorAccessor";
 
 export async function traverseOperations(operations: Action[], input: PdfFile[], progressCallback: (state: Progress) => void): Promise<PdfFile[]> {
-    const validationResult = validateOperations(operations);
+    const validationResult = await validateOperations(operations);
     if(!validationResult.valid) {
         return Promise.reject({validationError: validationResult.reason});
     }
@@ -47,7 +47,7 @@ export async function traverseOperations(operations: Action[], input: PdfFile[],
             }
             break;
         default:
-            const operator = getOperatorByName(action.type);
+            const operator = await getOperatorByName(action.type);
             if(operator) {
                 const operation = new operator(action);
                 input = await operation.run(input, progressCallback);
diff --git a/shared-operations/src/workflow/validateOperations.ts b/shared-operations/src/workflow/validateOperations.ts
index 66de33812..f3d89bbbd 100644
--- a/shared-operations/src/workflow/validateOperations.ts
+++ b/shared-operations/src/workflow/validateOperations.ts
@@ -1,9 +1,9 @@
 import { Operator } from "../functions";
 import { Action } from "../../declarations/Action";
-import { getOperatorByName } from "./getOperatorByName";
+import { getOperatorByName } from "./operatorAccessor";
 
 /** This function validates the "workflow-json" from the API */
-export function validateOperations(actions: Action[]): { valid: boolean, reason?: string} {
+export async function validateOperations(actions: Action[]): Promise<{ valid: boolean, reason?: string}> {
     const done: Action[] = [];
 
     for (const action of actions) {
@@ -15,7 +15,7 @@ export function validateOperations(actions: Action[]): { valid: boolean, reason?
             continue;
         }
         
-        const operator = getOperatorByName(action.type);
+        const operator = await getOperatorByName(action.type);
         if(!operator) {
             return { valid: false, reason: `action.type ${action.type} does not exist` };
         }
@@ -35,7 +35,7 @@ export function validateOperations(actions: Action[]): { valid: boolean, reason?
                     }
 
                     for (const afterDoneChild of done[childAction.values.id]?.actions || []) {
-                        const receivingOperator = getOperatorByName(afterDoneChild.type);
+                        const receivingOperator = await getOperatorByName(afterDoneChild.type);
                         if (receivingOperator === undefined) {
                             return { valid: false, reason: `action.type ${afterDoneChild.type} does not exist.` };
                         } else if (!ioCompatible(operator, receivingOperator)) {
@@ -47,7 +47,7 @@ export function validateOperations(actions: Action[]): { valid: boolean, reason?
                     return { valid: false, reason: "There shouldn't be a done action here." };
                 }
                 else {
-                    const receivingOperator = getOperatorByName(childAction.type);
+                    const receivingOperator = await getOperatorByName(childAction.type);
                     if (receivingOperator === undefined) {
                         return { valid: false, reason: `action.type ${childAction.type} does not exist.` };
                     } else if (!ioCompatible(operator, receivingOperator)) {
@@ -56,7 +56,7 @@ export function validateOperations(actions: Action[]): { valid: boolean, reason?
                 }
             }
 
-            const validationResult = validateOperations(action.actions);
+            const validationResult = await validateOperations(action.actions);
 
             if(!validationResult.valid) {
                 return validationResult;