diff --git a/pkgs/clan-app/ui-2d/index.html b/pkgs/clan-app/ui-2d/index.html
deleted file mode 120000
index 548aa000e..000000000
--- a/pkgs/clan-app/ui-2d/index.html
+++ /dev/null
@@ -1 +0,0 @@
-../ui/index.html
\ No newline at end of file
diff --git a/pkgs/clan-app/ui-2d/index.html b/pkgs/clan-app/ui-2d/index.html
new file mode 100644
index 000000000..0c649c3fb
--- /dev/null
+++ b/pkgs/clan-app/ui-2d/index.html
@@ -0,0 +1,14 @@
+
+
+
+ Solid App
+
+
+
+
+
+
+
+
+
+
diff --git a/pkgs/clan-app/ui-2d/package.json b/pkgs/clan-app/ui-2d/package.json
deleted file mode 120000
index c606d535c..000000000
--- a/pkgs/clan-app/ui-2d/package.json
+++ /dev/null
@@ -1 +0,0 @@
-../ui/package.json
\ No newline at end of file
diff --git a/pkgs/clan-app/ui-2d/package.json b/pkgs/clan-app/ui-2d/package.json
new file mode 100644
index 000000000..25ea99623
--- /dev/null
+++ b/pkgs/clan-app/ui-2d/package.json
@@ -0,0 +1,93 @@
+{
+ "name": "@clan/ui",
+ "version": "0.0.1",
+ "description": "",
+ "type": "module",
+ "scripts": {
+ "start": "vite",
+ "dev": "vite",
+ "build": "npm run check && npm run test && vite build && npm run convert-html",
+ "convert-html": "node gtk.webview.js",
+ "serve": "vite preview",
+ "check": "tsc --noEmit --skipLibCheck && eslint ./src",
+ "test": "vitest run --project unit --typecheck",
+ "storybook": "storybook",
+ "storybook-build": "storybook build",
+ "storybook-dev": "storybook dev -p 6006",
+ "test-storybook": "vitest run --project storybook",
+ "test-storybook-update-snapshots": "vitest run --project storybook --update",
+ "test-storybook-static": "npm run storybook-build && concurrently -k -s first -n 'SB,TEST' -c 'magenta,blue' 'http-server storybook-static --port 6006 --silent' 'wait-on tcp:127.0.0.1:6006 && npm run test-storybook'"
+ },
+ "license": "MIT",
+ "devDependencies": {
+ "@babel/plugin-syntax-import-attributes": "^7.27.1",
+ "@eslint/js": "^9.3.0",
+ "@kachurun/storybook-solid-vite": "^9.0.11",
+ "@storybook/addon-a11y": "^9.0.8",
+ "@storybook/addon-docs": "^9.0.8",
+ "@storybook/addon-links": "^9.0.8",
+ "@storybook/addon-onboarding": "^9.0.8",
+ "@storybook/addon-viewport": "^9.0.8",
+ "@storybook/addon-vitest": "^9.0.8",
+ "@tailwindcss/typography": "^0.5.13",
+ "@types/json-schema": "^7.0.15",
+ "@types/node": "^22.15.19",
+ "@types/three": "^0.176.0",
+ "@typescript-eslint/parser": "^8.32.1",
+ "@vitest/browser": "^3.2.3",
+ "@vitest/coverage-v8": "^3.2.3",
+ "autoprefixer": "^10.4.19",
+ "classnames": "^2.5.1",
+ "concurrently": "^9.1.2",
+ "eslint": "^9.27.0",
+ "eslint-plugin-tailwindcss": "^3.17.0",
+ "http-server": "^14.1.1",
+ "jsdom": "^26.1.0",
+ "playwright": "~1.52.0",
+ "postcss": "^8.4.38",
+ "postcss-url": "^10.1.3",
+ "prettier": "^3.2.5",
+ "solid-devtools": "^0.34.0",
+ "storybook": "^9.0.8",
+ "tailwindcss": "^3.4.3",
+ "typescript": "^5.4.5",
+ "typescript-eslint": "^8.32.1",
+ "vite": "^6.3.5",
+ "vite-plugin-solid": "^2.8.2",
+ "vite-plugin-solid-svg": "^0.8.1",
+ "vitest": "^3.2.3",
+ "wait-on": "^8.0.3"
+ },
+ "dependencies": {
+ "@floating-ui/dom": "^1.6.8",
+ "@kobalte/core": "^0.13.10",
+ "@kobalte/tailwindcss": "^0.9.0",
+ "@modular-forms/solid": "^0.25.1",
+ "@solid-primitives/storage": "^4.3.2",
+ "@solidjs/router": "^0.15.3",
+ "@tanstack/eslint-plugin-query": "^5.51.12",
+ "@tanstack/solid-query": "^5.76.0",
+ "corvu": "^0.7.1",
+ "material-icons": "^1.13.12",
+ "nanoid": "^5.0.7",
+ "solid-js": "^1.9.7",
+ "solid-markdown": "^2.0.13",
+ "solid-toast": "^0.5.0",
+ "three": "^0.176.0"
+ },
+ "optionalDependencies": {
+ "@esbuild/darwin-arm64": "^0.25.4",
+ "@esbuild/darwin-x64": "^0.25.4",
+ "@esbuild/linux-arm64": "^0.25.4",
+ "@esbuild/linux-x64": "^0.25.4"
+ },
+ "overrides": {
+ "vite": {
+ "rollup": "npm:@rollup/wasm-node@^4.34.9"
+ },
+ "@rollup/rollup-darwin-x64": "npm:@rollup/wasm-node@^4.34.9",
+ "@rollup/rollup-linux-x64": "npm:@rollup/wasm-node@^4.34.9",
+ "@rollup/rollup-darwin-arm64": "npm:@rollup/wasm-node@^4.34.9",
+ "@rollup/rollup-linux-arm64": "npm:@rollup/wasm-node@^4.34.9"
+ }
+}
diff --git a/pkgs/clan-app/ui-2d/tests b/pkgs/clan-app/ui-2d/tests
new file mode 120000
index 000000000..e26e91a6c
--- /dev/null
+++ b/pkgs/clan-app/ui-2d/tests
@@ -0,0 +1 @@
+../ui/tests
\ No newline at end of file
diff --git a/pkgs/clan-app/ui-2d/vite.config.ts b/pkgs/clan-app/ui-2d/vite.config.ts
deleted file mode 120000
index f6579e6aa..000000000
--- a/pkgs/clan-app/ui-2d/vite.config.ts
+++ /dev/null
@@ -1 +0,0 @@
-../ui/vite.config.ts
\ No newline at end of file
diff --git a/pkgs/clan-app/ui-2d/vite.config.ts b/pkgs/clan-app/ui-2d/vite.config.ts
new file mode 100644
index 000000000..61ab1c40e
--- /dev/null
+++ b/pkgs/clan-app/ui-2d/vite.config.ts
@@ -0,0 +1,54 @@
+import { defineConfig } from "vite";
+import solidPlugin from "vite-plugin-solid";
+import solidSvg from "vite-plugin-solid-svg";
+import devtools from "solid-devtools/vite";
+import path from "node:path";
+import { exec } from "child_process";
+
+// watch also clan-cli to catch api changes
+const clanCliDir = path.resolve(__dirname, "../../clan-cli");
+
+function regenPythonApiOnFileChange() {
+ return {
+ name: "run-python-script-on-change",
+ handleHotUpdate({}) {
+ exec("reload-python-api.sh", (err, stdout, stderr) => {
+ if (err) {
+ console.error(`reload-python-api.sh error:\n${stderr}`);
+ }
+ });
+ },
+ configureServer(server: import("vite").ViteDevServer) {
+ server.watcher.add([clanCliDir]);
+ },
+ };
+}
+
+export default defineConfig({
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./"), // This now points to ui-2d directory
+ },
+ },
+ optimizeDeps: {
+ include: ["debug", "extend"],
+ },
+ plugins: [
+ /*
+ Uncomment the following line to enable solid-devtools.
+ For more info see https://github.com/thetarnav/solid-devtools/tree/main/packages/extension#readme
+ */
+ devtools(),
+ solidPlugin(),
+ solidSvg(),
+ regenPythonApiOnFileChange(),
+ ],
+ server: {
+ port: 3000,
+ },
+ build: {
+ target: "safari11",
+ // assetsDi
+ manifest: true,
+ },
+});
\ No newline at end of file
diff --git a/pkgs/clan-app/ui-2d/vitest.config.ts b/pkgs/clan-app/ui-2d/vitest.config.ts
new file mode 120000
index 000000000..dbf594a2c
--- /dev/null
+++ b/pkgs/clan-app/ui-2d/vitest.config.ts
@@ -0,0 +1 @@
+../ui/vitest.config.ts
\ No newline at end of file