question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unify various modules and helpers

See original GitHub issue

What

Twind started as a single module that exported setup and tw. As the project has evolved we have added helpers like css/apply/style and other features to support things like the shim, SSR and CLI. Now we are coming up to V1 we are looking to clean up and consolidate the Twind offering somewhat.

The general idea here is to create an interface something like this for the client and server respectively:

import { setup, tw, css, apply, style, sheets } from "twind";
import { setup, extract, sheets } from "twind/server";

Why

The aim is to make things a little more intuitive, improve discoverability and make documentation easier. We have witnessed developers struggling to know what to import where and wondering whether they are doing it right. The proposal aims to create just one way to do things.

Considerations

Bundle Size

Unifying modules like this is likely to increase the overall bundle size by a couple of KB (from ~14 to 16). Time taken to download/parse Twind is always a primary concern but we think the pros outweigh the cons here. Another thing to note is that the module will be tree-shakeable so if you are using a bundler and don’t use css for example, then it won’t be bundled into your application.

Shim by default

You might notice that the shim is not exposed by the proposed interface. The more we have used Twind ourselves or seen it been used by others, we have noticed that the shim is the easiest and most popular mechanism for both server and client. Going forward we would like to make this the default behaviour and have things just work. This means that the go to way of adding styles to your app will be via class="bg-black text-white" which comes with the advantage of aligning static HTML and virtual DOM implementations. We appreciate that not every application will require the runtime component which activates the MutationObserver (and allows for the better dev tools experience) so we are proposing that this can be disabled by config similarly to the autoprefixer and hashing setup({ runtime: false }).

Tailwind Utilities

By default Twind includes Tailwind theme/variants/utilities definitions because it is a comprehensive and well documented preset. However this is where the vast majority of Twind’s filesize comes from. Something we have been considering lately is abstracting these out to twind/tailwind which make Twind core offering very obvious and promote the idea of developers/companies to create their own design system that they can use with Twind much like we do by default with Tailwind as a basis today. This might also allow developers to create custom builds that only import the utilities they need resulting in smaller bundles for everyone.

The downside of this however is (quite contrary to the primary goal here) that it would requires something like this:

import { setup, tw, css, apply, style, sheets } from "twind";
import * as tailwind from "twind/tailwind"

setup({ presets: [{ ...tailwind }] });

With that said, this is probably something we could either a) do internally but still apply Tailwind presets by default or b) not do at all c) embrace the ideal wholly knowing that extra import only has to be done once during setup.

RFC

I’m creating this issue to gather feedback, thoughts and further considerations that we might not have been noted here. If you have and bright ideas or strong opinions on any aspect of this proposal then please comment below and I will update this description accordingly.

/cc @tw-in-js/contributors

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:8
  • Comments:16 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
lukejacksonncommented, Apr 7, 2021

Only just seen this reply so thanks for your patience. We are using @twind/next out of the box with no special configuration. It works absolutely great. The critical CSS is extracted to a style tag at the top of the page on first load SSR… after that the shim kicks in and handles dynamic styles at runtime (think a modal that was opened by the user after page load that requires styling). This comes with the added benefit of not shipping potentially unused styles to the client, but obviously this is a tradeoff.

I’m still unsure of how valid the concern is of performance degradation when it comes to loading in Twind. On our netlify deploy environments we were seeing lighthouse perf scores ~90 and once we promoted the site to a production like environment we are seeing that go up to ~100 for desktop at least.

I do agree however that it would be interesting to see how we could make hydration more efficient. My initial approach would be to send down a map of already computed rules (essentially a serialized version of the cache that Twind would generate on the server) to prevent duplication of work by the browser. It sounds easy enough but I’m sure it comes with drawbacks/complications that I have not considered.

1reaction
lukejacksonncommented, Mar 30, 2021

Thanks for your comments @danielweck I will follow the conversation on the thread you created (as this was not really the intended topic here) but just to let you know that I’m working on a “not so pet project” (a global ecommerce site) and we only have ~16KB of compressed twind imported at runtime (which includes tw/shim/css/style). All critical CSS is statically extracted during SSR with twind/next.

So in that sense I think that is is reasonably reasonable to state this kind of JS size, excluding of course all the additional “non-essential” modules like typography and forms.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Module `Unification` - Oregon State University
Last updated on August 8, 2021. Here, we'll develop a general unification monad typeclas and transformer that will be used for type inference....
Read more >
Overview: module code — Ivy Models 1.0 documentation
All modules for which code is available. ivy_models.transformers.helpers · ivy_models.transformers.perceiver_io. © Copyright 2020-2022, Ivy Team.
Read more >
Move some EE only helper methods to EE modules - GitLab
Move some EE only helper methods to EE modules · Review changes · Check out branch · Download · Email patches · Plain...
Read more >
Problems with Standalone Build Helper and merge modules
1) Copied all merge module from the development machine (C:\Program Files (x86)\InstallShield\2012Spring\Modules\i386) to the build server. 2) ...
Read more >
Helper Modules | ICONICS Software Solutions
The Unified Data Manager is a collection of helpful tools all related to data manipulation and management. Unified Data Manager · 7:56 min....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found