Skip to content

Enable plugins to rename layer names #18558

Open

Description

@Freymaurer

Based on my comment on another discussion (link). For context, i am working on a component library using the new vite tailwind plugin.

If you export tailwind 4 css into a tailwind 3 project (even with prefix) it throws due to: @layer base is used but no matching @tailwind base directive is present..

The recommended workaround is to rename the layers as detailed here.

In my case this looks like this:

@layer swt-theme, swt-base, swt-components, swt-utilities;
@import "tailwindcss/theme.css" layer(swt-theme) prefix(swt);
@import "tailwindcss/preflight.css" layer(swt-base) prefix(swt);
@import "tailwindcss/utilities.css" layer(swt-utilities) prefix(swt);

@plugin "daisyui" {
    themes: all;
}

In addition to tailwind i use daisyui 5 (compatible with tailwind 4). Because of the daisyui plugin, the final .css file still contains references to @layer base resulting in @layer base is used but no matching @tailwind base directive is present.

I reported this as issue with a tailwind play link, but it seems that this issue cannot be adressed by the author of daisyui.

I quote:

I understand.
Unfortunately, it's not possible yet to use another layer name due to Tailwind CSS plugin API.
Tailwind CSS provides APIs like addBase, addComponents, addUtilities
addBase always adds styles to Tailwind's predefined @layer base and addComponents, addUtilities always add styles to Tailwind's predefined @layer utilities.

If Tailwind provides more access regarding this behavior, we may be able to provide an option as well.

I hope that you can provide a way for plugin provider to either customize layer names or to correctly propagate any name changes in the tailwind config to the plugins.

This issue currently forces me to update the css file by hand before publishing, so it is really annoying 😅

Thanks for your time, reading this!

Activity

  1. Matheun commented on Aug 27, 2025

    @Matheun

    This would probably be better of in something like a addLayer function:

    // tailwindcss/packages/tailwindcss/src/compat/plugin-api.ts
    export function buildPluginApi({
    ...
    }): PluginAPI {
      let api: PluginAPI = {
        ...
        addLayer(name, css) {
          if (referenceMode) return
          let baseNodes = objectToAst(css)
          featuresRef.current |= substituteFunctions(baseNodes, designSystem)
          let rule = atRule('@layer', name, baseNodes)
          walk([rule], (node) => {
            node.src = src
          })
          ast.push(rule)
        },
        ...
      }
    }

    @thecrypticace Would this be a solution? I don't fully understand yet how the prefixes are handled in the source code, but this seems like a solution to me.

    This could also possibly replace the addBase function (if this works ofc) since people could then simply use addLayer(base, css)

  2. Freymaurer commented on Sep 30, 2025

    @Freymaurer
    Author

    @Matheun @thecrypticace is there any progess on this issue? 🙂

  3. Himanshu197200 commented on Nov 22, 2025

    @Himanshu197200

    @thecrypticace @Freymaurer is this issue still open for work?

  4. Freymaurer commented on Nov 22, 2025

    @Freymaurer
    Author

    Yes, i am still working around it using a custom ci job in which i replace the missing custom layer name

  5. ilya9933 commented on Aug 14, 2026

    @ilya9933

    I took a look at the current plugin API implementation on main before attempting a PR.

    There seem to be two related, but different, requirements here:

    1. Let a plugin author emit CSS into an arbitrary layer.
    2. Let a plugin consumer remap the standard layers used by an existing plugin without waiting for that plugin to change.

    The proposed addLayer(name, css) API would address the first requirement. However, it would not solve the original daisyUI scenario by itself: an existing plugin would continue to call addBase() or addComponents() with the standard semantics until the plugin author released an update.

    In the current implementation:

    • addBase() creates an @layer base node directly in packages/tailwindcss/src/compat/plugin-api.ts.
    • addComponents() is currently an alias for addUtilities().
    • Utilities are registered in the design system and are emitted at the consumer's @tailwind utilities location, so they already behave differently from addBase().

    Would the maintainers prefer this to be solved at the plugin-author level with an API such as addLayer(name, css), or at the consumer/compiler level with a mapping for the standard base, components, and utilities layers?

    The consumer-side mapping would preserve compatibility with existing plugins and appears closer to the original use case, but it needs an agreed CSS API. I considered a mapping associated with @plugin, although using declarations in the @plugin body would conflict with the plugin's own options, so a dedicated compiler-level syntax may be cleaner.

    If custom layer mapping is in scope, I can prepare a focused PR with tests covering:

    • A plugin that calls addBase() while the consumer uses a renamed base layer.
    • Existing/default behavior when no mapping is configured.
    • Source locations and reference mode.
    • A v4 component-library stylesheet consumed by a v3 application.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions