diff --git a/frontend/src/components/floating-menus/NodeCatalog.svelte b/frontend/src/components/floating-menus/NodeCatalog.svelte
index 58856e2ac8..f4e19b8c9c 100644
--- a/frontend/src/components/floating-menus/NodeCatalog.svelte
+++ b/frontend/src/components/floating-menus/NodeCatalog.svelte
@@ -19,6 +19,9 @@
 
 	$: nodeCategories = buildNodeCategories($nodeGraph.nodeTypes, searchTerm);
 
+	let focusedNodeIndex = 0;
+	$: flatNodeList = nodeCategories.flatMap((node) => node[1].nodes);
+
 	type NodeCategoryDetails = {
 		nodes: FrontendNodeType[];
 		open: boolean;
@@ -29,6 +32,7 @@
 		const isTypeSearch = searchTerm.toLowerCase().startsWith("type:");
 		let typeSearchTerm = "";
 		let remainingSearchTerms = [searchTerm.toLowerCase()];
+		focusedNodeIndex = 0;
 
 		if (isTypeSearch) {
 			// Extract the first word after "type:" as the type search
@@ -104,11 +108,32 @@
 			});
 	}
 
+	function keyboardNavigationHandler(e: KeyboardEvent) {
+		const listLength: number = flatNodeList.length;
+		if (listLength === 0) return;
+
+		if (e.key === "ArrowDown") {
+			focusedNodeIndex = (focusedNodeIndex + 1) % listLength;
+			e.preventDefault();
+		} else if (e.key === "ArrowUp") {
+			focusedNodeIndex = (focusedNodeIndex - 1 + listLength) % listLength;
+			e.preventDefault();
+		} else if (e.key === "Enter") {
+			const node = flatNodeList[focusedNodeIndex];
+			dispatch("selectNodeType", node.name);
+		} else {
+			return;
+		}
+
+		setTimeout(() => document.querySelector("[data-emphasized]")?.scrollIntoView({ block: "nearest" }), 0);
+	}
+
 	onMount(() => {
 		setTimeout(() => nodeSearchInput?.focus(), 0);
 	});
 
 
+