An experimental transpiler to bring tailwind macros to SWC 🚀

Overview

stailwc (speedy tailwind compiler)

This is an experimental SWC transpiler to bring compile time tailwind macros to SWC (and nextjs) a-la twin macro. The goal is to give the same great performance and flexibility while performing considerably better than babel-based alternatives (about 11x faster in my experience, proper benchmarks coming soon!)

🚨 We currently only support NextJS 12.2.5

Getting started

> yarn add stailwc

Currently the setup process is a little bit convoluted, but it will be cleaned up in the future, once we determine the best way to package this. Place the following in your next.config.js:

next.config.js

const stailwc = require("stailwc/install");

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  experimental: {
    swcPlugins: [stailwc()],
  },
  compiler: {
    emotion: true,
  },
};

module.exports = nextConfig;

Optionally, you can also include the tailwind normalizer.

_document.tsx

import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html>
      <Head>
        <link
          rel="stylesheet"
          type="text/css"
          href="https://unpkg.com/[email protected]/src/css/preflight.css"
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Now get hacking!

Usage

You can interact with stailwc in two ways. The first is through the tw JSW attribute, and the second is via the tw template tag.

import { useState } from "react";

export const ColorButton = () => {
  const [clicked, setClicked] = useState(0);
  return (
    <button
      tw="p-1 m-4 text-green bg-white hover:(bg-gray text-yellow md:text-red) border-3"
      css={clicked % 2 == 0 ? tw`border-green` : tw`border-blue`}
      onClick={() => setClicked(clicked + 1)}
    >
      Clicked {clicked} times
    </button>
  );
};

Caveats

Next currently doesn't support the SWC error handler meaning that errors are logged only to the command line, and not shown visually on the screen. This will be supported down the line (see here: vercel/next.js#39779).

Comments
  • The automated release is failing 🚨

    The automated release is failing 🚨

    :rotating_light: The automated release from the master branch failed. :rotating_light:

    I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

    You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

    Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

    Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

    If you are not sure how to resolve this, here are some links that can help you:

    If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


    Unable to build workspace dependencies graph: Unable to parse the workspace structure starting at /home/runner/work/stailwc/stailwc/Cargo.toml

    Unfortunately this error doesn't have any additional information. Feel free to kindly ask the author of the @semantic-release/exec plugin to add more helpful information.


    Good luck with your project ✨

    Your semantic-release bot :package::rocket:

    semantic-release 
    opened by arlyon 3
  • Rework mutliple tag detection

    Rework mutliple tag detection

    This case currently fails because the check isn't set up for recursive cases:

              <InputText
                register={register}
                name="value"
                tw="flex h-[20px] items-center"
                prefix={
                  <button type="submit" tw="-mx-3 h-full w-full flex-1 px-3">
                    <CheckIcon tw="h-5 w-5 text-neutral-400" />
                  </button>
                }
              />
    
    Error: 
      x tw attribute already exists, ignoring
        ,----
     61 | <button type="submit" tw="-mx-3 h-full w-full flex-1 px-3">
        :                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        `----
    
    Error: 
      > previous encountered here
        ,----
     59 | tw="flex h-[20px] items-center"
        :    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        `----
    
    released 
    opened by arlyon 1
  • Support for emotion components

    Support for emotion components

    It would be nice if we could transform tw.div as well as tw(Container) style directives into the equivalent statements:

    const Box = tw.div`text-red-500`;
    const BoxExtended = tw(Box)`bg-blue-500`;
    ---
    const Box = _styled.div({
        "--tw-text-opacity": "1",
        color: "rgb(239 68 68 / var(--tw-text-opacity))"
    });
    const BoxExtended = _styled(Box)({
        "--tw-bg-opacity": "1",
        backgroundColor: "rgb(59 130 246 / var(--tw-bg-opacity))"
    });
    
    opened by arlyon 1
  • support for styled-components

    support for styled-components

    hey, https://github.com/ben-rogerson/twin.macro/discussions/516#discussioncomment-4032968 the styled-components support would be really appreciated 🙏

    opened by koniuszy 1
  • Issue in example

    Issue in example

    Hi there, thanks for the addon i will be testing it but i noticed there is a small error with the node sample there is a " missing after staliwc

    /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, swcMinify: true, experimental: { swcPlugins: **[["stailwc", {}]],** }, compiler: { emotion: true, }, };

    opened by nimbit-software 1
  • Styled components support

    Styled components support

    This enables styled-components support with stailwc, bar the injected global styles due. For more info, see https://github.com/swc-project/swc/issues/6233#issuecomment-1363806515

    Closes #11 Closes #22

    opened by arlyon 0
  • The automated release is failing 🚨

    The automated release is failing 🚨

    :rotating_light: The automated release from the master branch failed. :rotating_light:

    I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

    You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

    Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

    Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

    If you are not sure how to resolve this, here are some links that can help you:

    If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


    Unable to build workspace dependencies graph: Unable to parse the workspace structure starting at /home/runner/work/stailwc/stailwc/Cargo.toml

    Unfortunately this error doesn't have any additional information. Feel free to kindly ask the author of the @semantic-release/exec plugin to add more helpful information.


    Good luck with your project ✨

    Your semantic-release bot :package::rocket:

    semantic-release 
    opened by arlyon 0
  • The automated release is failing 🚨

    The automated release is failing 🚨

    :rotating_light: The automated release from the master branch failed. :rotating_light:

    I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

    You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

    Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

    Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

    If you are not sure how to resolve this, here are some links that can help you:

    If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


    Unfortunately this error doesn't have any additional information. Feel free to kindly ask the author of the @semantic-release/exec plugin to add more helpful information.


    Good luck with your project ✨

    Your semantic-release bot :package::rocket:

    semantic-release 
    opened by arlyon 0
  • Get rid of global style workarounds

    Get rid of global style workarounds

    Right now for both global styles and emotion styles we rely on some ugly workarounds to handle some 'odd' behaviour from SWC which is described in this comment: https://github.com/swc-project/swc/issues/6233#issuecomment-1363806515. Our only recourse is to sit and wait until they are resolved upstream.

    opened by arlyon 0
  • Benchmarks and profiling

    Benchmarks and profiling

    This library has been written with the goal of doing as few allocations as possible however there are probably plenty for performance / speed gains to be had still. As an idea for potential pitfalls:

    • creating too many intermediate ObjectLit
    • inefficient config loading (parse and allocate the json config per file)
    • inefficient parsing
    • inefficient match for finding commands (rust_phf?)

    I would like to build out flamegraphs for the snapshot tests to determine larger-than-expected execution times as well as run benchmarks on those to track perf over time.

    opened by arlyon 0
  • Handle negatives correctly for transform

    Handle negatives correctly for transform

    Currently -transform-x-full transpiles to transform: -translateX(100%) while the correct value is translateX(-100%). Solution is likely to have the plugin operate on the entire Subject rather than just the Literal.

    opened by arlyon 0
Releases(0.11.0)
Owner
Alexander Lyon
I love making great teams build things quickly. You can usually find me working on tooling / libraries.
Alexander Lyon
[SWC plugin] workaround for jest

[SWC plugin] workaround for jest This is a SWC plugin to handle jest compatibility issues. This SWC plugin should be used with @swc/jest. usage instal

magic-akari 17 Dec 19, 2022
Automatically transform your Next.js Pages to use SuperJSON with SWC

?? NEXT SUPERJSON PLUGIN export default function Page({ date }) { return ( <div> Today is {date.toDateString()} </div> ) } // You c

⚡️Blitz 92 Jan 4, 2023
SWC plugin for transform Vue3-jsx syntax

swc-plugin-transform-vue3-jsx ?? SWC plugin for faster conversion vue3-jsx. Installation npm npm install swc-plugin-transform-vue3-jsx -D yarn yarn ad

null 4 Oct 19, 2022
A swc plugin that automatically converts React component libraries into "React Client Component"

A swc plugin that automatically converts React component libraries into "React Client Component". For example, you can automatically convert components from @mui into "React Client Component" without having to wrap a component that uses "use client".

xiaotian 3 Jul 12, 2023
Rust derive macros for automating the boring stuff.

derived: Macros for automating the boring stuff The derived crate provides macros that can simplify all the boring stuff, like writing constructors fo

Sayan 7 Oct 4, 2021
Helper macros: autoimpl, impl_scope

Impl-tools A set of helper macros Macros Autoimpl #[autoimpl] is a variant of #[derive], supporting: explicit generic parameter bounds ignored fields

null 38 Jan 1, 2023
Simple procedural macros `tnconst![...]`, `pconst![...]`, `nconst![...]` and `uconst![...]` that returns the type level integer from `typenum` crate.

typenum-consts Procedural macros that take a literal integer (or the result of an evaluation of simple mathematical expressions or an environment vari

Jim Chng 3 Mar 30, 2024
Experimental playground for wiktionary data

wikt Experimental playground for wiktionary data. This document might not update as often as the code does. Set up You'll want a minimum of 10 GB free

Félix Saparelli 8 Jul 9, 2022
An experimental programming language for exploring first class iterators.

An experimental programming language for exploring first class iterators.

Miccah 4 Nov 23, 2021
Experimental syntax for Rust

Osy.rs Experimental syntax for Rust Hey everyone, this readme needs work! The spec has been roughed out in Osy.rs_spec.alpha, but the file could be be

null 3 Dec 17, 2021
An experimental Rust crate for sigstore

Continuous integration Docs License This is an experimental crate to interact with sigstore. This is under high development, many features and checks

sigstore 89 Dec 29, 2022
Experimental Valve Index camera passthrough for Linux

Index camera passthrough Warning: This is still a work in progress, you could get motion sickness if you try it now The problem that the Index camera

yshui 22 Dec 1, 2022
Experimental Rust tool for generating FFI definitions allowing many other languages to call Rust code

Diplomat is an experimental Rust tool for generating FFI definitions allowing many other languages to call Rust code. With Diplomat, you can simply define Rust APIs to be exposed over FFI and get high-level C, C++, and JavaScript bindings automatically!

null 255 Dec 30, 2022
An experimental implementation of Arc against Apache Datafusion

box This is an experimental repository to perform a proof of concept replacement of the Apache Spark executor for Arc with Apache DataFusion. This is

tripl.ai 1 Nov 26, 2021
An experimental RISC-V recompiler

WARNING: All of this code is highly experimental and is a direct result of a two day hacking binge fueled by a truckload of tea. It's definitely not s

Koute 13 Apr 2, 2023
An experimental Athena extension for DuckDB 🐤

DuckDB Athena Extension WARNING This is a work in progress - things may or may not work as expected ??‍♂️ Limitations Only the default database is sup

Damon P. Cortesi 34 Apr 3, 2023
Js-macros - Quickly prototype Rust procedural macros using JavaScript or TypeScript!

js-macros Quickly prototype Rust procedural macros using JavaScript or TypeScript! Have you ever thought "this would be a great use case for a procedu

null 15 Jun 17, 2022
The first cesil transpiler/compiler in 50 years!

CesilC CESIL, or Computer Education in Schools Instruction Language, is a programming language designed to introduce pupils in British secondary schoo

null 5 Aug 6, 2022
Small ray tracer demo of the F# to Rust language transpiler in Fable 4.x

Small ray tracer demo of the F# to Rust language transpiler in Fable 4.x

null 45 Nov 16, 2022
A Huff <> bytecode transpiler

Murph - Transpile EVM bytecode into huff Murph can transpile this: 60003560e01c8063552410771461001c5780632096525514610023575b6004356000555b60005460005

Franfran 53 Feb 17, 2023