{"id":16592287,"url":"https://github.com/quantizor/twyx","last_synced_at":"2025-07-08T11:05:52.517Z","repository":{"id":196047198,"uuid":"688975884","full_name":"quantizor/twyx","owner":"quantizor","description":"twyx is tailwind for CSS people","archived":false,"fork":false,"pushed_at":"2023-11-28T17:10:42.000Z","size":166,"stargazers_count":12,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-09T03:58:36.771Z","etag":null,"topics":["css","react","tailwind"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/s/playground-3zjdw6?file=/src/App.tsx","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quantizor.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"quantizor","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2023-09-08T14:01:34.000Z","updated_at":"2024-11-13T13:47:58.000Z","dependencies_parsed_at":"2023-09-21T05:12:27.216Z","dependency_job_id":"a3ce7e89-fc27-44b5-8704-317ef196aaf5","html_url":"https://github.com/quantizor/twyx","commit_stats":null,"previous_names":["probablyup/twyx","quantizor/twyx"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/quantizor/twyx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quantizor%2Ftwyx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quantizor%2Ftwyx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quantizor%2Ftwyx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quantizor%2Ftwyx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quantizor","download_url":"https://codeload.github.com/quantizor/twyx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quantizor%2Ftwyx/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264257663,"owners_count":23580469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","react","tailwind"],"created_at":"2024-10-11T23:20:13.766Z","updated_at":"2025-07-08T11:05:52.492Z","avatar_url":"https://github.com/quantizor.png","language":"TypeScript","funding_links":["https://github.com/sponsors/quantizor"],"categories":[],"sub_categories":[],"readme":"# twyx\n\n**_tailwind for css people_**\n\ntwyx is an abstraction on top of [tailwind](https://tailwindcss.com/) that seeks to make the framework more approachable to those that grew up with and/or prefer CSS syntax. It maps real CSS properties with the classes they target in a tiny wrapper. For more info on library design and tradeoffs, see [CONTRIBUTING](./CONTRIBUTING.md).\n\n### standalone\n\n```tsx\nimport { twyx } from \"twyx\";\n\nconst classes = twyx(\n  {\n    borderColor: \"red-500\",\n    borderStyle: { _: \"solid\", md: \"dashed\", dark: { _: \"dashed\", md: \"solid\" } },\n    borderWidth: 1,\n  },\n  \"additional classes here\",\n);\n\n// out:\n// classes === \"border border-solid md:border-dashed dark:border-dashed md:dark:border-solid border-red-500 additional classes here\"\n```\n\n### react\n\n`twyx/react` supports the [polymorphic \"as\" prop](https://www.robinwieruch.de/react-as-prop/) for dynamic composition of element as well as styling.\n\nYou can use the `twyx` function directly with `className` in React or try the `x` primitives.\n\n```tsx\nimport { twyx, x } from 'twyx/react'\n\n// option 1: twyx function\n\u003cdiv\n  className={twyx({\n    borderColor: 'red-500',\n    borderWidth: 1,\n    borerStyle: {\n      _:'solid',\n      md: 'dashed',\n      dark: {\n        _: 'dashed',\n        md: 'solid'\n      },\n    }\n  }, 'other classes if desired')}\n/\u003e\n\n// out\n// \u003cdiv className=\"border-red-500 border-solid md:border-dashed dark:border-dashed md:dark:border-solid other classes if desired\" /\u003e\n\n// option 2: x.* primitives\n\u003cx.div as=\"p\" className=\"other classes if desired\" borderColor=\"red-500\" borderStyle={{_: 'solid', md: 'dashed', dark: {_:'dashed', md:'solid'}}} borderWidth={1} /\u003e\n\n// out\n// \u003cp className=\"border-red-500 border-solid md:border-dashed dark:border-dashed md:dark:border-solid border other classes if desired\" /\u003e\n```\n\n\u003e _Why \"x\"?_ twyx was inspired by [xstyled](https://xstyled.dev/), a prop-contemporary focusing on the styled-components ecosystem. Great artists steal, h/t to @gregberge :bow:\n\n## install\n\n```sh\nbun add twyx\n```\n\nIf you are using one of the supported framework(s) below, any additional dependencies are listed.\n\n| framework | install command                           |\n| --------- | ----------------------------------------- |\n| react     | `bun add react; bun add -D @types/react;` |\n\n### configure tailwind to use the twyx transformer\n\ntwyx is able to autogenerate tailwind classes at build time using a custom transformer. Follow the example below and hook up the transformer to any file types where twyx usage occurs.\n\n```ts\n// tailwind.config.ts\n\nimport type { Config } from \"tailwindcss\";\nimport { transformTwyxProps } from \"twyx/transformer\";\n\nexport default {\n  content: {\n    files: [\n      /* file glob patterns that might contain tailwind syntax */\n    ],\n    transform: {\n      js: transformTwyxProps,\n      jsx: transformTwyxProps,\n      tsx: transformTwyxProps,\n    },\n  },\n} as Config;\n```\n\n## usage\n\nAll the normal rules of tailwind still apply, namely templating class names is strictly forbidden.\n\n\u003cstrong style=\"color: limegreen\"\u003edo\u003c/strong\u003e\n\n```ts\ntwyx({\n  borderColor: condition ? \"green-200\" : \"green-500\",\n  color: \"red-500\",\n});\n```\n\n\u003cstrong style=\"color: red\"\u003edon't\u003c/strong\u003e\n\n```ts\ntwyx({\n  borderColor: `green-${condition ? 200 : 500}`,\n});\n```\n\n\u003e **Why?** Tailwind runs a simple scanner over files to determine if classes it knows about are in use. If you write\n\u003e conditional styles in such a way that the whole string is not present at build time, the scanner will not work and\n\u003e the class will not be generated unless you [manually safelist](https://tailwindcss.com/docs/content-configuration#safelisting-classes) it.\n\n### extending twyx\n\nIf you add additional tailwind utility classes in your project and want them to be picked up by twyx autocomplete, you'll need to do perform a module augmentation like so:\n\n```ts\ndeclare module \"twyx\" {\n  export namespace Twyx {\n    type CustomColors = ColorProps\u003c\"indigo\" | \"chartreuse\"\u003e;\n\n    export interface PropValues extends ColorProps\u003cBaseColors | BaseColorTransparencies\u003e, CustomColors {\n      aspectRatio: \"my-custom-value\";\n    }\n  }\n}\n```\n\nCustom values will be appended to the original type.\n\n### todo\n\n- [x] write some tests\n- [x] set up ci \u0026 changesets\n- [ ] figure out if it's possible to hook up Tailwind's nice VS Code extension autocomplete directly to twyx\n- [ ] website using astro (just wanna try it and see what's up)\n\n---\n\nThank you very much to the Tailwind team for creating a fantastic framework. This library is meant to act as a bridge for those that prefer the CSS-way of referring to things.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquantizor%2Ftwyx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquantizor%2Ftwyx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquantizor%2Ftwyx/lists"}