MCPcopy Index your code
hub / github.com/ben-rogerson/twin.macro

github.com/ben-rogerson/twin.macro @3.4.1 sqlite

repository ↗ · DeepWiki ↗ · release 3.4.1 ↗
188 symbols 734 edges 352 files 1 documented · 1% 18 cross-repo links
README

Twin examples Twin examples

The <em>magic</em> of Tailwind with the <em>flexibility</em> of css-in-js.




<a href="https://www.npmjs.com/package/twin.macro"><img src="https://img.shields.io/npm/dt/twin.macro.svg" alt="Total Downloads"></a>
<a href="https://www.npmjs.com/package/twin.macro"><img src="https://img.shields.io/npm/v/twin.macro.svg" alt="Latest Release"></a>
<a href="https://discord.gg/Xj6x9z7"><img src="https://img.shields.io/discord/705884695400939552?label=discord&logo=discord" alt="Discord"></a>






🌟 New: Twin v3 now includes full Tailwind plugin support and more

Release notes →

<a href="https://stackblitz.com/github/ben-rogerson/twin.examples/tree/master/webpack-emotion-typescript?file=src/App.tsx">
  <img
    alt="Open in StackBlitz"
    src="https://developer.stackblitz.com/img/open_in_stackblitz_small.svg"
  />
</a>

Style jsx elements using Tailwind classes:

import 'twin.macro'

const Input = () => <input tw="border hover:border-black" />

Nest Twin’s tw import within a css prop to add conditional styles:

import tw from 'twin.macro'

const Input = ({ hasHover }) => (
  <input css={[tw`border`, hasHover && tw`hover:border-black`]} />
)

Or mix sass styles with the css import:

import tw, { css } from 'twin.macro'

const hoverStyles = css`
  &:hover {
    border-color: black;
    ${tw`text-black`}
  }
`
const Input = ({ hasHover }) => (
  <input css={[tw`border`, hasHover && hoverStyles]} />
)

Styled Components

You can also use the tw import to create and style new components:

import tw from 'twin.macro'

const Input = tw.input`border hover:border-black`

And clone and style existing components:

const PurpleInput = tw(Input)`border-purple-500`

Switch to the styled import to add conditional styling:

import tw, { styled } from 'twin.macro'

const StyledInput = styled.input(({ hasBorder }) => [
  `color: black;`,
  hasBorder && tw`border-purple-500`,
])
const Input = () => <StyledInput hasBorder />

Or use backticks to mix with sass styles:

import tw, { styled } from 'twin.macro'

const StyledInput = styled.input`
  color: black;
  ${({ hasBorder }) => hasBorder && tw`border-purple-500`}
`
const Input = () => <StyledInput hasBorder />

How it works

When babel runs over your javascript or typescript files at compile time, twin grabs your classes and converts them into css objects. These css objects are then passed into your chosen css-in-js library without the need for an extra client-side bundle:

import tw from 'twin.macro'

tw`text-sm md:text-lg`

// ↓ ↓ ↓ ↓ ↓ ↓

{
  fontSize: '0.875rem',
  '@media (min-width: 768px)': {
    fontSize: '1.125rem',
  },
}

Features

👌 Simple imports - Twin collapses imports from common styling libraries into a single import:

- import styled from '@emotion/styled'
- import css from '@emotion/react'
+ import { styled, css } from 'twin.macro'

🐹 Adds no size to your build - Twin converts the classes you’ve used into css objects using Babel and then compiles away, leaving no runtime code

🍱 Apply variants to multiple classes at once with variant groups

import 'twin.macro'

const interactionStyles = () => (



)

const mediaStyles = () => 



const pseudoElementStyles = () => 



const stackedVariants = () => 



const groupsInGroups = () => 


🛎 Helpful suggestions for mistypings - Twin chimes in with class and variant values from your Tailwind config:

✕ ml-1.25 was not found

Try one of these classes:

- ml-1.5 > 0.375rem
- ml-1 > 0.25rem
- ml-10 > 2.5rem

🖌️ Use the theme import to add values from your tailwind config

import { css, theme } from 'twin.macro'

const Input = () => <input css={css({ color: theme`colors.purple.500` })} />

See more examples using the theme import →

💡 Works with the official tailwind vscode plugin - Avoid having to look up your classes with auto-completions straight from your Tailwind config - setup instructions →

💥 Add !important to any class with a trailing or leading bang!



 || 


// ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓



Add !important to multiple classes with bracket groups:




// ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓



Get started

Twin works with many modern stacks - take a look at these examples to get started:

App build tools and libraries

  • Parcel

styled-components / emotion / emotion (ts) - Webpack

styled-components (ts) / emotion (ts) - Preact

styled-components / emotion / goober - Create React App

styled-components / emotion - Vite

styled-components (ts) / emotion (ts) / solid (ts) 🎉 - Jest / React Testing Library

styled-components (ts) / emotion (ts)

Advanced frameworks

  • Next.js

styled-components / styled-components (ts) / emotion / emotion (ts) / stitches (ts) - T3 App

styled-components (ts) 🎉 / emotion (ts) 🎉 - Blitz.js

emotion (ts) - Gatsby

styled-components / emotion

Component libraries

  • Storybook

styled-components (ts) / emotion / emotion (ts) 🎉 - yarn/npm workspaces + Next.js + shared ui components

styled-components - Yarn workspaces + Rollup

emotion - HeadlessUI (ts)

Community

Drop into our Discord server for announcements, help and styling chat.

Discord

Resources

Special thanks

This project stemmed from babel-plugin-tailwind-components so a big shout out goes to Brad Cornes for the amazing work he produced. Styling with tailwind.macro has been such a pleasure.

Extension points exported contracts — how you extend this code

TwStyle (Interface)
(no doc)
types/index.d.ts
RecursiveKeyValuePair (Interface)
(no doc)
src/core/types/index.ts
JSONObject (Interface)
(no doc)
src/suggestions/lib/getPackageVersions.ts
Matchers (Interface)
(no doc)
tests/types/types.d.ts
DOMAttributes (Interface)
(no doc)
types/index.d.ts
HTMLAttributes (Interface)
(no doc)
types/index.d.ts
IntrinsicAttributes (Interface)
(no doc)
types/index.d.ts

Core symbols most depended-on inside this repo

toMatchFormattedJavaScript
called by 147
tests/types/types.d.ts
run
called by 147
tests/util/run.ts
color
called by 75
tests/__fixtures__/colorFunctions/tailwind.config.js
half
called by 20
tests/__fixtures__/pluginGapFallback/tailwind.config.js
addVariant
called by 18
tests/__fixtures__/pluginExamples/tailwind.config.js
toMatchFormattedError
called by 12
tests/types/types.d.ts
addComponents
called by 11
tests/__fixtures__/pluginExamples/tailwind.config.js
getDirectReplacement
called by 10
src/macro/screen.ts

Shape

Function 179
Interface 7
Method 2

Languages

TypeScript100%

Modules by API surface

src/macro/lib/astHelpers.ts22 symbols
src/macro/globalStyles.ts9 symbols
src/core/extractRuleStyles.ts9 symbols
tests/__fixtures__/!properties.tsx7 symbols
src/macro/screen.ts7 symbols
src/core/lib/convertClassName.ts7 symbols
tests/__fixtures__/plugins/tailwind.config.js6 symbols
tests/__fixtures__/pluginExamples/tailwind.config.js6 symbols
src/core/getStyles.ts6 symbols
src/core/createCoreContext.ts6 symbols
src/core/lib/logging.ts5 symbols
types/index.d.ts4 symbols

Dependencies from manifests, versioned

@babel/cli7.19.3 · 1×
@babel/plugin-syntax-jsx7.18.6 · 1×
@babel/preset-typescript7.18.6 · 1×
@babel/template7.22.15 · 1×
@emotion/react11.10.5 · 1×
@emotion/styled11.10.5 · 1×
@tailwindcss/aspect-ratio0.4.2 · 1×
@tailwindcss/container-queries0.1.0 · 1×
@tailwindcss/forms0.5.3 · 1×
@tailwindcss/typography0.5.7 · 1×
@types/babel-plugin-macros2.8.5 · 1×
@types/didyoumean1.2.0 · 1×

For agents

$ claude mcp add twin.macro \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact