Skip to main content
Nodes 2.0 widgets allow you to create rich, interactive node widgets using Vue 3 Single File Components (SFCs). This is the recommended approach for building custom widgets that need complex UI interactions, state management, or styling.

Overview

You can create Vue-based widgets using the getCustomVueWidgets() hook. ComfyUI exposes Vue globally as window.Vue, so your extension uses the same Vue instance as the main app (smaller bundle size).

Project Structure

Complete Example

package.json

vite.config.ts

Key configuration points:

extension.js

WidgetStarRating.vue

init.py

Using Tailwind CSS

tailwind.config.js

Always set preflight: false to prevent Tailwind’s CSS reset from affecting ComfyUI’s styles.

postcss.config.js

styles.css

Handling Positioning

Without Tailwind’s preflight, some utility classes like absolute, translate-x-1/2 may not work as expected. Use inline styles for critical positioning:

Widget Component API

Your Vue component receives these props: Use defineModel() for two-way value binding:

Build and Test

Restart ComfyUI to load your extension.

Development Workflow

Run the watcher during development:
This rebuilds dist/extension.js on every file change. Refresh ComfyUI to see updates.

Common Pitfalls

Failed to resolve module specifier “vue”

The browser can’t resolve bare "vue" imports. Solution: Use rollup-plugin-external-globals to map Vue imports to window.Vue:

CSS Not Loading

ComfyUI only loads JS files. CSS must be inlined into the bundle. Solution: Use vite-plugin-css-injected-by-js.

Styles Affecting Other UI

Tailwind’s preflight resets global styles, breaking ComfyUI. Solution: Set preflight: false in tailwind.config.js.

Accessing ComfyUI’s App

Import from the relative path to scripts/app.js:
Configure Vite to preserve this import:

Examples