Download the PHP package daikazu/bladewind without Composer

On this page you can find all versions of the php package daikazu/bladewind. 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 bladewind

BladeWind

BladeWind

Latest Version on Packagist Tests PHP Version Total Downloads

Buy Me A Coffee

Per-page CSS for Laravel apps built with Blade.

You know the Lighthouse warning: “Reduce unused CSS.” Meanwhile, every page on your site downloads the same compiled app.css, including rules for things that page will never render. I got tired of seeing that warning, so I built BladeWind.

BladeWind takes the CSS you have already compiled and gives each page two files: a small shared stylesheet and a second file with the rules that are only used for that page. It writes the page file on the first visit, then reuses it until the page or your CSS changes.

It built this to use with Tailwind but it also works with other CSS frameworks.

[!NOTE] This is an early release. Tailwind is where BladeWind has seen the most use. The other frameworks pass the test suite and work on the test sites, but they haven't met many real projects yet. If you try BladeWind with any of them, I'd love to hear how it went, good or bad: open an issue with your framework and what you saw. Until 1.0, a minor release may include breaking changes, and the changelog will call them out.

What it does

BladeWind reads the compiled stylesheet your vite build made. It doesn’t replace Vite, run Tailwind on the server, or add another build step.

It checks the classes in the page’s HTML and in the Blade views that generated it. This is important because a class inside an @if, added with wire:loading.class, or applied through an Alpine binding might not appear in the initial HTML response, even though the page still needs the corresponding CSS rule.

BladeWind copies the rules that page can use into a page file, keeping their contents and order. The rest of the site’s pages get their own files. If BladeWind can’t safely make one, it serves your normal full stylesheet and logs why.

It doesn’t remove or rewrite your CSS, and it can’t detect every class that your JavaScript or database-driven content may add later. Settings for handling those cases are covered below.

What it does not do: it does not purge, minify or rewrite your CSS; it does not touch your views, your compiled views or your HTML beyond the stylesheet links; and it cannot see classes that arrive from outside Blade (see When to use it, and when not to).

How much you save

I measured the gzipped CSS a page loads on the test sites I built BladeWind against, one per framework. Your numbers depend on how much of your framework is per-page rules and how much is base styling every page needs anyway:

Framework Full stylesheet With BladeWind Saving
Tailwind CSS 4 16.6 KB 6.1 to 7.7 KB 54 to 63%
Tailwind CSS 3 10.1 KB 5.1 KB 50%
Tachyons 13.6 KB 2.4 KB 83%
Bootstrap 5 30.7 KB 10.1 KB 67%
Bulma 1 65.0 KB 34.6 KB 47%
Foundation 6 17.4 KB 10.7 KB 38%

Tailwind 4 pages also get their theme variables and --tw-* defaults shaken per page; the other frameworks keep their variables and resets whole, since those come before the first component rule or must reach every page.

Requirements

PHP 8.4 and Laravel 13. The stylesheet must be built through Vite, so it can be found through public/build/manifest.json, and be the output of Tailwind CSS 4 or 3, Tachyons, Bootstrap 5, Bulma 1 or Foundation for Sites 6 (or a layer-less utility stylesheet you name as tailwind3 or tachyons in framework). The web server must be able to write to public/bladewind. Livewire 4 and livewire/blaze 1 are supported when present; neither is required.

Installation

  1. Install the package:

  2. In your layout, take the CSS entry out of @vite and add the directive right after it:

  3. Add the generated-files directory to .gitignore:

That's it. Run npm run build like always, and the first visit to each page writes its files. The web server needs write access to public/bladewind.

Publish the config only if you want to change a default:

Seeing it work

Build your assets, load a page, and check any of these:

When to use it, and when not to

BladeWind earns its keep on sites with lots of different pages that each use a slice of the stylesheet: a marketing site with a dashboard bolted on, a content site with varied templates, a component framework where every page pays for every component. It does little for a single dashboard app where every page uses most of the CSS, or for a stylesheet that's already tiny.

Skip it, or plan to configure around it, when:

Framework-specific limits worth knowing before choosing:

How it works

You don't need this section to use BladeWind. If you want to know what happens to a request, it goes through six steps:

  1. Analysis at compile time. When Blade compiles a view, BladeWind parses it and records every class token the view can produce: static class attributes, @class arrays, PHP expressions it can enumerate, wire:loading.class, Alpine :class bindings, and which views and components it includes. The entry is stored beside the compiled view. Nothing is precomputed for the whole site, and no command has to run first.
  2. Marked links. @bladewindStyles in your layout renders your normal stylesheet links, marked for replacement, so the page is complete even if nothing else happens.
  3. The page's class set. When the response is ready, a global middleware unions the classes in the final HTML with the analysed inventory of every view that rendered and everything those views statically include. Custom properties the document reads in style attributes, and the ones pages.keep_variables names, join the set as pseudo-tokens. So do the framework's runtime classes.
  4. The split. The compiled stylesheet is taken apart once per build by the driver that recognises it, and the result is memoised per process:
    • Tailwind 4 keeps its utilities in @layer utilities and its theme in @layer theme, so the root is the base and components layers plus every @keyframes, and a page file is its utilities, wrapped in the same layer, with only the theme variables, --tw-* defaults and @property registrations those utilities reach.
    • Every other framework is a flat stylesheet, so the split is a cut: everything before the first rule with a class selector (the reset or preflight, --tw-*, --bs-* or --bulma-* variables, your base styles) is the root, and everything from that rule on is what pages pick from, in source order, with @keyframes lifted into the root. Rules whose selectors name no class, or name an element beside a class, reach every page, because no class set can say whether an element needs them.
  5. The files. bw-root-<id>.css and bw-page-<id>-<set>.css are written under public/bladewind on first use, content-addressed, and pruned by least recent use. The marked links are replaced with links to them, or with an inline <style> for the page part.
  6. The fallback. Anything unexpected links the full stylesheet as @vite would.

Every step runs in PHP against the compiled stylesheet found through the Vite manifest. Build wherever you build today, ship public/build as usual, and make sure the web server can write to public/bladewind.

Configuration

Key Default Meaning
enabled true Turns the whole package off when false; @bladewindStyles then emits your normal links.
debug false Adds the metrics panel to every page and sends the X-BladeWind-Styles header. For development only.
paths [resource_path('views')] Directories whose views are analysed.
pages.enabled true Per-page stylesheets. false links the full stylesheet.
pages.delivery link link links the page file. inline writes it into the HTML as a <style> element instead: no flash of unstyled content with wire:navigate and one less request, at the cost of the page CSS (1 to 2 KB gzipped) travelling with every response instead of being cached per URL.
pages.keep_variables [] Theme variables your JavaScript reads by name (getPropertyValue('--color-brand')), which the server cannot see. Exact names or --prefix-*. Variables used in style attributes, :style bindings or <style> blocks are found automatically.
pages.max_files 500 Page files kept per compiled stylesheet before the least recently used are pruned. Keep it above your number of distinct page shapes.
pages.unanalysed fallback What a page gets when one of its rendered views has no analysis entry (a package view outside paths): fallback links the full stylesheet and logs BW6003 naming the view; html builds the page from the classes that rendered, which misses branches that view shows only after a Livewire update.
assets.path bladewind Directory under public/ for generated files. Keep it outside Vite's build directory, which vite build empties.
assets.url null Base URL for generated files. Leave null unless a CDN pulls from your origin; a push CDN never receives files written at runtime.
stylesheets ['resources/css/app.css'] Your Vite CSS entries. The first is split into root and page files. Each must be a CSS entry of the manifest: a script entry that imports CSS is refused (BW3002), and an entry the manifest does not carry makes @bladewindStyles throw exactly as @vite would.
build_directory build Vite's build directory under public/, if the application calls Vite::useBuildDirectory().
drivers [] Your own driver classes, tried before the built-in ones under auto and selectable by name. See "Writing your own driver".
framework auto Whose output the stylesheet is split as: tailwind4, tailwind3, tachyons, bootstrap5, bulma, foundation, or auto to recognise it from the stylesheet (a top-level @layer utilities block, else the --tw-* namespace, else the Tachyons banner, else the --bs-* or --bulma-* namespace, else Foundation's reveal overlay and XY grid classes). Name one to skip detection, or to split a layer-less utility stylesheet that is none of these as tailwind3 or tachyons, which split the same way.
safelist [] Class tokens every page carries whatever the analysis sees: exact tokens, or prefix-* patterns expanded against the classes the stylesheet has rules for.
components [] Per component or view: classes a view can produce that analysis cannot see; dynamic allowed targets of a dynamic component.
cache_path null Where analysis entries live. null means storage/framework/views/bladewind, which view:clear removes.

Troubleshooting

Every BW code mentioned below is explained in docs/diagnostics.md.

Livewire, Alpine and Blaze

Commands

None of them is required for page styles to work.

Testing your pages

The package ships a trait for a host application's own suite. One call per page asserts it was served with page styles rather than the fallback, that every class in its HTML the stylesheet styles has a rule in the root or page file, that the classes you name as reachable at runtime have one too, and that the page produced exactly the diagnostics you expect.

reaches is for classes the rendered HTML does not carry but a Livewire update or an Alpine binding can add. absent proves the page file is really per page. diagnostics is exact: a code you did not list fails, and a listed code that stopped firing fails too. fallback: true asserts the page falls back, unanalysed: n pins the header's count of rendered views without an analysis entry (left unchecked by default, since a dynamic component or a Livewire island counts its string-compiled views there), and framework: 'tailwind4' pins the driver. The call returns what it served (rootCss, pageCss, fullCss, the header fields) for assertions of your own. The suite needs a built stylesheet under public/build; the trait never builds one.

The call turns bladewind.debug on for the rest of the test, so the response carries the header. Clear the generated files between tests with app(PageStyleStore::class)->clear() in a beforeEach so each page is generated fresh. The HTML check is a differential check of the package's own scanner and split: rendered classes are always in a page's set, so regressions in analysis — unrendered branches, Alpine bindings, Livewire classes — are what reaches catches. Request-time codes (BW3xxx, BW6xxx) are logged once per process per reason, so pin them on the first page that triggers them in a test.

Writing your own driver

A driver tells BladeWind how one framework's compiled stylesheet is shaped. For a framework that keeps its rules in no cascade layer, which is every one except Tailwind 4, that is a name and a way to recognise the stylesheet:

Register it in config/bladewind.php:

That is all. FlatDriver supplies the rest: the split (everything before the first rule with a class selector is the root, the rest is what pages pick from, @keyframes lifted into the root), the indexing of each rule under the classes of the element it styles, the bare page file, and the BW6002 wording. Your driver is tried before the built-in ones under framework => 'auto', and framework => 'unocss' selects it outright.

Override runtimeTokens() when the framework's own JavaScript puts classes on elements no view contains (the way Bootstrap creates modal-backdrop or Foundation reveal-overlay): return those class names and every page carries their rules.

For a framework whose output is layered, or whose variables should be shaken per page, implement Daikazu\BladeWind\Pages\Drivers\CssFrameworkDriver directly and return a SplitStylesheet; Tailwind4Driver and StylesheetSplitter are the worked example. Whatever you return, the rule the package holds itself to applies: a page must never lack a rule or a variable it needs, so err toward carrying more, and run your stylesheet through the pattern in tests/Unit/Pages/Drivers/ to check that every rule after the cut is reachable from a token or unconditional.

Diagnostics

Everything BladeWind cannot see or do is reported with a BW code: analysis codes (BW1xxx, BW2xxx) from bladewind:analyze and bladewind:inspect, and request-time codes (BW3xxx, BW6xxx) in the application log. None of them breaks a page. The full list, with what each means and what to do about it, is in docs/diagnostics.md.

Resources

Credits

License

BladeWind is open-source software licensed under the MIT license.


All versions of bladewind with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
ext-zlib Version *
fortephp/forte Version ^1.1
laravel/framework Version ^13.0
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 daikazu/bladewind contains the following files

Loading the files please wait ...