Registration happens against the instance’s node registry, fd.nodes (a NodeComponentRegistry). There are three methods:
Approach
When to use
fd.nodes.registerCustom()
One-off project-specific nodes
fd.nodes.registerPlugin()
Libraries providing multiple node types
createPlugin().register(fd.nodes)
Same as above, with a chainable builder API
Custom node types are namespaced (e.g., "mylib:code-editor") to prevent conflicts. Resolve fd with getInstance() inside the component tree, or use the mount handle’s .instance outside it. You can register before or after mounting.
Why registration works after mount
BaseRegistry tracks a version counter that invalidates dependent $derived
reads. When you register a node after mount, the counter bumps and the editor
re-resolves, so late registrations take effect.
Plugin lifecycle is managed on fd.nodes; isValidNamespace remains a standalone helper:
import { isValidNamespace, getInstance } from '@flowdrop/flowdrop/editor';const fd = getInstance();fd.nodes.unregisterPlugin('awesome'); // Remove all nodes from a pluginfd.nodes.getRegisteredPlugins(); // List registered namespacesfd.nodes.getPluginNodeCount('awesome'); // Count nodes in a pluginisValidNamespace('my-lib'); // Validate namespace format
Namespace rules: Must match /^[a-z][a-z0-9-]*$/ — lowercase letters, digits, and hyphens, starting with a letter.