
N8n:Design System
- 189 installs
- 199k repo stars
- Updated August 5, 2026
- n8n-io/n8n
Implement n8n UI using shared tokens, components, and layout rules so new screens stay visually consistent with the workflow editor and marketing product surfaces.
About
n8n:design-system skill encodes the n8n product UI standards—components, tokens, layout, and branding—so frontend work on the workflow platform remains consistent across editor screens and related SaaS surfaces.
- Defines n8n shared UI components
- Applies design tokens and spacing
- Keeps workflow editor visually consistent
- Guides frontend implementation choices
- Supports branded SaaS interface work
N8n:Design System by the numbers
- 189 all-time installs (skills.sh)
- +8 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #946 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/n8n-io/n8n --skill n8ndesign-systemAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 189 |
|---|---|
| repo stars | ★ 199k |
| Last updated | August 5, 2026 |
| Repository | n8n-io/n8n ↗ |
What it does
Implement n8n UI using shared tokens, components, and layout rules so new screens stay visually consistent with the workflow editor and marketing product surfaces.
Files
Design System
Comprehensive guide for building, styling, and using components in the frontend.
When to Apply
Reference these guidelines when:
- Working on
.{vue|css|scss}files inpackages/frontend - Adding new components to
packages/frontend/@n8n/design-system - Refactoring styles for Vue components
- Implementing new UI components or features
- Reviewing changes to UI
Rules
- Follow guidelines in
packages/frontend/@n8n/design-system/src/styleguide/*.mdx - ALWAYS use CSS variables for styles from
packages/frontend/@n8n/design-system/src/css/_tokens.scssorpackages/frontend/@n8n/design-system/src/css/_primtivies.scss. Use hard-coded values only when no suitable tokens. - ALWAYS prefer using existing components from
packages/frontend/@n8n/design-system/src/components. Prefer components that aren't marked@deprecated. - Use
light-dark()when alternating colors for ligh/dark mode - When working with animations or transitions, ALWAYS prefer using mixins from
packages/frontend/@n8n/design-system/src/css/mixins/motion.scss - When reviewing animations, follow the guides in
rules/web-animation-guidelines.md - When reviewing UI changes or adding new components, follow
rules/web-interface-guidelines.md
Examples
- "Add a modal dialog for confirming workflow deletion" → Use
N8nDialog - "Add a dropdown to select workflow status" → Use
N8nDropdownorN8nSelect - "Add button with + icon to add new tiem" → Wrap
N8nButtonwithiconOnlyprop withN8nTooltipand wrap inN8nTooltip. UseN8nIconand proper aria-label. - "Add a destructive action button" → use
N8nButtonwithvariant="destructive" - "Make background color white/black" → Use
var(--background--surface)for white on light mode and "black" on dark mode - "Animate the title in gracefully" -> Use
fade-in-upmixin frommotion.scsswithvar(--duration--base)
Web Motion Guidelines
Design and implement web animations that feel natural and purposeful
Timing and Duration
Duration Guidelines
| Element Type | Duration |
|---|---|
| Micro-interactions | 100-150ms |
| Standard UI (tooltips, dropdowns) | 150-250ms |
| Modals, drawers | 200-300ms |
Rules:
- UI animations should stay under 300ms
- Larger elements animate slower than smaller ones
- Exit animations can be ~20% faster than entrance
- Match duration to distance - longer travel = longer duration
The Frequency
Determine how often users will see the animation:
- 100+ times/day → No animation (or drastically reduced)
- Occasional use → Standard animation
- Rare/first-time → Can be more special
Example: Raycast never animates because users open it hundreds of times a day.
When to Animate
Do animate:
- Enter/exit transitions for spatial consistency
- State changes that benefit from visual continuity
- Responses to user actions (feedback)
- Rarely-used interactions where delight adds value
Don't animate:
- Keyboard-initiated actions
- Hover effects on frequently-used elements
- Anything users interact with 100+ times daily
- When speed matters more than smoothness
Performance
Prefer animating transform and opacity. These skip layout and paint stages, running entirely on the GPU.
Avoid animating:
padding,margin,height,width(trigger layout)blurfilters above 20px (expensive, especially Safari)- CSS variables in deep component trees
Optimization Techniques
/* Force GPU acceleration */
.animated-element {
will-change: transform;
}Practical Tips
Quick reference for common scenarios. See PRACTICAL-TIPS.md for detailed implementations.
| Scenario | Solution |
|---|---|
| Make buttons feel responsive | Add transform: scale(0.97) on :active |
| Element appears from nowhere | Start from scale(0.95), not scale(0) |
| Shaky/jittery animations | Add will-change: transform |
| Hover causes flicker | Animate child element, not parent |
| Popover scales from wrong point | Set transform-origin to trigger location |
| Sequential tooltips feel slow | Skip delay/animation after first tooltip |
| Small buttons hard to tap | Use 44px minimum hit area (pseudo-element) |
| Something still feels off | Add subtle blur (under 20px) to mask it |
| Hover triggers on mobile | Use @media (hover: hover) and (pointer: fine) |
Easing Decision Flowchart
Is the element entering or exiting the viewport? ├── Yes → ease-out └── No ├── Is it moving/morphing on screen? │ └── Yes → ease-in-out └── Is it a hover change? ├── Yes → ease └── Is it constant motion? ├── Yes → linear └── Default → ease-out
Web Interface Guidelines
<!-- credit to https://github.com/raunofreiberg/interfaces --> This document outlines a non-exhaustive list of details that make a good (web) interface. It is a living document, periodically updated based on learnings. Some of these may be subjective, but most apply to all websites.
The WAI-ARIA spec is deliberately not duplicated in this document. However, some accessibility guidelines may be pointed out. Contributions are welcome. Edit this file and submit a pull request.
Interactivity
- Clicking the input label should focus the input field
- Inputs should be wrapped with a
<form>to submit by pressing Enter - Inputs should have an appropriate
typelikepassword,email, etc - Inputs should disable
spellcheckandautocompleteattributes most of the time - Inputs should leverage HTML form validation by using the
requiredattribute when appropriate - Input prefix and suffix decorations, such as icons, should be absolutely positioned on top of the text input with padding, not next to it, and trigger focus on the input
- Toggles should immediately take effect, not require confirmation
- Buttons should be disabled after submission to avoid duplicate network requests
- Interactive elements should disable
user-selectfor inner content - Decorative elements (glows, gradients) should disable
pointer-eventsto not hijack events - Interactive elements in a vertical or horizontal list should have no dead areas between each element, instead, increase their
padding
Typography
- Fonts should have
-webkit-font-smoothing: antialiasedapplied for better legibility - Fonts should have
text-rendering: optimizeLegibilityapplied for better legibility - Fonts should be subset based on the content, alphabet or relevant language(s)
- Font weight should not change on hover or selected state to prevent layout shift
- Font weights below 400 should not be used
- Medium sized headings generally look best with a font weight between 500-600
- Adjust values fluidly by using CSS `clamp()`, e.g.
clamp(48px, 5vw, 72px)for thefont-sizeof a heading - Where available, tabular figures should be applied with
font-variant-numeric: tabular-nums, particularly in tables or when layout shifts are undesirable, like in timers - Prevent text resizing unexpectedly in landscape mode on iOS with
-webkit-text-size-adjust: 100%
Motion
- Switching themes should not trigger transitions and animations on elements [^1]
- Animation duration should not be more than 200ms for interactions to feel immediate
- Animation values should be proportional to the trigger size:
- Don't animate dialog scale in from 0 → 1, fade opacity and scale from ~0.8
- Don't scale buttons on press from 1 → 0.8, but ~0.96, ~0.9, or so
- Actions that are frequent and low in novelty should avoid extraneous animations: [^2]
- Opening a right click menu
- Deleting or adding items from a list
- Hovering trivial buttons
- Looping animations should pause when not visible on the screen to offload CPU and GPU usage
- Use
scroll-behavior: smoothfor navigating to in-page anchors, with an appropriate offset
Touch
- Hover states should not be visible on touch press, use
@media (hover: hover)[^3] - Font size for inputs should not be smaller than 16px to prevent iOS zooming on focus
- Inputs should not auto focus on touch devices as it will open the keyboard and cover the screen
- Apply
mutedandplaysinlineto<video />tags to auto play on iOS - Disable
touch-actionfor custom components that implement pan and zoom gestures to prevent interference from native behavior like zooming and scrolling - Disable the default iOS tap highlight with
-webkit-tap-highlight-color: rgba(0,0,0,0), but always replace it with an appropriate alternative
Optimizations
- Large
blur()values forfilterandbackdrop-filtermay be slow - Scaling and blurring filled rectangles will cause banding, use radial gradients instead
- Sparingly enable GPU rendering with
transform: translateZ(0)for unperformant animations - Toggle
will-changeon unperformant scroll animations for the duration of the animation [^4] - Auto-playing too many videos on iOS will choke the device, pause or even unmount off-screen videos
- Bypass React's render lifecycle with refs for real-time values that can commit to the DOM directly [^5]
- Detect and adapt to the hardware and network capabilities of the user's device
Accessibility
- Disabled buttons should not have tooltips, they are not accessible [^6]
- Focusable elements in a sequential list should be navigable with <kbd>↑</kbd> <kbd>↓</kbd>
- Focusable elements in a sequential list should be deletable with <kbd>⌘</kbd> <kbd>Backspace</kbd>
- To open immediately on press, dropdown menus should trigger on
mousedown, notclick - Use a svg favicon with a style tag that adheres to the system theme based on
prefers-color-scheme - Icon only interactive elements should define an explicit
aria-label - Tooltips triggered by hover should not contain interactive content
- Images should always be rendered with
<img>for screen readers and ease of copying from the right click menu - Illustrations built with HTML should have an explicit
aria-labelinstead of announcing the raw DOM tree to people using screen readers - Gradient text should unset the gradient on
::selectionstate - When using nested menus, use a "prediction cone" to prevent the pointer from accidentally closing the menu when moving across other elements.
Design
- Optimistically update data locally and roll back on server error with feedback
- Authentication redirects should happen on the server before the client loads to avoid janky URL changes
- Style the document selection state with
::selection - Display feedback relative to its trigger:
- Show a temporary inline checkmark on a successful copy, not a notification
- Highlight the relevant input(s) on form error(s)
- Empty states should prompt to create a new item, with optional templates
[^1]: Switching between dark mode or light mode will trigger transitions on elements that are meant for explicit interactions like hover. We can disable transitions temporarily to prevent this. For Next.js, use next-themes which prevents transitions out of the box. [^2]: This is a matter of taste but some interactions just feel better with no motion. For example, the native macOS right click menu only animates out, not in, due to the frequent usage of it. [^3]: Most touch devices on press will temporarily flash the hover state, unless explicitly only defined for pointer devices with `@media (hover: hover)`. [^4]: Use `will-change` as a last resort to improve performance. Pre-emptively throwing it on elements for better performance may have the opposite effect. [^5]: This might be controversial but sometimes it can be beneficial to manipulate the DOM directly. For example, instead of relying on React re-rendering on every wheel event, we can track the delta in a ref and update relevant elements directly in the callback. [^6]: Disabled buttons do not appear in tab order in the DOM so the tooltip will never be announced for keyboard users and they won't know why the button is disabled. [^7]: As of 2023, Safari will not take the border radius of an element into account when defining custom outline styles. Safari 16.4 has added support for outline following the curve of border radius. However, keep in mind that not everyone updates their OS immediately.