windrunner 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -15
- package/README.md +328 -240
- package/dist/index.d.ts +62 -33
- package/dist/index.esm.js +235 -5
- package/dist/index.js +238 -5
- package/dist/index.min.js +3 -3
- package/package.json +58 -58
package/LICENSE
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
ISC License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Bigetion
|
|
4
|
-
|
|
5
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
-
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
-
copyright notice and this permission notice appear in all copies.
|
|
8
|
-
|
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
-
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
-
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
-
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
-
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
-
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
-
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bigetion
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,240 +1,328 @@
|
|
|
1
|
-
# windrunner
|
|
2
|
-
|
|
3
|
-
Zero-config Tailwind v4 runtime for the browser. Compile utility classes on-demand — no build step, no PostCSS, no config file.
|
|
4
|
-
|
|
5
|
-
Drop a `<script>` tag and start using Tailwind classes anywhere.
|
|
6
|
-
|
|
7
|
-
## How it works
|
|
8
|
-
|
|
9
|
-
Instead of generating a full CSS bundle upfront, `windrunner` scans the DOM for class names and compiles only the CSS rules actually used — then injects them into a `<style>` tag in `<head>`. A `MutationObserver` watches for DOM changes and compiles new classes as they appear.
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
Page loads → scan DOM → compile used classes → inject <style>
|
|
13
|
-
↑ |
|
|
14
|
-
MutationObserver detects new classes ←─────────────┘
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Install
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install windrunner
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Usage
|
|
24
|
-
|
|
25
|
-
### Drop-in script (zero config)
|
|
26
|
-
|
|
27
|
-
```html
|
|
28
|
-
<script type="module">
|
|
29
|
-
import { windrunner } from "windrunner";
|
|
30
|
-
windrunner({ autoStart: true });
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<div class="flex items-center gap-4 p-6 bg-blue-50 rounded-xl">
|
|
34
|
-
<h1 class="text-2xl font-bold text-slate-900">Hello</h1>
|
|
35
|
-
<button class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200">
|
|
36
|
-
Click me
|
|
37
|
-
</button>
|
|
38
|
-
</div>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### CDN
|
|
42
|
-
|
|
43
|
-
```html
|
|
44
|
-
<script type="module">
|
|
45
|
-
import { windrunner } from "https://cdn.jsdelivr.net/npm/windrunner@1.0.1/dist/index.min.js";
|
|
46
|
-
windrunner({ autoStart: true });
|
|
47
|
-
</script>
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Live demo / Example landing page
|
|
51
|
-
|
|
52
|
-
Try the example landing page:
|
|
53
|
-
|
|
54
|
-
- CodeSandbox (example landing): https://xj6q66.csb.app
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
### React / Vue
|
|
58
|
-
|
|
59
|
-
```js
|
|
60
|
-
import { useEffect } from "react";
|
|
61
|
-
import { windrunner } from "windrunner";
|
|
62
|
-
|
|
63
|
-
export default function App() {
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
const wind = windrunner({ id: "my-app", autoStart: true });
|
|
66
|
-
return () => wind.disconnect();
|
|
67
|
-
}, []);
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
<main className="min-h-screen bg-slate-50 p-8">
|
|
71
|
-
<h1 className="text-3xl font-bold text-slate-900">React + Windrunner</h1>
|
|
72
|
-
</main>
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Manual control
|
|
78
|
-
|
|
79
|
-
```js
|
|
80
|
-
import { createWindrunner, compileClass } from "windrunner";
|
|
81
|
-
|
|
82
|
-
// Compile a single class to a CSS rule string
|
|
83
|
-
const css = compileClass("md:hover:bg-blue-500");
|
|
84
|
-
// → '@media (min-width: 768px) { .md\\:hover\\:bg-blue-500:hover { background-color: oklch(...); } }'
|
|
85
|
-
|
|
86
|
-
// Create an instance with full control
|
|
87
|
-
const wind = createWindrunner({ id: "my-app" });
|
|
88
|
-
wind.processClassList("flex items-center justify-between gap-4");
|
|
89
|
-
wind.scan(); // scan entire document
|
|
90
|
-
wind.observe(); // start watching DOM mutations
|
|
91
|
-
wind.disconnect(); // stop watching
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## API
|
|
95
|
-
|
|
96
|
-
### `windrunner(options?)`
|
|
97
|
-
|
|
98
|
-
Auto-start mode. Scans DOM and begins observing immediately.
|
|
99
|
-
|
|
100
|
-
```ts
|
|
101
|
-
windrunner({
|
|
102
|
-
id?: string, // style tag id, default: "tailwind-runtime-css"
|
|
103
|
-
autoStart?: boolean, // default: true
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
```js
|
|
220
|
-
windrunner({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
1
|
+
# windrunner
|
|
2
|
+
|
|
3
|
+
Zero-config Tailwind v4 runtime for the browser. Compile utility classes on-demand — no build step, no PostCSS, no config file.
|
|
4
|
+
|
|
5
|
+
Drop a `<script>` tag and start using Tailwind classes anywhere.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
Instead of generating a full CSS bundle upfront, `windrunner` scans the DOM for class names and compiles only the CSS rules actually used — then injects them into a `<style>` tag in `<head>`. A `MutationObserver` watches for DOM changes and compiles new classes as they appear.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Page loads → scan DOM → compile used classes → inject <style>
|
|
13
|
+
↑ |
|
|
14
|
+
MutationObserver detects new classes ←─────────────┘
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install windrunner
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Drop-in script (zero config)
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<script type="module">
|
|
29
|
+
import { windrunner } from "windrunner";
|
|
30
|
+
windrunner({ autoStart: true });
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<div class="flex items-center gap-4 p-6 bg-blue-50 rounded-xl">
|
|
34
|
+
<h1 class="text-2xl font-bold text-slate-900">Hello</h1>
|
|
35
|
+
<button class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200">
|
|
36
|
+
Click me
|
|
37
|
+
</button>
|
|
38
|
+
</div>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### CDN
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<script type="module">
|
|
45
|
+
import { windrunner } from "https://cdn.jsdelivr.net/npm/windrunner@1.0.1/dist/index.min.js";
|
|
46
|
+
windrunner({ autoStart: true });
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Live demo / Example landing page
|
|
51
|
+
|
|
52
|
+
Try the example landing page:
|
|
53
|
+
|
|
54
|
+
- CodeSandbox (example landing): https://xj6q66.csb.app
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### React / Vue
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
import { useEffect } from "react";
|
|
61
|
+
import { windrunner } from "windrunner";
|
|
62
|
+
|
|
63
|
+
export default function App() {
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const wind = windrunner({ id: "my-app", autoStart: true });
|
|
66
|
+
return () => wind.disconnect();
|
|
67
|
+
}, []);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<main className="min-h-screen bg-slate-50 p-8">
|
|
71
|
+
<h1 className="text-3xl font-bold text-slate-900">React + Windrunner</h1>
|
|
72
|
+
</main>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Manual control
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
import { createWindrunner, compileClass } from "windrunner";
|
|
81
|
+
|
|
82
|
+
// Compile a single class to a CSS rule string
|
|
83
|
+
const css = compileClass("md:hover:bg-blue-500");
|
|
84
|
+
// → '@media (min-width: 768px) { .md\\:hover\\:bg-blue-500:hover { background-color: oklch(...); } }'
|
|
85
|
+
|
|
86
|
+
// Create an instance with full control
|
|
87
|
+
const wind = createWindrunner({ id: "my-app" });
|
|
88
|
+
wind.processClassList("flex items-center justify-between gap-4");
|
|
89
|
+
wind.scan(); // scan entire document
|
|
90
|
+
wind.observe(); // start watching DOM mutations
|
|
91
|
+
wind.disconnect(); // stop watching
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API
|
|
95
|
+
|
|
96
|
+
### `windrunner(options?)`
|
|
97
|
+
|
|
98
|
+
Auto-start mode. Scans DOM and begins observing immediately.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
windrunner({
|
|
102
|
+
id?: string, // style tag id, default: "tailwind-runtime-css"
|
|
103
|
+
autoStart?: boolean, // default: true
|
|
104
|
+
plugins?: Plugin[], // custom plugins (see Plugin System)
|
|
105
|
+
theme?: { // override/extend theme values
|
|
106
|
+
extend: {
|
|
107
|
+
colors: { brand: "#ff6b6b" }
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Plugin System (NEW in v1.1.0)
|
|
114
|
+
|
|
115
|
+
Create custom utilities and variants:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
import { windrunner, plugin } from 'windrunner';
|
|
119
|
+
|
|
120
|
+
// Define a plugin
|
|
121
|
+
const myPlugin = plugin(({ addUtility, addVariant, theme }) => {
|
|
122
|
+
// Add custom utility
|
|
123
|
+
addUtility('glass', 'backdrop-filter: blur(10px); background: rgba(255,255,255,0.1);');
|
|
124
|
+
|
|
125
|
+
// Add pattern-based utility
|
|
126
|
+
addUtility(/^text-stroke-(\d+)$/, (match) => {
|
|
127
|
+
return `-webkit-text-stroke-width: ${match[1]}px;`;
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Add custom variant
|
|
131
|
+
addVariant('parent-hover', (selector) => `.parent:hover ${selector}`);
|
|
132
|
+
|
|
133
|
+
// Access theme
|
|
134
|
+
const colors = theme('colors');
|
|
135
|
+
addUtility('brand-bg', `background-color: ${colors.brand};`);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Use the plugin
|
|
139
|
+
windrunner({
|
|
140
|
+
autoStart: true,
|
|
141
|
+
plugins: [myPlugin]
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
See [Plugin Examples](./examples/plugins/) for ready-to-use plugins:
|
|
146
|
+
- **text-stroke** - Text outline effects
|
|
147
|
+
- **glass-morphism** - Glassmorphism effects
|
|
148
|
+
- **custom-variants** - parent-hover, loading, and more
|
|
149
|
+
|
|
150
|
+
**Plugin API:**
|
|
151
|
+
- `addUtility(pattern, handler)` - Add custom utility
|
|
152
|
+
- `addUtilities(utilities)` - Add multiple utilities
|
|
153
|
+
- `addVariant(name, handler)` - Add custom variant
|
|
154
|
+
- `theme(key)` - Access theme values
|
|
155
|
+
- `config()` - Access full configuration
|
|
156
|
+
|
|
157
|
+
Full plugin documentation: [Plugin System Guide](./docs/guides/plugins.md) (coming soon)
|
|
158
|
+
|
|
159
|
+
### `createWindrunner(options?)`
|
|
160
|
+
|
|
161
|
+
Returns a runtime instance with manual control methods:
|
|
162
|
+
|
|
163
|
+
| Method | Description |
|
|
164
|
+
|---|---|
|
|
165
|
+
| `start()` | Scan DOM + start observer (waits for DOMContentLoaded) |
|
|
166
|
+
| `scan(root?)` | One-time scan of all `[class]` elements |
|
|
167
|
+
| `observe(root?)` | Start MutationObserver |
|
|
168
|
+
| `processClassName(cls)` | Compile + inject one class |
|
|
169
|
+
| `processClassList(str)` | Compile + inject space-separated classes |
|
|
170
|
+
| `processElement(el)` | Compile all classes on a DOM element |
|
|
171
|
+
| `flush()` | Force-flush pending element queue |
|
|
172
|
+
| `disconnect()` | Stop observer, cleanup |
|
|
173
|
+
| `getCacheSize()` | Number of compiled classes in cache |
|
|
174
|
+
| `getInsertedRuleCount()` | Number of CSS rules injected |
|
|
175
|
+
|
|
176
|
+
### `compileClass(className, options?)`
|
|
177
|
+
|
|
178
|
+
Compile a single class name to a CSS rule string. Works in Node.js too.
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
compileClass("hover:text-blue-500")
|
|
182
|
+
// → '.hover\\:text-blue-500:hover { color: oklch(0.623 0.214 259.8); }'
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `parseClass(className, screens?, containers?)`
|
|
186
|
+
|
|
187
|
+
Parse a class name into its parts:
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
parseClass("md:hover:mt-4", { md: "768px" })
|
|
191
|
+
// → { original: "md:hover:mt-4", baseToken: "mt-4", variants: ["hover"],
|
|
192
|
+
// breakpoint: "md", containerBreakpoint: null, important: false, starting: false }
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Supported utilities
|
|
196
|
+
|
|
197
|
+
Full Tailwind v4 coverage including:
|
|
198
|
+
|
|
199
|
+
- **Layout** — display, position, overflow, z-index, visibility, float, clear, aspect-ratio, columns, isolation, object-fit/position
|
|
200
|
+
- **Spacing** — margin, padding, gap, space (with negative values)
|
|
201
|
+
- **Sizing** — width, height, min/max-w/h, size-*
|
|
202
|
+
- **Flexbox** — flex, grow, shrink, basis, direction, wrap, align, justify, place
|
|
203
|
+
- **Grid** — grid-cols/rows, col/row-span, grid-flow, auto-cols/rows, place-*
|
|
204
|
+
- **Typography** — font-size, font-weight, line-height, letter-spacing, text-align, text-color, text-decoration, text-transform, text-overflow, whitespace, word-break, list-style
|
|
205
|
+
- **Colors** — all OKLCH P3 Tailwind v4 palette + mauve/olive/mist/taupe, opacity modifier (`bg-blue-500/50`)
|
|
206
|
+
- **Backgrounds** — bg-color, bg-linear-to-* (v4), gradient stops (from/via/to), bg-size/position/repeat/attachment/clip/origin
|
|
207
|
+
- **Borders** — border-width/style/color/radius (all sides + logical)
|
|
208
|
+
- **Effects** — shadow, opacity, inset-shadow-* (v4), ring, inset-ring-* (v4)
|
|
209
|
+
- **Transforms** — rotate, scale, translate (2D + 3D), skew, origin, perspective, backface, transform-style
|
|
210
|
+
- **Filters** — blur, brightness, contrast, grayscale, hue-rotate, invert, saturate, sepia, drop-shadow, all backdrop-* variants
|
|
211
|
+
- **Transitions** — transition, duration, delay, ease
|
|
212
|
+
- **Animations** — animate-spin/ping/pulse/bounce
|
|
213
|
+
- **Interactivity** — cursor, select, resize, outline, pointer-events, appearance, touch-action, scroll-behavior, scroll-margin/padding, will-change
|
|
214
|
+
- **v4 New** — field-sizing-*, mask-*, @container, @container breakpoints (@sm: @md: etc.)
|
|
215
|
+
- **Variants** — hover, focus, focus-visible, active, visited, disabled, dark, group-hover/focus, peer-*, not-hover/focus/disabled, in-hover, starting: (@starting-style), first/last/odd/even, before/after, placeholder
|
|
216
|
+
|
|
217
|
+
## Custom theme
|
|
218
|
+
|
|
219
|
+
```js
|
|
220
|
+
windrunner({
|
|
221
|
+
autoStart: true,
|
|
222
|
+
theme: {
|
|
223
|
+
extend: {
|
|
224
|
+
colors: {
|
|
225
|
+
brand: {
|
|
226
|
+
50: "oklch(0.97 0.01 200)",
|
|
227
|
+
500: "oklch(0.55 0.18 200)",
|
|
228
|
+
900: "oklch(0.25 0.10 200)",
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
spacing: {
|
|
232
|
+
18: "4.5rem",
|
|
233
|
+
128: "32rem",
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Preventing FOUC
|
|
241
|
+
|
|
242
|
+
Because windrunner compiles CSS at runtime, browsers may briefly render unstyled content before styles are injected (Flash of Unstyled Content). The recommended fix:
|
|
243
|
+
|
|
244
|
+
```html
|
|
245
|
+
<head>
|
|
246
|
+
<!-- 1. Hide the page before styles are ready -->
|
|
247
|
+
<style>html { opacity: 0; transition: opacity 0.2s ease; }</style>
|
|
248
|
+
|
|
249
|
+
<!-- 2. Reveal after windrunner finishes its first scan -->
|
|
250
|
+
<script type="module">
|
|
251
|
+
import { windrunner } from "windrunner";
|
|
252
|
+
windrunner({
|
|
253
|
+
autoStart: true,
|
|
254
|
+
onReady: () => document.documentElement.style.opacity = "1",
|
|
255
|
+
});
|
|
256
|
+
</script>
|
|
257
|
+
</head>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The `onReady` callback fires after the initial DOM scan completes and CSS rules are injected, ensuring the page is fully styled before it becomes visible. The `transition` gives a smooth 200ms fade-in instead of an abrupt pop.
|
|
261
|
+
|
|
262
|
+
## Preflight
|
|
263
|
+
|
|
264
|
+
windrunner injects a CSS reset (based on Tailwind's preflight) automatically. To opt out:
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
windrunner({ autoStart: true, preflight: false });
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## vs Tailwind Play CDN
|
|
271
|
+
|
|
272
|
+
| | windrunner | Tailwind Play CDN |
|
|
273
|
+
|---|---|---|
|
|
274
|
+
| Size | ~78 KB min | ~350 KB |
|
|
275
|
+
| Dependencies | 0 | 0 |
|
|
276
|
+
| Tailwind version | v4 | v4 |
|
|
277
|
+
| Works in Node.js | ✓ (compile only) | ✗ |
|
|
278
|
+
| Custom theme | ✓ | ✓ |
|
|
279
|
+
| Arbitrary values | ✓ | ✓ |
|
|
280
|
+
| Preflight | ✓ | ✓ |
|
|
281
|
+
| FOUC prevention | ✓ (onReady) | ✗ |
|
|
282
|
+
| Plugins | ✗ | ✓ |
|
|
283
|
+
| Full utility coverage | ✓ | ✓ |
|
|
284
|
+
|
|
285
|
+
## 📚 Documentation
|
|
286
|
+
|
|
287
|
+
**New to Windrunner?** Start here:
|
|
288
|
+
|
|
289
|
+
- **[Quick Start Guide](./docs/getting-started/quick-start.md)** - Get running in 5 minutes
|
|
290
|
+
- **[React Integration](./docs/frameworks/react.md)** - Best practices for React apps
|
|
291
|
+
- **[FOUC Prevention](./docs/guides/fouc-prevention.md)** - 5 strategies to prevent flash of unstyled content
|
|
292
|
+
- **[Full Documentation](./docs/)** - Complete guides, API reference, and recipes
|
|
293
|
+
|
|
294
|
+
### Example Projects
|
|
295
|
+
|
|
296
|
+
Learn by example with our sample applications:
|
|
297
|
+
|
|
298
|
+
1. **[Landing Page](./examples/landing.html)** - Modern marketing page with animations
|
|
299
|
+
2. **[Todo App](./examples/todo-app/)** - React app with dark mode and local storage
|
|
300
|
+
3. **[Coverage Demo](./examples/coverage/)** - Showcase of utility class coverage
|
|
301
|
+
|
|
302
|
+
## When to Use Windrunner
|
|
303
|
+
|
|
304
|
+
✅ **Perfect for:**
|
|
305
|
+
- Rapid prototyping and MVPs
|
|
306
|
+
- Landing pages and marketing sites
|
|
307
|
+
- Internal tools and dashboards
|
|
308
|
+
- No-code platforms (Webflow, WordPress, etc.)
|
|
309
|
+
- Projects without build tooling
|
|
310
|
+
- Learning Tailwind v4
|
|
311
|
+
|
|
312
|
+
⚠️ **Consider traditional Tailwind for:**
|
|
313
|
+
- Large production apps with strict performance budgets
|
|
314
|
+
- SEO-critical pages (requires FOUC prevention)
|
|
315
|
+
- Projects already using PostCSS/build tools
|
|
316
|
+
- Enterprise applications requiring battle-tested solutions
|
|
317
|
+
|
|
318
|
+
See the [documentation](./docs/) for detailed use case analysis and migration guides.
|
|
319
|
+
|
|
320
|
+
## Contributing
|
|
321
|
+
|
|
322
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
323
|
+
|
|
324
|
+
Found a bug? Have a feature request? [Open an issue](https://github.com/Bigetion/windrunner/issues/new).
|
|
325
|
+
|
|
326
|
+
## License
|
|
327
|
+
|
|
328
|
+
ISC
|