6 releases (stable)

1.0.4 Oct 11, 2023
0.1.0 Oct 11, 2023

#94 in Procedural macros

Download history 1/week @ 2024-02-18 4/week @ 2024-02-25 24/week @ 2024-03-31 41/week @ 2024-04-14

65 downloads per month

MIT/Apache

370KB
12K SLoC

twust

Twust is a powerful static checker in rust for TailwindCSS class names at compile-time.

Screenshot 2023-09-09 at 19 51 09

Table of Contents

Overview

twust is a Rust procedural macro that provides compile-time validation for TailwindCSS class names. Leveraging the power of Rust's macro system, twust ensures that you only use valid TailwindCSS class names, preventing runtime errors and promoting a more robust development experience.

Installation

Add twust to your Cargo.toml:

[dependencies]
twust = "0.1.0"

Usage

Simply prefix your TailwindCSS class strings with the tw! macro:

use twust::tw;

let classes = tw!("bg-blue-500 hover:bg-blue-700");
    // You can override/extend color/background color in tailwind.config.json
tw!("bg-taxvhiti bg-tahiti-500 bg-tahiti bg-midnight bg-purple bg-red-50 bg-tahiti-800 border-s-tahiti-800");
tw!("md:text-red-50 text-slate-50 text-purple text-tahiti-500");
tw!("py-sm md:py-md tablet:py-sm lg:py-lg xl:py-xl");
tw!("group");
tw!("hover:-translate-y-0.5 transition motion-reduce:hover:translate-y-0 motion-reduce:transition-none");
tw!("group/edit block invisible md:hover:bg-slate-200 group-hover/item:visible");
tw!("group-[:nth-of-type(3)_&]:block group-hover/edit:text-gray-700 group-[:nth-of-type(3)_&]:block");
tw!("scroll-m-15 group-aria-[sort=ascending]:rotate-0");

// Even scroll margin can also be configured, here we add, sm and md under the Spacing/scrollMargin field in the config file
tw!("scroll-mx-sm scroll-mx-md");
tw!("px-[-45px] px-[-45cm] px-[-45rem] px-[-45em] px-[-45%] px-[-45vh]");
tw!("m-4 last:first:invalid:last:first:p-4 last:m-4 pb-[calc(100%-34px)] pb-[23px] [mask-type:luminance]
    [mask-type:luminance] hover:[mask-type:alpha] lg:[--scroll-offset:44px] oyelowo oyedayo break-after-avoid"
);
tw!("h-full border-2 border-opacity-60 rounded-lg overflow-hidden");

If an invalid class name is used, the compiler will raise an error, preventing it from being used in your application.

Statement of Problem

TailwindCSS offers developers a flexible utility-first approach to styling web applications. However, its flexibility can also lead to potential pitfalls:

  • Runtime Errors: Invalid TailwindCSS class names can cause unexpected styling issues that are only caught during runtime.

  • Developer Experience: Manually validating class names can be tedious and error-prone. Moreover, relying on runtime checks or external tools can disrupt the development workflow.

  • Incompatibility with Plugins: Some TailwindCSS utilities extend their functionality with plugins like daisyui. Traditional methods might not support these extensions seamlessly, leading to a fragmented development experience.

  • Code Reusability: Directly copying and reusing TailwindCSS code from one project to another can often require manual transformations or mappings, reducing developer efficiency.

  • Increased Build Size: Invalid class names that slip into the production code can increase the size of the final CSS bundle, affecting performance.

Solution

twust addresses these challenges by offering:

  • Compile-time Validation: By checking the validity of TailwindCSS class names at compile time, twust prevents invalid class names from making their way into the production code.

  • Seamless Integration: As a Rust macro, twust integrates seamlessly into your Rust workflow, offering immediate feedback without the need for external tools or manual validation.

  • Plugin Support: With twust, you can easily integrate popular plugins like daisyui by merely specifying them as a feature, ensuring a consistent and extended development experience.

  • Effortless Code Reusability: The ability to copy-paste and reuse your TailwindCSS code without any manual mappings or transformations. Just wrap your code with the macro, and you're set.

  • Optimized Builds: By ensuring only valid class names are used, twust helps in reducing the unnecessary bloat in the final CSS bundle.

Features

  • Comprehensive Coverage: Supports all standard TailwindCSS class names, including responsive variants, pseudo-class variants, and more.

  • Custom Configurations: Easily integrate with custom TailwindCSS configurations to support custom utility classes.

  • Plugin Integration: Enable support for popular plugins like daisyui by specifying them as a feature, offering an extended range of class names.

  • Easy Code Reusability: Directly copy-paste your TailwindCSS code across projects without any manual effort, ensuring rapid development.

  • Performance: Designed with performance in mind, ensuring minimal overhead during the compilation process.

How does this compare with Other Rust Libraries

tailwindcss-to-rust

tailwindcss-to-rust is a CLI tool that generates Rust code from compiled TailwindCSS. It allows developers to refer to Tailwind classes from Rust, offering compile-time error checks for nonexistent classes and code completion for available classes.

Shortcomings:

  1. Complex Setup: The setup process for tailwindcss-to-rust requires several steps, including:

    • Installing multiple tools.
    • Customizing tailwind.config.js for Rust file checks.
    • Generating Rust code and ensuring the tailwindcss executable is in the PATH.
    • Modifying regular expressions to match a specific templating system.

    This setup can be daunting, especially for developers unfamiliar with TailwindCSS or Rust.

  2. Generated Code Maintenance: tailwindcss-to-rust generates code based on the current state of the TailwindCSS configuration. Any changes to the configuration or updates to TailwindCSS itself may require regenerating the Rust code, making maintenance more challenging.

  3. Custom Class Grouping: While the tool groups classes based on the Tailwind documentation, custom classes end up in an "unknown" group (C::unk). Although there's a plan to improve this, it's not yet implemented.

  4. Limited Modifiers: Some parameterizable modifiers like aria-* and data-* are not included. Depending on the project, this can be a significant limitation.

  5. External Dependencies: The tool requires the presence of the tailwindcss CLI tool, either through npm or as a standalone binary. This adds an external dependency, which might not be suitable for all projects, especially those that want to minimize their dependency tree.

Approach with twust

Our solution with twust offers a more streamlined and integrated approach:

  • Simpler Setup: Just add the macro to your project and start using it. No need for external tools or additional configuration steps.

  • Real-time Validation: Instead of generating static Rust code from TailwindCSS, twust validates class names in real-time during the compilation process.

  • No External Dependencies: twust is self-contained, meaning you don't need any external tools like the tailwindcss CLI.

  • Extensive Coverage: We support all standard TailwindCSS class names, including responsive variants, pseudo-class variants, and more. With the macro's flexibility, supporting newer TailwindCSS features becomes easier.

tailwind.config.json Overview

Basic Structure:

{
  "corePlugins": {},
  "allowedLists": {
    "classes": [],
    "modifiers": []
  },
  "theme": {
    ...utilities...
    "extend": {
      ...extended utilities...
    }
  },
  "variants": {},
  "plugins": {}
}

Key Sections:

  1. corePlugins: Determines which utility plugins should be included in the generated CSS. Each key represents a utility, and its value (true/false) determines if it should be generated.

  2. allowedLists:

    • classes: Array of allowed class names.
    • modifiers: Array of allowed modifiers like hover, focus, etc.
  3. theme: Defines the default values and customizations for your design system.

    In the main section of theme, you have configurations for different utilities like screens, colors, spacing, etc. The extend section within theme allows you to add additional values to the default set.

Contribution

Contributions are always welcome! If you have suggestions, bug reports, or want to contribute to the code, please open an issue or pull request.

License

twust is licensed under the MIT license. See the LICENSE file for details.

Dependencies

~4–5.5MB
~106K SLoC