Skip to content

[Feature Request] Support fully isolated UnoCSS runtime for component libraries (Shadow DOM) #4961

@octavio-parozlabs

Description

@octavio-parozlabs

Clear and concise description of the problem

Context / Problem

I am developing a React component library for dynamic forms, which uses UnoCSS runtime internally to apply dynamic styles.

The library will be imported by other projects, which may use TailwindCSS, Material UI, Bootstrap, or other styling systems.

Problem:

UnoCSS runtime currently injects global styles, including preflights and base styles, which can conflict with the consumer project’s styles.

I want UnoCSS runtime to be fully isolated within the library component, so the consumer project is not affected and does not need to know that UnoCSS is being used internally.

Ideally, this would involve using a Shadow DOM to encapsulate the styles and runtime updates.

Issues with Shadow DOM:

While Shadow DOM could theoretically isolate UnoCSS, there are challenges:

UnoCSS runtime and preflights are not fully compatible with Shadow DOM out-of-the-box.

MutationObserver-based runtime updates may not detect class changes inside shadow roots without additional configuration.

Base styles (preflights) may still leak to the global DOM if not properly scoped.

Currently, there is no native support in UnoCSS for fully running runtime inside a Shadow DOM in a way that is completely isolated and safe for component libraries.

🔹 Desired behavior

UnoCSS runtime should allow full isolation, preferably supporting Shadow DOM internally.

Preflights and base styles should only affect the component subtree (rootElement) and never touch the global DOM.

Runtime updates should only observe changes within the isolated container, preventing any side effects on the consumer project.

The consumer project should remain unaware of UnoCSS usage, avoiding style conflicts.

🔹 Example usage

'use client'

import { useEffect, useRef } from 'react'
import { createRuntimeUno } from '@unocss/runtime'
import presetUno from '@unocss/preset-uno'

export default function DynamicForm() {
  const ref = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (ref.current) {
      // Current runtime works, but cannot fully isolate within a Shadow DOM
      createRuntimeUno({
        defaults: { presets: [presetUno()] },
        rootElement: ref.current,
      })
    }
  }, [])

  return (
    <div ref={ref}>
      <div className="bg-green-600 text-white p-4">
        Dynamic content with UnoCSS runtime
      </div>
    </div>
  )
}

Current issue: UnoCSS runtime still injects styles globally (including preflights), and fully isolating it in a Shadow DOM is not supported.

Suggested solution

Expected behavior: UnoCSS runtime should be completely contained inside the library component, with styles scoped to the component’s subtree, fully compatible with Shadow DOM, and invisible to the consumer project.

🔹 Expected solution

Support for fully isolated UnoCSS runtime, optionally using Shadow DOM internally.

Preflights and base styles should be scoped to rootElement only.

Runtime updates (MutationObserver) should work inside the Shadow DOM.

Allow component libraries to use UnoCSS safely without leaking styles globally or causing conflicts with consumer projects.

Alternative

No response

Additional context

No response

Validations

  • Read the Contributing Guidelines.
  • Read the README.md of using the package.
  • Already used the Interactive Docs.
  • Check that there isn't already an issue that request the same feature to avoid creating a duplicate.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions