Download the PHP package craftpulse/craft-tailwind without Composer

On this page you can find all versions of the php package craftpulse/craft-tailwind. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package craft-tailwind

Tailwind for Craft CMS

Server-side Tailwind CSS class merging for Craft CMS 5 templates. Resolves conflicting utility classes, organizes styles into named slots, and injects CSS custom properties -- all without client-side JavaScript.

What it solves

Component overrides without conflicts

A button component defines default colors. A page template wants to override just the color, but concatenating classes produces bg-brand-accent bg-red-500 -- both classes render, the cascade picks a winner unpredictably, and the source is impossible to reason about.

With craft-tailwind, the merge engine understands which utilities conflict and keeps only the last one per CSS property:

Dynamic colors without safelisting

A CMS field lets editors pick a brand color. Tailwind tree-shakes unused classes at build time, so writing bg-{{ color }} produces nothing -- the class never made it into the build.

CSS custom properties sidestep this entirely. Define your palette once in plugin settings, reference the variables in your templates with arbitrary value syntax, and swap values at runtime:

Form field modifiers

A form input has default styling. Error state needs a red border. Disabled state needs muted colors. Without merge, layering modifier classes means manually tracking which base classes to remove:

Installation

You can install Tailwind via the Plugin Store in the Craft control panel, or from the command line.

With DDEV:

Without DDEV:

Tailwind works on Craft 5.x and requires PHP 8.2 or later.

Configuration

Settings can be managed through the control panel (Settings > Plugins > Tailwind) or via a config file. File-based configuration takes precedence over CP settings.

Config file

Create config/tailwind.php:

When a setting is defined in both the config file and the CP, the config file value wins. The CP settings page shows a warning on each overridden field.

About the cacheSize setting

The merge engine is called every time you use craft.tailwind.merge() or build a ClassList. To avoid re-parsing the same class strings over and over within a single request, results are kept in an in-memory LRU cache (Least Recently Used). When the cache fills up, the entry that hasn't been used for the longest gets evicted to make room — so "hot" class strings (e.g. your main button's classes) stay resident.

The cache is per-request: it lives only for the duration of one PHP process. You don't need to think about invalidation. Set cacheSize to 0 to disable caching entirely (useful when debugging a merge).

Tip — HMR and the LRU don't interact. Because the cache is per-request, it starts empty on every page load. Editing tailwind.config.js, your CSS entry, the plugin settings, or anything Vite picks up will be reflected on the very next request — there's no stale cache to clear during development. The one place merges can survive across requests is inside Craft's {% cache %} blocks; that's normal template caching, not the plugin's LRU, and the usual {% cache %} invalidation rules apply.

Multi-environment configuration

The config file supports Craft's standard multi-environment pattern:

Usage

Class merging

craft.tailwind.merge() resolves conflicting Tailwind utilities. The last class per CSS property group wins:

Accepts any number of arguments. Each argument is a space-separated class string.

Named-slot ClassList

When a component has many style concerns, a flat class string becomes hard to override selectively. The ClassList object splits classes into named slots, each representing a single responsibility:

The ClassList object is immutable. Every mutation returns a new instance:

Works naturally with Craft's {% tag %} helper:

CSS variables

Define CSS custom properties in plugin settings (or config/tailwind.php), then render them as a <style> tag in your layout. The include() method returns a Twig\Markup object, so you don't need the |raw filter:

CSP and subresource integrity

Pass attributes to the <style> tag — useful for Content Security Policy nonces or other custom attributes:

The plugin doesn't assume a nonce source — wire it up to your CSP module's per-request nonce however you expose it (a variable, a service, a Twig global).

Auto-inject

If you don't want to think about where the tag goes, enable the Auto-Inject setting (CP or config/tailwind.php). The plugin will register the style block via Craft's View::registerCss() on every site request automatically:

Auto-inject is skipped on console requests and CP requests. If you use a dynamic per-request CSP nonce, keep auto-inject disabled and call {{ craft.tailwind.include({ nonce: cspNonce }) }} in your layout so the nonce can be resolved at render time.

Inspecting variables

Use craft.tailwind.cssVariables when you need to look up or iterate variables instead of rendering them:

Sanitization and naming

The CssVariables object sanitizes values to prevent CSS injection. Values containing characters outside the safe set (letters, digits, hyphens, underscores, dots, hashes, commas, parentheses, percent signs, slashes, spaces, and quotes) are silently dropped. In devMode, dropped values are logged as warnings.

Variable names are auto-prefixed with -- if missing, so both color-brand and --color-brand resolve to the same property.

Version detection

The plugin auto-detects whether your project uses Tailwind v3 or v4 and selects the correct merge engine. Detection follows this priority:

  1. CSS signals -- scans the CSS path for @import "tailwindcss" or @theme directives (definitive v4 indicators)
  2. Config files -- looks for tailwind.config.{js,ts,cjs,mjs} in the buildchain path (v3 indicator)
  3. Fallback -- defaults to v4 with a devMode warning

Set buildchainPath and cssPath in settings to point detection at the right directories. When unset, both default to the project root.

To skip detection entirely, set tailwindVersion to '3' or '4' explicitly.

Debug toolbar panel

When Craft's debug toolbar is enabled (devMode + a user with debug access), a Tailwind panel appears alongside the others. It records every merge operation during the current request and shows:

Use it to answer questions like "why is bg-red-500 not appearing on the page?" (find the merge input where it was overridden) or "is my cache actually helping?" (check the hit rate).

The panel has no overhead outside of debug-enabled requests — data collection only runs when the debug module is loaded.

Typography plugin support

The @tailwindcss/typography plugin registers prose-{size} and prose-{theme} classes that neither underlying merge engine knows about by default — so out of the box prose prose-sm prose-lg passes through unchanged. The plugin's typography setting opts you into a curated conflict-group config that covers the suffixes shipped by @tailwindcss/typography 0.5.x:

Enable it in plugin settings or in config/tailwind.php:

Now size and theme conflicts resolve last-wins, while size and color stay orthogonal:

A typical rich-text area with editor-controlled size:

Custom typography themes

If you've registered your own prose-* themes — for example a brand variant via an @utility prose-mybrand { ... } block on v4, or a theme.extend.typography.mybrand entry on v3 — add the suffixes to the extras lists so the merger treats them as conflict-group members:

With the extras above, merge('prose prose-slate', 'prose-mybrand') resolves to prose prose-mybrand. Suffixes are stored without the prose- prefix.

You can also manage the toggle and extras through the CP settings page (under Typography). Defaults are always included — extras only need entries for suffixes you've registered yourself.

Why opt-in?

Resolving prose-* conflicts by default would surprise users who use the typography plugin alongside their own prose-* naming conventions, or who don't use the typography plugin at all and would rather see their prose-* classes pass through unchanged. The toggle keeps the default behavior predictable and lets typography users enable resolution explicitly.

API reference

Template variables (craft.tailwind)

Property / Method Returns Description
.merge('a', 'b', ...) string Merge multiple class strings
.classes({ slot: 'classes' }) ClassList Named-slot class builder
.version string Detected Tailwind version ('3' or '4')
.cssVariables CssVariables CSS custom properties container
.include(attributes = {}) Twig\Markup Ready-to-render <style> tag — no \|raw required

ClassList methods

Method Returns Description
__toString() string All slots merged into a single class string
.get(slot) ?string Value of a single slot
.override({ slot: '...' }) ClassList New instance with replaced slots
.extend({ slot: '...' }) ClassList New instance with appended slot values
.without('slot', ...) ClassList New instance without named slots
.merge('additional') string All slots + additional merged to a string
.toArray() array Named slots as an associative array

CssVariables methods

Use these when you need introspection; for rendering prefer craft.tailwind.include() on the variable.

Method Returns Description
__toString() string :root { ... } CSS block
.asCss() string :root { ... } CSS block (no <style> wrapper)
.get(name) ?string Value of a single variable
.has(name) bool Whether a variable exists
.all() array All variables as key-value pairs
.isEmpty() bool Whether the collection is empty

Credits

This plugin wraps two PHP merge libraries:

Brought to you by CraftPulse.


All versions of craft-tailwind with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
craftcms/cms Version ^5.0.0
michtio/tailwind-merge-v3 Version ^1.2
michtio/tailwind-merge-v4 Version ^0.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package craftpulse/craft-tailwind contains the following files

Loading the files please wait ...