UNPKG

25.5 kBMarkdownView Raw
1> the smallest, fastest, most feature complete Tailwind-in-JS solution in existence
2
3[![MIT License](https://flat.badgen.net/github/license/tw-in-js/twind)](https://github.com/tw-in-js/twind/blob/main/LICENSE)
4[![Latest Release](https://flat.badgen.net/npm/v/twind?icon=npm&label&cache=10800&color=blue)](https://www.npmjs.com/package/twind)
5[![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/twind?icon=packagephobia&label&color=blue&cache=10800)](https://bundlephobia.com/result?p=twind 'gzip bundle size (including dependencies)')
6[![Package Size](https://flat.badgen.net/badgesize/brotli/https://cdn.jsdelivr.net/npm/twind/twind.min.js?icon=jsdelivr&label&color=blue&cache=10800)](https://unpkg.com/twind/twind.js 'brotli package size (without dependencies)')
7[![Documentation](https://flat.badgen.net/badge/icon/Documentation?icon=awesome&label)](https://twind.dev/docs)
8[![Github](https://flat.badgen.net/badge/icon/tw-in-js%2Ftwind?icon=github&label)](https://github.com/tw-in-js/twind)
9[![Discord](https://flat.badgen.net/badge/icon/discord?icon=discord&label)](https://discord.com/invite/2aP5NkszvD)
10[![CI](https://github.com/tw-in-js/twind/workflows/CI/badge.svg)](https://github.com/tw-in-js/twind/actions?query=workflow%3Aci)
11[![Coverage Status](https://flat.badgen.net/coveralls/c/github/tw-in-js/twind/main?icon=codecov&label&cache=10800)](https://coveralls.io/github/tw-in-js/twind?branch=main)
12
13- [Documentation](#documentation)
14- [Quickstart](#quickstart)
15- [Advantages](#advantages)
16- [Rationale](#rationale)
17- [Why Twind?](#why-twind)
18- [Benchmarks](#benchmarks) - how does twind compare to other libraries
19- [Inspiration](#inspiration) - who inspired us
20- [Release Notes](https://twind.dev/docs/handbook/release-notes.html) & [Changelog](https://github.com/tw-in-js/twind/releases) - what is new
21
22---
23
24If you are here then the likelihood is that you are using Tailwind or a CSS-in-JS solution such as styled-components, Emotion or goober in order to style your web applications. These packages have proven overwhelmingly popular and revolutionized web development as we know it.
25
26The purpose of this project is to unify these two approaches; embracing the flexibility of CSS-in-JS whilst conforming to the carefully considered constraints of the Tailwind API.
27
28We hope to create a place for likeminded people to discuss issues, share ideas and collaborate.
29
30## [Documentation](https://twind.dev/docs)
31
32Frequently viewed docs:
33
34- [Installation](https://twind.dev/docs/handbook/getting-started/installation.html) - how to install `twind`
35- [Styling with Twind](https://twind.dev/docs/handbook/getting-started/styling-with-twind.html) - how to style with Twind
36- [Shim](https://twind.dev/docs/handbook/getting-started/using-the-shim.html) - seamless integration with existing Tailwind HTML
37- [Grouping](https://twind.dev/docs/handbook/getting-started/thinking-in-groups.html) - how to optimize rules size
38- [Theming](https://twind.dev/docs/handbook/getting-started/customize-the-theme.html) - how to apply your theme
39- [CSS-in-JS](https://twind.dev/docs/handbook/getting-started/css-in-js.html) - how to apply custom CSS
40- [Setup](https://twind.dev/docs/handbook/advanced/setup.html) - how to use `setup`
41- [Components](https://twind.dev/docs/handbook/advanced/defining-components.html) - how to define component styles
42- [Tailwind Extensions](https://twind.dev/docs/handbook/getting-started/tailwind-extensions.html) - which additional features are available
43- [Static Extraction (SSR)](https://twind.dev/docs/handbook/advanced/ssr.html) - how to extract the generated CSS on the server
44- [Recipes](https://twind.dev/docs/handbook/recipes.html) - how to use with framework X
45- [Modules](https://twind.dev/docs/handbook/getting-started/modules.html) - which modules are available
46
47## Quickstart
48
49If you would like to get started with Twind right away then copy paste this code into your favorite sandbox:
50
51```js
52import { tw } from 'https://cdn.skypack.dev/twind'
53
54document.body.innerHTML = `
55 <main class="${tw`h-screen bg-purple-400 flex items-center justify-center`}">
56 <h1 class="${tw`font-bold text(center 5xl white sm:gray-800 md:pink-700)`}">This is Twind!</h1>
57 </main>
58`
59```
60
61Alternatively try the 🚀 [live and interactive demo](https://esm.codes/#aW1wb3J0IHsgdHcgfSBmcm9tICdodHRwczovL2Nkbi5za3lwYWNrLmRldi90d2luZCcKCmRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gYAogIDxtYWluIGNsYXNzPSIke3R3YGgtc2NyZWVuIGJnLXB1cnBsZS00MDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgfSI+CiAgICA8aDEgY2xhc3M9IiR7dHdgZm9udC1ib2xkIHRleHQoY2VudGVyIDV4bCB3aGl0ZSBzbTpncmF5LTgwMCBtZDpwaW5rLTcwMClgfSI+VGhpcyBpcyBUd2luZCE8L2gxPgogIDwvbWFpbj4KYA==) and take a look at the [installation guide](https://twind.dev/docs/handbook/getting-started/installation.html).
62
63For seamless integration with existing Tailwind HTML you can use [twind/shim](https://twind.dev/docs/handbook/getting-started/using-the-shim.html):
64
65```html
66<script type="module" src="https://cdn.skypack.dev/twind/shim"></script>
67
68<main class="h-screen bg-purple-400 flex items-center justify-center">
69 <h1 class="font-bold text(center 5xl white sm:gray-800 md:pink-700)">This is Twind!</h1>
70</main>
71```
72
73Try `twind/shim` in the 🚀 [live and interactive shim demo](https://esm.codes/#aW1wb3J0ICdodHRwczovL2Nkbi5za3lwYWNrLmRldi90d2luZC9zaGltJwoKZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBgCiAgPG1haW4gY2xhc3M9Imgtc2NyZWVuIGJnLXB1cnBsZS00MDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIiPgogICAgPGgxIGNsYXNzPSJmb250LWJvbGQgdGV4dChjZW50ZXIgNXhsIHdoaXRlIHNtOmdyYXktODAwIG1kOnBpbmstNzAwKSI+CiAgICAgIFRoaXMgaXMgVHdpbmQhCiAgICA8L2gxPgogIDwvbWFpbj4KYA==)
74
75> 📚 For more detailed instruction on usage please [read the documentation](https://twind.dev/docs/handbook/getting-started.html) and check out [this extended demo](https://esm.codes/#aW1wb3J0IHsgdHcsIHNldHVwIH0gZnJvbSAnaHR0cHM6Ly9jZG4uc2t5cGFjay5kZXYvdHdpbmQnCgpzZXR1cCh7CiAgdGhlbWU6IHsKICAgIC8vIEV4YW1wbGUgb2YgZXh0ZW5kaW5nIHRoZSBkZWZhdWx0IHRoZW1lCiAgICBleHRlbmQ6IHsKICAgICAgY29sb3JzOiB7IGhvdHBpbms6ICcjRkYwMEZGJyB9LAogICAgICByb3RhdGU6IHsgNTogJzVkZWcnIH0KICAgIH0KICB9Cn0pCgpjb25zdCBhcHAgPSAoKSA9PiBgCiAgICA8ZGl2IGNsYXNzPScke3N0eWxlLmNvbnRhaW5lcn0nPgogICAgICA8aDEgY2xhc3M9JyR7CiAgICAgICAgLy8gRXhhbXBsZSBvZiBhbiBpbmxpbmUgc3R5bGUKICAgICAgICB0d2AKICAgICAgICAgIHRleHQod2hpdGUgNHhsKQogICAgICAgICAgZm9udChib2xkIHNhbnMpCiAgICAgICAgICB0cmFuc2l0aW9uLXRyYW5zZm9ybQogICAgICAgICAgaG92ZXI6KAogICAgICAgICAgICByb3RhdGUtNQogICAgICAgICAgICBzY2FsZS0xNTAKICAgICAgICAgICAgY3Vyc29yLXBvaW50ZXIKICAgICAgICAgICkKICAgICAgICBgCiAgICAgIH0nPkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGA7CiAgCiAgCmNvbnN0IHN0eWxlID0gewogIC8vIEV4YW1wbGUgb2YgYWJzdHJhY3RlZCBzdHlsZQogIGNvbnRhaW5lcjogdHdgCiAgICBoLWZ1bGwKICAgIGJnLWhvdHBpbmsKICAgIGZsZXgKICAgIGl0ZW1zLWNlbnRlcgogICAganVzdGlmeS1jZW50ZXIKICBgCn0KCmRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gYXBwKCk=)
76
77## Advantages
78
79> 💡 You can click on each summary to show additional details.
80
81<details><summary>⚡️ No build step</summary>
82
83In fact, there is no dependency on Tailwind or PostCSS at all. This makes it possible to use Twind without a development server. The various ways how to start using twind are described in the [installation guide](https://twind.dev/docs/handbook/getting-started/installation.html).
84
85```js
86import { tw } from 'twind'
87
88document.body.innerHTML = `
89 <main class="${tw`h-screen bg-purple-400 flex items-center justify-center`}">
90 <h1 class="${tw`font-bold text(center 5xl white sm:gray-800 md:pink-700)`}">
91 This is Twind!
92 </h1>
93 </main>
94`
95```
96
97> 🚀 [live and interactive demo](https://esm.codes/#aW1wb3J0IHsgdHcgfSBmcm9tICdodHRwczovL2Nkbi5za3lwYWNrLmRldi90d2luZCcKCmRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gYAogIDxtYWluIGNsYXNzPSIke3R3YGgtc2NyZWVuIGJnLXB1cnBsZS00MDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgfSI+CiAgICA8aDEgY2xhc3M9IiR7dHdgZm9udC1ib2xkIHRleHQoY2VudGVyIDV4bCB3aGl0ZSBzbTpncmF5LTgwMCBtZDpwaW5rLTcwMClgfSI+CiAgICAgIFRoaXMgaXMgVHdpbmQhCiAgICA8L2gxPgogIDwvbWFpbj4KYA==)
98
99</details>
100
101<details><summary>🧪 Use plain Tailwind HTML markup</summary>
102
103It might not always be desirable to generate rules by invoking the compiler directly via function call. In this case you may use the [shim module](https://twind.dev/docs/handbook/getting-started/using-the-shim.html) which finds and replaces class names within HTML, generating styles appropriately. This feature can be used together with your favorite framework without any additional setup. This is especially useful during development too; for example when editing classes in the inspector.
104
105```html
106<script type="module" src="https://cdn.skypack.dev/twind/shim"></script>
107
108<main class="h-screen bg-purple-400 flex items-center justify-center">
109 <h1 class="font-bold text(center 5xl white sm:gray-800 md:pink-700)">This is Twind!</h1>
110</main>
111```
112
113> 🚀 [live and interactive shim demo](https://esm.codes/#aW1wb3J0ICdodHRwczovL2Nkbi5za3lwYWNrLmRldi90d2luZC9zaGltJwoKZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBgCiAgPG1haW4gY2xhc3M9Imgtc2NyZWVuIGJnLXB1cnBsZS00MDAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIiPgogICAgPGgxIGNsYXNzPSJmb250LWJvbGQgdGV4dChjZW50ZXIgNXhsIHdoaXRlIHNtOmdyYXktODAwIG1kOnBpbmstNzAwKSI+CiAgICAgIFRoaXMgaXMgVHdpbmQhCiAgICA8L2gxPgogIDwvbWFpbj4KYA==)
114
115</details>
116
117<details><summary>💸 Unlimited styles for a low fixed cost of ~12KB</summary>
118
119By shipping the compiler (rather than the resultant output) there is a known and fixed cost associated with styling. No matter how many styles you write or how many variants you use, all that your users will ever have to download is approximately 12KB of code (which is less than styled-components or your average purged Tailwind build).
120
121</details>
122
123<details><summary>🎯 Extended syntax, variants and directives</summary>
124
125> 💡 The following list is just an excerpt. Please take a look at the [Tailwind Extensions](https://twind.dev/docs/handbook/getting-started/tailwind-extensions.html) documentation page.
126
127- Custom syntax for grouping directives and variants
128
129 Having control over the interpreter affords us the possibility of defining terse syntax for [grouping responsive and pseudo variants](https://twind.dev/docs/handbook/getting-started/thinking-in-groups.html) as well as directives with common prefixes. This massively reduces repetition and improves comprehension.
130
131 ```js
132 // Before directive grouping
133 tw`border-2 border-black border-opacity-50 border-dashed`
134 // After directive grouping
135 tw`border(2 black opacity-50 dashed)`
136
137 // With variants
138 tw`sm:(border(2 black opacity-50 hover:dashed))`
139 // => sm:border-2 sm:border-black sm:border-opacity-50 sm:hover:border-dashed
140
141 tw`w(1/2 sm:1/3 lg:1/6) p-2`
142 // => w-1/2 sm:w-1/3 lg:w-1/6 p-2
143 ```
144
145- Every variant can be applied to every directive
146
147 Because twind is generating CSS during runtime there is no restriction to which directives variants can be applied.
148
149- Most pseudo classes can be used as variant or `group-*` variant
150
151 Unknown variants (not listed in [core variants](https://github.com/tw-in-js/twind/blob/main/src/twind/variants.ts)) are assumed to be [pseudo classes](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes).
152
153- Named groups to support nested groups
154
155 Named groups allow to nest groups within each other and target specific groups by their name. The group names are ad-hoc meaning there is no special configuration required.
156
157 Here is an example [using the shim](https://twind.dev/docs/handbook/getting-started/using-the-shim.html):
158
159 ```html
160 <div class="group-x bg-white hover:bg-blue-500 ...">
161 <p class="text-gray-900 group-x-hover:text-white ...">New Project</p>
162 <div class="group-y bg-gray-100 hover:bg-green-500 ...">
163 <p class="text-gray-500 group-y-hover:text-white ...">
164 Create a new project from a variety of starting templates.
165 </p>
166 </div>
167 </div>
168 ```
169
170- [Pseudo Elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) are supported using double colon
171
172 ```html
173 <p class="first-line::(uppercase text-blue-500)">
174 Styles will only be applied to the first line of this paragraph. After that, all text will be
175 styled like normal. See what I mean?
176 </p>
177 ```
178
179- `siblings`, `sibling` and `children` variants
180
181 Allows to apply styling to different elements instead of repeating a directive on each one. This feature can be combined with other variants like `hover`.
182
183- `override` variant to increase the specificity of rules
184
185 This can be used to ensure a rule has a higher [specificity](https://specificity.keegan.st/) than others:
186
187 ```js
188 const shared = tw`text(xl center blue-600) underline`
189 const special = tw`${shared} override:(text-purple-600 no-underline)`
190 ```
191
192- Using exclamation point (`!`) after a directive to override any other declarations
193
194 Directives may end with exclamation point (`text-center!`) to be marked as [important](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity#The_!important_exception)
195
196- Dark mode is always available
197
198 Please see [Installation - Dark Mode](https://twind.dev/docs/handbook/advanced/setup.html#dark-mode) for details.
199
200</details>
201
202<details><summary>✈️ Includes a themed Tailwind preflight stylesheet by default</summary>
203
204The [base reset](https://tailwindcss.com/docs/preflight) provided by Tailwind is instantiated with respect to your theme (values like fonts, colors etc.) and injected in the stylesheet during setup. This guarantees more consistent cross browser results out of the box.
205
206> 💡 It is possible to [customize or disable the preflight](https://twind.dev/docs/handbook/advanced/setup.html#preflight).
207
208</details>
209
210<details><summary>🎢 Familiar and Tailwind V2 compliant theming</summary>
211
212Theming is done exactly as [documented by the Tailwind](https://tailwindcss.com/docs/theme) meaning that you can copy paste in your themes from existing projects. The only different here is that there is no need to rebuild anything after changing you theme. Just refresh the page!
213
214> 💡 For further details please read the [theme guide](https://twind.dev/docs/handbook/getting-started/customize-the-theme.html).
215
216</details>
217
218<details><summary>🚓 Escape hatch for writing arbitrary CSS</summary>
219
220The compiler [accepts functions](https://twind.dev/docs/modules/twind.html#inline-plugins) that can return arbitrary CSS-in-JS objects. A convenient escape hatch for all those one-off rules which aren't supported by Tailwind. The `&` keyword allows you to write complex rules (like pseudo elements `&::before` and `&::after`) that are beyond the scope of inline styles without having to add another dependency.
221
222> 💡 We provide a [css helper](https://twind.dev/docs/handbook/getting-started/css-in-js.html) as a convenience for this case.
223
224</details>
225
226<details><summary>🤖 Built in support for conditionally combining rules</summary>
227
228Input is not limited to strings like with HTML classes. The [`tw` function](https://twind.dev/docs/handbook/getting-started/styling-with-twind.html#the-tw-function) accept arrays, objects, template literals, functions, almost everything! The interpreter spec is inspired by and is very similar to [clsx](https://github.com/lukeed/clsx) and offers a much more developer friendly API that handles null values gracefully.
229
230</details>
231
232<details><summary>🌈 Improve readability by breaking rules over multiple lines</summary>
233
234Using template literals as input ([the recommended method](https://twind.dev/docs/modules/twind.html#tw-function)) or even object syntax allows you to break rules over multiple lines, drastically improving readability and maintainability of complex rules.
235
236</details>
237
238<details><summary>❄️ Optional hashing of class names ensuring no conflicts</summary>
239
240By default no hashing is enabled to aid debugging during development. However it is possible to configure Twind to [hash class names](https://twind.dev/docs/handbook/advanced/setup.html#hash) before injecting them into the DOM. This may be useful in production as it can reduce the down-the-wire size of server-side rendered pages and eliminates any chance of class name conflicts with third party styles.
241
242</details>
243
244<details><summary>🚅 Faster than all popular CSS-in-JS libraries</summary>
245
246Given the limited grammar that the compiler has to support there is a much higher chance of finding a rule and its variant in the cache. Because of this along with some other specialist optimizations we are able to compile and inject CSS [faster than most](#benchmarks) CSS-in-JS solutions.
247
248</details>
249
250<details><summary>🔌 Language extension via plugins </summary>
251
252Extending the grammar is trivial and can be achieved by providing functions _inline_ or by generalizing inline rules and defining them during setup under [the _plugins_ key](https://twind.dev/docs/handbook/advanced/plugins.html).
253
254</details>
255
256<details><summary>🎩 Remove all runtime overhead with static extraction</summary>
257
258The compiler itself is not reliant on the DOM at all which makes it an ideal candidate for static extraction which essentially removes all runtime overhead. This is possible during [SSR](https://twind.dev/docs/handbook/advanced/ssr.md) or build time prepass.
259
260</details>
261
262## Rationale
263
264This project was started by the authors of two similar libraries – [oceanwind](https://github.com/lukejacksonn/oceanwind) and [beamwind](https://github.com/kenoxa/beamwind) – who chose to collaborate rather than compete with each other in this space.
265
266> Combining efforts has saved us time and resulted in a much more complete and production ready offering.
267
268Furthermore we were able to agree on and coin some standards for certain aspects of the implementation based on our collective learnings; things like parsing input, [grouping syntax](https://twind.dev/docs/handbook/getting-started/thinking-in-groups.html), precedence calculation and [plugin API](https://twind.dev/docs/handbook/advanced/plugins.html).
269
270## Why twind?
271
272A lot of developers ask _"Why not just use Tailwind?"_ and our answer is always that you should use Tailwind, it is an absolutely incredible API with amazing documentation!
273
274> I've wanted to do a CSS-in-JS flavor of Tailwind for over 2 years because of all the neat benefits you get there so it's cool to see projects like this! – [@adamwathan](https://twitter.com/adamwathan/status/1320370489408225282)
275
276However, if like us you are already building your app in JS using a framework like React, Preact, Vue or Svelte, rather than just static HTML, then compiling Tailwind shorthands just in time (like twind does) rather than ahead of time like with Tailwind and PostCSS, comes with a lot of advantages.
277
278### Challenges
279
280The core problems we are trying to solve here are as follows:
281
2821. Parsing Input: taking input and normalizing it to create a comprehendable set of Tailwind rules
2832. Compiling Rules: taking a set of Tailwind rules and translating them into appropriate CSS rules
2843. Injecting Styles: taking CSS rules and generating classes that get append to a stylesheet in the DOM
2854. Merging Themes: combining themes which configure and constrain the compiler
2865. Custom Plugins: taking functions and using them to extend the capabilities of the compiler
287
288This has to happen in a performant way at runtime, whilst adhering to Tailwind V2 as a language specification. All grammars that exist in Tailwind should be covered by this implementation.
289
290### Opportunities
291
292Simply recreating a tailwind like experience at runtime might seem like a futile exercise but we'd like to believe it opens up the doors to some exciting new possibilities. There is always going to be a tradeoff between compiling at ahead of time and compiling _just in time_, however we are confident the upsides here are significant enough to persue a runtime implementation and the results have been promising so far.
293
294> Note it is still possible to remove all runtime overhead via a prepass either at serve or built time
295
296The flexible nature of a runtime first approach affords us possibilities like:
297
298- Dynamic Theming: generating new themes on the fly without the need to rebuilding anything
299- Unlimited Variants: enabling every variant combination by default because unused rules are never generated
300- Enhanced Syntax: taking advantage of macros within template literals to create more terse rules
301- Error Handling: warning the developer about unknown directives and theme values
302- Hashing Classes: reducing the overall output size and eliminating conflicts via deterministic hashing
303- [Inline Plugins](https://twind.dev/docs/handbook/advanced/plugins.html#inline-plugins): extending the capabilities of the compiler with simple functions at runtime
304
305Another big advantage we see of shipping the interpreter compiler itself (rather than pre-compiled output) is that the effective size of the CSS for your whole app is deterministic and fixed. The weight of the compiler itself along with your theme file is all that users will ever download, no matter how many styles you use.
306
307Currently the compiler weighs around 12KB which is smaller than styled-components and the average tailwind output.
308
309### Motivation
310
311It goes without saying that the primary inspiration here comes from Tailwind. It is a revolutionary take on styling the web which has proven popular by designers and developers alike. All the core plugins here, abide by the rules painstakingly thought out, implemented and popularized by Adam Wathan et al. making us forever in his debt.
312
313We hope one day we will get the chance to collaborate with Tailwind Labs to create an official implementation!
314
315## Benchmarks
316
317The implementation is tested for speed alongside several popular CSS-in-JS solutions that export general CSS functions. For those that only support a _styled component_ approach an equivalent test has been setup. Currently Twind comes in on second place behind [goober](https://github.com/cristianbote/goober) – a less than 1KB css-in-js solution by Cristian Bote – an awesome library worth checking out.
318
319### CSS Function w/ template literal
320
321```
322goober@2.0.30 x 632,419 ops/sec ±0.59% (95 runs sampled)
323twind (tw) x 400,438 ops/sec ±0.35% (84 runs sampled)
324twind (apply) x 342,725 ops/sec ±0.37% (96 runs sampled)
325twind (css) x 270,020 ops/sec ±0.53% (95 runs sampled)
326emotion@11.1.3 x 229,990 ops/sec ±0.17% (99 runs sampled)
327```
328
329### CSS Function w/ object
330
331```
332goober@2.0.30 x 842,430 ops/sec ±1.10% (88 runs sampled)
333twind (css) x 203,990 ops/sec ±0.32% (94 runs sampled)
334emotion@11.1.3 x 162,460 ops/sec ±0.75% (90 runs sampled)
335otion@0.6.2 x 53,592 ops/sec ±0.85% (96 runs sampled)
336```
337
338### Styled component w/ template literal
339
340```
341twind x 51,628 ops/sec ±0.63% (89 runs sampled)
342goober@2.0.18 x 40,069 ops/sec ±0.43% (96 runs sampled)
343emotion@11.0.0 x 35,349 ops/sec ±1.01% (93 runs sampled)
344styled-components@5.2.1 x 38,284 ops/sec ±0.48% (93 runs sampled)
345```
346
347For a more detailed testing summary please see the [benchmarks](https://github.com/tw-in-js/twind/blob/main/benchmarks) directory.
348
349## Inspiration
350
351It would be untrue to suggest that the design here is totally original. Other than the founders' initial attempts at implementing such a module ([oceanwind](https://github.com/lukejacksonn/oceanwind) and [beamwind](https://github.com/kenoxa/beamwind)) we are truly standing on the shoulders of giants.
352
353- [Tailwind](https://tailwindcss.com/): created a wonderfully thought out API on which the compiler's grammar was defined.
354- [styled-components](https://styled-components.com/): implemented and popularized the advantages of doing CSS-in-JS.
355- [htm](https://github.com/developit/htm): a JSX compiler that proved there is merit in doing runtime compilation of DSLs like JSX.
356- [goober](https://github.com/cristianbote/goober): an impossibly small yet efficient CSS-in-JS implementation that defines critical module features.
357- [otion](https://github.com/kripod/otion): the first CSS-in-JS solution specifically oriented around handling CSS in an atomic fashion.
358- [clsx](https://github.com/lukeed/clsx): a tiny utility for constructing class name strings conditionally.
359- [style-vendorizer](https://github.com/kripod/style-vendorizer): essential CSS prefixing helpers in less than 1KB of JavaScript.
360- [CSSType](https://github.com/frenic/csstype): providing autocompletion and type checking for CSS properties and values.
361
362---
363
364## Backers
365
366Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/twind#backer)]
367
368<a href="https://opencollective.com/twind/backer/0/website" target="_blank"><img src="https://opencollective.com/twind/backer/0/avatar.svg"></a>
369<a href="https://opencollective.com/twind/backer/1/website" target="_blank"><img src="https://opencollective.com/twind/backer/1/avatar.svg"></a>
370<a href="https://opencollective.com/twind/backer/2/website" target="_blank"><img src="https://opencollective.com/twind/backer/2/avatar.svg"></a>
371
372## Sponsors
373
374Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/twind#sponsor)]
375
376<a href="https://opencollective.com/twind/sponsor/0/website" target="_blank"><img src="https://opencollective.com/twind/sponsor/0/avatar.svg"></a>
377
378---
379
380## License
381
382[MIT](https://github.com/tw-in-js/twind/blob/main/LICENSE)
383
\No newline at end of file