diff --git a/.changeset/ninety-regions-love.md b/.changeset/ninety-regions-love.md
new file mode 100644
index 0000000..e6de288
--- /dev/null
+++ b/.changeset/ninety-regions-love.md
@@ -0,0 +1,5 @@
+---
+"$editor": minor
+---
+
+feat: node groups
diff --git a/apps/web/package.json b/apps/web/package.json
index 3945d04..c59559e 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -18,6 +18,7 @@
"eslint": "catalog:",
"globals": "catalog:",
"mode-watcher": "catalog:",
+ "phosphor-svelte": "catalog:",
"svelte": "catalog:",
"svelte-check": "catalog:",
"typescript-eslint": "catalog:",
diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte
index db47146..6dc32de 100644
--- a/apps/web/src/routes/+page.svelte
+++ b/apps/web/src/routes/+page.svelte
@@ -1,5 +1,36 @@
-See /editor :)
+
+ See /editor :)
+
+ How to use:
+
+ -
+
+ MAJ
+ +
+ DRAG
+
+ to select multiple nodes, then G to group them.
+
+ - UV nodes CANNOT be grouped at this time
+ -
+ When selecting a node group or when inside it, press N to bring up its
+ settings.
+
+ -
+ You can create your own, editable copy of any node group by opening its settings sheet
+ and pressing "Copy & Edit".
+
+ -
+ Nodes with are a node group.
+ Click the button to enter said
+ node group.
+
+ - Select a node group and press Enter to enter it.
+
+
diff --git a/apps/web/src/routes/editor/+page.svelte b/apps/web/src/routes/editor/+page.svelte
index bb9ed73..ff2e97e 100644
--- a/apps/web/src/routes/editor/+page.svelte
+++ b/apps/web/src/routes/editor/+page.svelte
@@ -1,19 +1,119 @@
+
+
+
+ {#if nodeType === "node-group"}
+
+
+ {#if nodeLocked}
+
+ {/if}
+ {#if sheetTargetId}
+
+ {/if}
+
+ {/if}
+
{label}
+
+
+
+
+ {#each outputs as outputDef (outputDef.id)}
+
+ {outputDef.label}: {outputDef.type}
+
+
+ {/each}
+
+ {#if nodeType === "group-input" && !isLocked}
+ {@render addHandleButton()}
+ {/if}
+
+
+
+
+{:else}
+