{"id":8877368,"url":"https://github.com/typicode/mistcss","last_synced_at":"2025-05-15T15:04:53.616Z","repository":{"id":224622279,"uuid":"763157777","full_name":"typicode/mistcss","owner":"typicode","description":"Create visual components for React without JavaScript or TypeScript.  Leverage native HTML and CSS. It's an alternative to CSS-in-JS and CSS modules.","archived":false,"fork":false,"pushed_at":"2025-01-08T11:04:51.000Z","size":12407,"stargazers_count":1396,"open_issues_count":1,"forks_count":37,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-05-12T09:26:59.087Z","etag":null,"topics":["css","css-in-js","next","nextjs","react","remix","remix-run","styling"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/typicode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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,"zenodo":null},"funding":{"github":"typicode"}},"created_at":"2024-02-25T17:52:23.000Z","updated_at":"2025-05-11T11:53:27.000Z","dependencies_parsed_at":"2024-04-01T13:30:00.538Z","dependency_job_id":"467211ee-5aa1-4700-a733-ef8746081ca1","html_url":"https://github.com/typicode/mistcss","commit_stats":{"total_commits":109,"total_committers":9,"mean_commits":12.11111111111111,"dds":"0.15596330275229353","last_synced_commit":"77770552825f09d971aac0c0bcb7cd413878b356"},"previous_names":["typicode/mistcss"],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Fmistcss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Fmistcss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Fmistcss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typicode%2Fmistcss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/typicode","download_url":"https://codeload.github.com/typicode/mistcss/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254364270,"owners_count":22058878,"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","css-in-js","next","nextjs","react","remix","remix-run","styling"],"created_at":"2024-05-01T07:02:43.086Z","updated_at":"2025-05-15T15:04:53.597Z","avatar_url":"https://github.com/typicode.png","language":"JavaScript","readme":"# MistCSS\n\n\u003e Simplicity is the ultimate sophistication\n\nMistCSS lets you create reusable visual components without JavaScript or TypeScript (_think about it for a second... no JS/TS needed_).\n\nLeverage native HTML and CSS, get type safety and autocomplete. Just clean and efficient styling.\n\n\u003cimg width=\"1116\" alt=\"Screenshot 2024-11-01 at 03 47 44\" src=\"https://github.com/user-attachments/assets/74aea071-be00-4d03-b43a-e46d6282e4b5\"\u003e\n\n_What you see above is standard HTML ([data-attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*)) and CSS ([nested CSS](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting)). MistCSS simply creates a `d.ts` file based on your CSS._\n\n## Features\n\n- 🥶 Not just zero-runtime, it goes beyond. It's zero JavaScript, not even for components, resulting in smaller bundles and faster code.\n- 💎 What you write is what you get. No transformations, easy debugging.\n- 🎒 Standards-based, reusable styles across frameworks, compatible with Tailwind or any CSS framework\n- ⚡️ Instantly productive, no learning curve, simple on-boarding.\n- 💖 Back to basics with a modern twist: access the full power of HTML and CSS, enhanced with type safety and code completion (without the complexity).\n\n## Differences\n\n|                      | CSS-in-JS                              | MistCSS                       |\n| -------------------- | -------------------------------------- | ----------------------------- |\n| Runtime              | `~0-10 KB`                             | `0 KB`                        |\n| JavaScript functions | `a few KB per component`               | `0 KB`                        |\n| TypeScript code      | `yes (at least for props)`             | `no (generated for the user)` |\n| Debugging            | `react devtools`                       | `browser inspector`           |\n| Syntax highlighting  | `depends (may require extension)`      | `no additional extension`     |\n| Generated bundle     | `runtime + JS functions + logic + CSS` | `CSS`                         |\n\n_This is general comparison and may vary depending on the library you're using._\n\n## Usage\n\nTraditional approaches require wrapping your markup/styles in JavaScript functions (`Button.tsx` → `\u003cbutton/\u003e`, `Input.tsx` → `\u003cinput/\u003e`, ...), defining props with TypeScript types, and writing logic to manage class names.\n\nWith MistCSS, styling is straightforward and minimal. Here’s how it looks:\n\n`mist.css`\n\n```css\nbutton {\n  border-radius: 1rem;\n  padding: 1rem;\n  background: lightgray;\n\n  \u0026[data-variant='primary'] {\n    background-color: black;\n    color: white;\n  }\n\n  \u0026[data-variant='secondary'] {\n    background-color: grey;\n    color: white;\n  }\n}\n```\n\n`Page.tsx`\n\n```jsx\n\u003c\u003e\n  \u003cbutton data-variant=\"primary\"\u003eSave\u003c/button\u003e\n\n  {/* TS error, tertiary isn't valid */}\n  \u003cbutton data-variant=\"tertiary\"\u003eSave\u003c/button\u003e\n\u003c/\u003e\n```\n\nOutput\n\n```jsx\n\u003cbutton data-variant=\"primary\"\u003eSave\u003c/button\u003e {/* Same as in Page.tsx */}\n```\n\n_This example demonstrates enums, but MistCSS also supports boolean and string props. For more details, see the FAQ._\n\n## How does it work?\n\nMistCSS parses your `mist.css` file and generates `mist.d.ts` for type safety.\n\nFor instance, here’s the generated `mist.d.ts` for our button component:\n\n\u003c!-- prettier-ignore-start --\u003e\n```typescript\ninterface Mist_button extends React.DetailedHTMLProps\u003cReact.HTMLAttributes\u003cHTMLButtonElement\u003e, HTMLButtonElement\u003e {\n  'data-variant'?: 'primary' | 'secondary'\n}\n\ndeclare namespace JSX {\n  interface IntrinsicElements {\n    button: Mist_button // ← \u003cbutton/\u003e is extended at JSX level to allow 'primary' and 'secondary' values\n  }\n}\n```\n\u003c!-- prettier-ignore-stop --\u003e\n\nThat’s it! Simple yet powerful, built entirely on browser standards and TypeScript/JSX.\n\n## Install\n\n```sh\nnpm install mistcss --save-dev\n```\n\n`postcss.config.js`\n\n```js\nmodule.exports = {\n  plugins: {\n    mistcss: {},\n  },\n}\n```\n\n`layout.tsx`\n\n```ts\nimport './mist.css'\n```\n\n## FAQ\n\n### Can I use CSS frameworks like Tailwind or Open Props?\n\nAbsolutely, MistCSS is pure HTML and CSS, generating only `mist.d.ts`, so there are no limitations. You can integrate any CSS framework seamlessly. Here are a few examples to get you started:\n\n\u003e [!IMPORTANT]\n\u003e For the best experience, set up Tailwind IntelliSense in your editor. Refer to [Tailwind's editor setup guide](https://tailwindcss.com/docs/editor-setup).\n\n#### Tailwind v3 ([@apply](https://tailwindcss.com/docs/functions-and-directives#apply))\n\n```css\nbutton {\n  @apply bg-blue-500 text-white;\n  /* ... */\n}\n```\n\n#### Tailwind v3 ([theme](https://tailwindcss.com/docs/functions-and-directives#theme))\n\n```css\nbutton {\n  background: theme(colors.blue.500);\n  /* ... */\n}\n```\n\n#### Tailwind v4\n\nTailwind v4 will support CSS variables natively (see [blog post](https://tailwindcss.com/blog/tailwindcss-v4-alpha)).\n\n#### Tailwind (inline style)\n\nTo override some styles, you can use `className`\n\n```jsx\n\u003cbutton data-variant=\"primary\" className=\"p-12\"\u003e\n  Save\n\u003c/button\u003e\n```\n\n#### Open Props\n\n```css\nbutton {\n  background-color: var(--blue-6);\n  /* ... */\n}\n```\n\n### Can I do X without JavaScript?\n\nCSS is more powerful than ever, before reaching for JS, explore if native CSS features can accomplish what you need.\n\n### Can I write `\u003cname\u003e` instead of `data-\u003cname\u003e`?\n\nNo, using `\u003cname\u003e` would result in invalid HTML. However, this constraint is actually advantageous.\n\nFirstly, it eliminates the risk of conflicts with native attributes:\n\n```jsx\n\u003c\u003e\n  \u003cButton type=\"primary\"\u003eSave\u003c/Button {/* Conflict with button's type=\"submit\" */}\n  \u003cbutton data-type=\"primary\"\u003eSave\u003c/button\u003e {/* Safe */}\n\u003c/\u003e\n```\n\nAdditionally, just by typing `data-` in your editor, autocomplete helps you clearly distinguish your custom attributes from standard tag attributes.\n\n### How to write enum, boolean, string props and conditions?\n\n```css\ndiv[data-component='section']\n  /* CSS variables */\n  --color: ...;\n\n  /* Default styles */\n  background: var(--color, green);\n  margin: ...;\n  padding: ...;\n\n  /* Enum props */\n  \u0026[data-size=\"sm\"] { ... }\n  \u0026[data-size=\"lg\"] { ... }\n\n  /* Boolean props */\n  \u0026[data-is-active] { ... }\n\n  /* Condition: size=\"lg\" \u0026\u0026 is-active */\n  \u0026[data-size=\"lg\"]\u0026[data-is-active] { ... }\n\n  /* Condition: size=\"lg\" \u0026\u0026 !is-active */\n  \u0026[data-size=\"lg\"]:not([data-is-active]) { ... }\n}\n```\n\n```jsx\n\u003cdiv\n  data-component=\"section\"\n  data-size=\"foo\"\n  data-is-active\n  style={{ '--color': 'red' }}\n/\u003e\n```\n\n### How to re-use the same tag?\n\nIf you want both basic links and button-styled links, here’s how you can do:\n\n```css\na:not([data-component]) { /* ... */ }\n\na[data-component='button'] {\n  \u0026[data-variant='primary'] { /* ... */ }\n}\n```\n\n\u003c!-- prettier-ignore-start --\u003e\n```jsx\n\u003c\u003e\n  \u003ca href=\"/home\"\u003eHome\u003c/a\u003e\n  \u003ca href=\"/home\" data-component=\"button\"\u003eHome\u003c/a\u003e\n  \u003ca href=\"/home\" data-component=\"button\" data-variant=\"primary\"\u003eHome\u003c/a\u003e\n\n  {/* TS error, `data-variant` is only valid with `data-component=\"button\"` */}\n  \u003ca href=\"/home\" data-variant=\"primary\"\u003eHome\u003c/a\u003e\n\u003c/\u003e\n```\n\u003c!-- prettier-ignore-stop --\u003e\n\n\u003e [!NOTE]\n\u003e `data-component` is just a naming convention. Feel free to use any attribute, like `data-kind='button'` or just `data-c`. It’s simply a way to differentiate between components using the same tag.\n\n### How to split my code?\n\nYou can use CSS [@import](https://developer.mozilla.org/en-US/docs/Web/CSS/@import). For example, in your `mist.css` file:\n\n```css\n@import './button.css';\n```\n\n### How to build complex components?\n\n`mist.css`\n\n```css\narticle[data-component='card'] {\n  /* ... */\n}\ndiv[data-component='card-title'] {\n  /* ... */\n}\ndiv[data-component='card-content'] {\n  /* ... */\n}\n```\n\n`Card.jsx`\n\n```jsx\nexport function Card({ title, children }) {\n  return (\n    \u003carticle data-component=\"card\"\u003e\n      \u003cdiv data-component=\"card-title\"\u003e{title}\u003c/div\u003e\n      \u003cdiv data-component=\"card-content\"\u003e{children}\u003c/div\u003e\n    \u003c/article\u003e\n  )\n}\n```\n\n\u003e [!TIP]\n\u003e To indicate that these styles aren't meant to be used outside of `Card`, you can name them `data-p-component` (`p` for `private`) or use another naming convention.\n\n### How to define CSS variables?\n\n```css\n:root {\n  --primary-color: #007bff;\n  --secondary-color: #6c757d;\n}\n\nbutton {\n  background: var(--primary-color)\n  /* ... */\n```\n\nSee also your CSS framework/tooling documentation for ways to define them in JS if you prefer.\n\n### How to Use MistCSS with an External UI?\n\nAssuming you have your UI components in a separate package `my-ui` and you're using Next.js, follow these steps:\n\n`app/layout.tsx`\n\n```tsx\nimport 'my-ui/mist.css'\n```\n\n`app/mist.d.ts`\n\n```typescript\nimport 'my-ui/mist.d.ts\n```\n\nThis setup ensures that your Next.js application correctly imports styles and type definitions from your external UI package. It may vary based on tools you're using, but the same principles should apply.\n\n### Origin of the project name?\n\nMist is inspired by atomized water 💧 often seen near waterfalls. A nod to the _Cascading_ in CSS 🌊.\n","funding_links":["https://github.com/sponsors/typicode"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypicode%2Fmistcss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftypicode%2Fmistcss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypicode%2Fmistcss/lists"}