{"id":17088287,"url":"https://github.com/frenic/glitz","last_synced_at":"2025-10-08T12:03:10.734Z","repository":{"id":50972147,"uuid":"114497390","full_name":"frenic/glitz","owner":"frenic","description":"Lightweight CSS-in-JS library with high performance written in TypeScript","archived":false,"fork":false,"pushed_at":"2024-12-03T14:31:41.000Z","size":5593,"stargazers_count":46,"open_issues_count":9,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-10-03T15:09:48.867Z","etag":null,"topics":["css","css-in-js","react","style","typescript"],"latest_commit_sha":null,"homepage":"","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/frenic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2017-12-16T23:43:27.000Z","updated_at":"2025-05-14T11:44:15.000Z","dependencies_parsed_at":"2024-06-18T21:21:27.174Z","dependency_job_id":"6ca9699b-9810-44c3-a341-375d9eb28a4d","html_url":"https://github.com/frenic/glitz","commit_stats":{"total_commits":643,"total_committers":8,"mean_commits":80.375,"dds":0.2332814930015552,"last_synced_commit":"0897c25782c2d329a2a18f5f102ffe0af90eaf1d"},"previous_names":[],"tags_count":496,"template":false,"template_full_name":null,"purl":"pkg:github/frenic/glitz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frenic%2Fglitz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frenic%2Fglitz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frenic%2Fglitz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frenic%2Fglitz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frenic","download_url":"https://codeload.github.com/frenic/glitz/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frenic%2Fglitz/sbom","scorecard":{"id":411214,"data":{"date":"2025-08-11","repo":{"name":"github.com/frenic/glitz","commit":"f34b90d866cd9c871cf63c5dff5422979b78e89d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.9,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":1,"reason":"Found 3/25 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"61 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr","Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2","Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-pq67-2wwv-3xjx","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-hc6q-2mpp-qw7j","Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T22:45:15.721Z","repository_id":50972147,"created_at":"2025-08-18T22:45:15.721Z","updated_at":"2025-08-18T22:45:15.721Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278646783,"owners_count":26021512,"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","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","react","style","typescript"],"created_at":"2024-10-14T13:36:57.234Z","updated_at":"2025-10-08T12:03:10.696Z","avatar_url":"https://github.com/frenic.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# ![Glitz](https://github.com/frenic/glitz/raw/master/glitz.svg?sanitize=true)\n\nGlitz is a CSS-in-JS library that is strictly focused on:\n\n:zap: **Performance** by caching and avoiding unnecessary re-renders whenever possible\u003cbr\u003e\n:policeman: **Type safety** by TypeScript\u003cbr\u003e\n:balance_scale: **Lightweight** [![@glitz/core bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@glitz/core.svg?style=flat-square)](https://bundlephobia.com/result?p=@glitz/core) by keeping things simple\u003cbr\u003e\n:muscle: **Flexibility** by composition to avoid wrapping elements\u003cbr\u003e\n:fire: Official [**React** bindings](https://github.com/frenic/glitz/blob/master/packages/react/)\u003cbr\u003e\n\nAlong with other built-in features like:\n\n- Atomic CSS (and non-Atomic CSS)\n- Shorthand expansion\n- Pseudo selectors/elements\n- Attribute selectors\n- Fallback values\n- `@media` support\n- `@keyframes` support\n- `@font-face` support\n- Media query ordering\n- Server rendering\n- Vendor prefixing _(with `@glitz/transformers`)_\n- Number to unit conversion `10 -\u003e \"10px\"`_(with `@glitz/transformers`)_\n- Warnings and errors when things goes wrong in development _(with `@glitz/transformers`)_\n\n## Table of content\n\n- [Getting started](#getting-started)\n- [Features](#features)\n  - [Atomic](#atomic)\n  - [Pseudo selectors/elements](#pseudo-selectorselements)\n  - [Attribute selectors](#attribute-selectors)\n  - [Fallback values](#fallback-values)\n  - [Keyframes](#keyframes)\n  - [Font faces](#font-faces)\n  - [Media queries](#media-queries)\n  - [Browser compatibility](#browser-compatibility)\n- [React](#react)\n- [Server rendering](#server-rendering)\n- [Shorthand properties](#shorthand-properties)\n- [TypeScript](#typescript)\n  - [Unknown properties](#unknown-properties)\n  - [Add custom properties](#add-custom-properties)\n- [Transformers](#transformers)\n  - [All](#all)\n  - [Prefixer](#prefixer)\n  - [Number as length](#number-as-length)\n  - [DevTool](#devtool)\n- [API](#api)\n  - [`new GlitzClient(options?: Options)`](#new-glitzclientoptions-options)\n  - [`new GlitzServer(options?: Options)`](#new-glitzserveroptions-options)\n  - [Options](#options)\n  - [Helpers](#helpers)\n- [Playground](#playground)\n\n## Getting started\n\n```bash\n$ npm install @glitz/core @glitz/transformers\n```\n\nThe most basic implementation is really easy. You don't need any config or module loaders to get started.\n\n```ts\nimport { GlitzClient } from '@glitz/core';\nimport transformers from '@glitz/transformers';\nconst glitz = new GlitzClient({ transformer: transformers() });\n\nconst className = glitz.injectStyle({\n  color: 'green',\n});\n```\n\n## Features\n\n### Atomic\n\nEach declaration will be injected individually by default which means that declaration blocks are divided into as small atomic rules as possible before they are injected into a virtual style sheet using the [`CSSStyleSheet.insertRule()`](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule) method. This results in minimal output and maximum performance because each class becomes highly reusable.\n\n```ts\nconst className = glitz.injectStyle({\n  display: 'flex',\n  color: 'green',\n  // Will be injected as:\n  // .a {\n  //   display: flex;\n  // }\n  // .b {\n  //   color: green;\n  // }\n});\n```\n\nSo the next time you use `display: 'flex'` it will reuse `a` instead of injecting a new rule.\n\n_However, the side-effect of this is that you cannot guarantee the order of the CSS. That why it's recommended to always use longhand properties. More info about using [shorthand properties](#shorthand-properties) here. You're able to [disable this feature](#optionsatomic) but it's not recommended._\n\n### Pseudo selectors/elements\n\nYou define your pseudo selector or element as the property name, followed with the style you wish to have for that pseudo.\n\n```ts\nconst className = glitz.injectStyle({\n  ':hover': {\n    textDecoration: 'underline',\n    // You're also able to nest\n    ':after': {\n      content: '\"Don\\'t forget double quotes when doing this\"',\n    },\n  },\n});\n```\n\n### Attribute selectors\n\nYou define your attribute selector as the property name, followed with the style you wish to have for that element.\n\n```ts\nconst className = glitz.injectStyle({\n  '[disabled]': {\n    display: 'none',\n  },\n});\n```\n\n### Fallback values\n\nAn array of values will be injected as one rule.\n\n```ts\nconst className = glitz.injectStyle({\n  width: ['50%', 'fit-content'],\n  // Will be injected as:\n  // .a {\n  //   width: 50%;\n  //   width: fit-content;\n  // }\n});\n```\n\n### Keyframes\n\nThe `animationName` property injects the `@keyframes` declaration list and will be replaced by a unique name.\n\n```ts\nconst className = glitz.injectStyle({\n  animationName: {\n    // or animation: { name: { ...\n    from: {\n      color: 'red',\n    },\n    to: {\n      color: 'green',\n    },\n  },\n  // Will be injected as:\n  // .a {\n  //   animation-name: a;\n  // }\n  // @keyframes a {\n  //   from {\n  //     color: red;\n  //   }\n  //   to {\n  //     color: green;\n  //   }\n  // }\n});\n```\n\nThe name will be reused when an identical declaration list is used again.\n\n### Font faces\n\nThe `fontFamily` property injects the `@font-face` rule and will be replaced by a unique name.\n\n```ts\nconst className = glitz.injectStyle({\n  fontFamily: {\n    // or font: { family: { ...\n    fontFamily: '\"Custom Font\"',\n    fontStyle: 'normal',\n    fontWeight: 'normal',\n    src: \"url(https://domain.tld/path/to/font-regular.woff2) format('woff2')\",\n  },\n  // Will be injected as:\n  // .a {\n  //   font-family: \"Custom Font\";\n  // }\n  // @font-face {\n  //   font-family: \"Custom Font\";\n  //   font-style: normal;\n  //   font-weight: 400;\n  //   src: url(https://domain.tld/path/to/font.woff2) format('woff2');\n  // }\n});\n```\n\nThe font family name will be reused when an identical block is used again.\n\nYou're also able to use fallback values in combination with font faces.\n\n```ts\nconst className = glitz.injectStyle({\n  fontFamily: [\n    {\n      fontFamily: '\"Custom Font\"',\n      fontStyle: 'normal',\n      fontWeight: 'normal,\n      src: \"url(https://domain.tld/path/to/font-regular.woff2) format('woff2')\",\n    },\n    {\n      fontFamily: '\"Custom Font\"',\n      fontStyle: 'normal',\n      fontWeight: 'bold',\n      src: \"url(https://domain.tld/path/to/font-bold.woff2) format('woff2')\",\n    },\n    'sans-serif',\n  ],\n});\n```\n\n### Media queries\n\nYou can define any `@media` property as you like.\n\n```ts\nconst className = glitz.injectStyle({\n  '@media (min-width: 768px)': {\n    display: 'block',\n  },\n});\n```\n\n### Browser compatibility\n\nYou can apply `@supports` condition rules. These can be handy when using server side rendered CSS because `CSS.supports()` isn't available on the server.\n\n```ts\nconst className = glitz.injectStyle({\n  '@supports (display: grid)': {\n    display: 'grid',\n  },\n  '@supports not (display: grid)': {\n    display: 'flex',\n  },\n});\n```\n\n## React\n\nThe official [React bindings](https://github.com/frenic/glitz/blob/master/packages/react/) for Glitz are highly flexible and composable.\n\n## Server rendering\n\nThe difference between `GlitzServer` class and `GlitzClient` class is that `GlitzClient` inserts new rules into the DOM directly. Instead `GlitzServer` collects the rendered style as a string for you to put in the `\u003chead\u003e`. The client side will then hydrate the CSS and reuse it.\n\n- [API reference](#new-glitzserveroptions-options)\n- [Example implementation](https://github.com/frenic/glitz/blob/master/packages/react/#server-rendering)\n\n## Shorthand properties\n\nProblems mixing CSS shorthand and longhand properties are common with styling techniques like this and doesn't only affects Glitz. It often causes unexpected behaviors.\n\n```ts\nconst first = glitz.injectStyle({\n  marginLeft: 10,\n});\n\n// Bad\nconst second = glitz.injectStyle({\n  margin: 20,\n  marginLeft: 10, // \u003c- The order of the CSS will result in this never being applied as expected\n});\n\n// Good\nconst second = glitz.injectStyle({\n  marginTop: 20,\n  marginRight: 20,\n  marginBottom: 20,\n  marginLeft: 10,\n});\n```\n\nInstead of writing each longhand property separately, you're able to use objects with shorthand properties.\n\n```ts\n// Good\nconst second = glitz.injectStyle({\n  margin: {\n    top: 20,\n    right: 20,\n    bottom: 20,\n    left: 10,\n  },\n});\n```\n\nFor `margin`, `padding` and `border` there's some property aliases to make this easier:\n\n- `x` is an alias for `left` and `right`\n- `y` is an alias for `top` and `bottom`\n- `xy` is an alias for `left`, `right`, `top` and `bottom`\n\n```ts\n// Bad\nconst second = glitz.injectStyle({\n  padding: '10px 20px',\n  border: 'red solid 5px',\n});\n\n// Good\nconst second = glitz.injectStyle({\n  padding: {\n    y: 10,\n    x: 20,\n  },\n  border: {\n    xy: {\n      color: 'red',\n      style: 'solid',\n      width: 5,\n    },\n  },\n});\n```\n\nYou can see a complete [list of shorthand objects](https://github.com/frenic/glitz/blob/c1b547990e7d56764472045566127aa3a0831711/packages/type/index.d.ts#L23) here.\n\n## TypeScript\n\nYou don't need TypeScript to use Glitz. But if you do, everything is typed! Even CSS! This means you'll get autocompletion and warnings as you write.\n\n```ts\nconst className = glitz.injectStyle({\n  colour: 'white', // Type error on property\n  overflow: 'hide', // Type error on value\n});\n```\n\n### Unknown properties\n\nUnknown properties will fail to be able to notify you when there's a typo. This means that function-like pseudos (e.g. `:not(:first-child)`) and media query selectors will be considered unknown properties. For those, there's two helper functions ([`pseudo`](#pseudo) and [`media`](#media)) that will make the selectors valid.\n\n```ts\nimport { media, selector } from '@glitz/core';\n\nconst className = glitz.injectStyle({\n  ...media(\n    { minWidth: '768px' },\n    {\n      display: 'block',\n    },\n  ),\n  ...selector(':not(:first-child)', {\n    textDecoration: 'underline',\n  }),\n});\n```\n\n### Add custom properties\n\nYou can also extend the interface with custom CSS properties like CSS variables and other unknown properties using module augmentation.\n\n```ts\n// my-style.d.ts\nimport * as Glitz from '@glitz/core';\n\ndeclare module '@glitz/core' {\n  interface Properties {\n    // Add CSS property\n    mozOsxFontSmoothing?: string;\n\n    // Add CSS variable name\n    '--theme-color'?: string;\n\n    // Allow any other property\n    [property: string]: any;\n  }\n}\n```\n\n## Transformers\n\nStyles will be processed by transformers before they are injected. A transform function will receive a flat object with `string | number | Array\u003cstring | number\u003e` values and expects the same in return. Have in mind that the transformer will receive each unique declaration only ones. The same unique declaration will later use a cached result and will never again reach the transformer.\n\nThese are not built in by default because it gives the users the freedom of choice and makes it easier to adopt to other platforms in the future.\n\n### All\n\nThe `@glitz/transformers` module includes all official transformers:\n\n- [`@glitz/prefixer-transformer`](https://github.com/frenic/glitz/tree/master/packages/prefixer-transformer)\n- [`@glitz/length-transformer`](https://github.com/frenic/glitz/tree/master/packages/length-transformer)\n- [`@glitz/devtool-transformer`](https://github.com/frenic/glitz/tree/master/packages/devtool-transformer)\n\n```ts\nimport { GlitzClient } from '@glitz/core';\nimport transformers from '@glitz/transformers';\nconst glitz = new GlitzClient({ transformer: transformers() });\n```\n\n### Prefixer\n\nThe [`@glitz/prefixer-transformer`](https://github.com/frenic/glitz/tree/master/packages/prefixer-transformer) is basically just a TypeScript wrapper for [`inline-style-prefixer/static`](https://github.com/rofrischmann/inline-style-prefixer).\n\n```ts\nimport { GlitzClient } from '@glitz/core';\nimport prefixer from '@glitz/prefixer-transformer';\nconst glitz = new GlitzClient({ transformer: prefixer });\n\nconst className = glitz.injectStyle({\n  display: 'flex',\n  // Will be transformed into:\n  // {\n  //   display: [\n  //     '-webkit-box',\n  //     '-moz-box',\n  //     '-ms-flexbox',\n  //     '-webkit-flex',\n  //     'flex',\n  //   ],\n  // }\n});\n```\n\n### Number as length\n\nThe [`@glitz/length-transformer`](https://github.com/frenic/glitz/tree/master/packages/length-transformer) converts numbers to lengths for certain properties.\n\n```ts\nimport { GlitzClient } from '@glitz/core';\nimport numberToLength from '@glitz/length-transformer';\nconst glitz = new GlitzClient({ transformer: numberToLength });\n\nconst className = glitz.injectStyle({\n  height: 10,\n  width: [100, 'max-content'],\n  // Will be transformed into:\n  // {\n  //   height: '10px',\n  //   width: ['100px', 'max-content'],\n  // }\n});\n```\n\n### DevTool\n\nThe [`@glitz/devtool-transformer`](https://github.com/frenic/glitz/tree/master/packages/devtool-transformer) produces warnings and errors when something does wrong in development.\n\n```ts\nimport { GlitzClient } from '@glitz/core';\nimport devTool from '@glitz/devtool-transformer';\nconst glitz = new GlitzClient({ transformer: devTool });\n\nconst className = glitz.injectStyle({\n  width: 'calc(100)',\n  // Will warn that `width` was ignored by the browser due to an error (unit missing)\n});\n```\n\n## API\n\n### `new GlitzClient(options?: Options)`\n\nThe Glitz core class for browsers.\n\n#### `GlitzClient#injectStyle(style: Style)`\n\nReturns: `string`\n\nThe returned value contains the class names of the injected style.\n\n```tsx\nconst glitz = new GlitzClient();\nconst classNames = glitz.injectStyle({ fontWeight: 'bold' });\n```\n\n#### `GlitzClient#injectGlobals(globalStyle: { [tagName]: Style })`\n\nReturns: `void`\n\nInjects global styles.\n\n```tsx\nconst glitz = new GlitzClient();\nglitz.injectStyle({ p: { fontWeight: 'bold' } });\n```\n\n#### `GlitzClient#hydrate(css: string)`\n\nReturns: `void`\n\nManually hydrate external Glitz generated CSS.\n\n_Note that `\u003cstyle data-glitz\u003e` tags are hydrated automatically._\n\n### `new GlitzServer(options?: Options)`\n\nThe Glitz core class for servers.\n\n_Note that `options` must be identical to the one used with `GlitzClient`._\n\n#### `GlitzServer#injectStyle(style: Style)`\n\nReturns: `string`\n\nThe returned value contains the class names of the injected style.\n\n```tsx\nconst glitz = new GlitzServer();\nconst classNames = glitz.injectStyle({ fontWeight: 'bold' });\n```\n\n#### `GlitzServer#injectGlobals(globalStyle: { [tagName]: Style })`\n\nReturns: `void`\n\nInjects global styles.\n\n```tsx\nconst glitz = new GlitzServer();\nglitz.injectStyle({ p: { fontWeight: 'bold' } });\n```\n\n#### `GlitzServer#hydrate(css: string)`\n\nReturns: `void`\n\nManually hydrate external Glitz generated CSS.\n\n_Note that `\u003cstyle data-glitz\u003e` tags are hydrated automatically._\n\n#### `GlitzServer#getStyle(markup?: boolean)`\n\nReturns: `string`\n\nPlain CSS will be returned unless `markup` is set to `true` and it will return markup instead to render directly into `\u003chead\u003e`.\n\n### Options\n\n#### `options.identifier`\n\n```ts\nidentifier: string;\n```\n\nDefault: `\"glitz\"`\n\nThe dataset name that will be used to identify Glitz style elements.\n\n#### `options.transformer()`\n\n```ts\ntransformer(style: Properties): Properties\n```\n\nDefault: `undefined`\n\nStyles will be processed by transformers before they are injected. A transform function will receive a flat object with `string | number | Array\u003cstring | number\u003e` values and expects the same in return. Have in mind that the transformer will receive each unique declaration only ones. The same unique declaration will later use a cached result and will never again reach the transformer.\n\nOfficial transformers are:\n\n- [Vendor prefix](#prefixer) style\n- [Number to unit conversion](#number-as-length)\n- [Warnings and errors](#devtool) when things goes wrong in development\n\nTo use all the official transformers, use `@glitz/transformers`:\n\n```ts\nimport { GlitzClient } from '@glitz/core';\nimport transformers from '@glitz/transformers';\nconst glitz = new GlitzClient({ transformer: transformers() });\n```\n\n#### `options.mediaOrder()`\n\n```ts\nmediaOrder(a: string, b: string): number\n```\n\nDefault: `undefined`\n\nUnordered media style may sometimes cause some unwanted behavior. With this function you're able to sort the order of the injected media styles.\n\nIt's recommended that you create your own with the media queries you use.\n\n```ts\nimport { query } from '@glitz/core';\n\nconst mediaQueryOrder = [\n  query({minWidth: '320px'}),\n  query({minWidth: '768px'}),\n  ...\n];\n\nfunction mediaQuerySorter(a, b) {\n  const indexA = mediaQueryOrder.indexOf(a);\n  const indexB = mediaQueryOrder.indexOf(b);\n  return indexA - indexB;\n}\n\nconst glitz = new GlitzClient({ mediaOrder: mediaQuerySorter });\n```\n\nIt's also possible to use [`sort-css-media-queries`](https://github.com/dutchenkoOleg/sort-css-media-queries/) if you don't have a specific list of media queries.\n\n#### `options.prefix`\n\n```ts\nprefix: string;\n```\n\nDefault: `\"\"`\n\nPrefix all class names.\n\n### Helpers\n\n#### `selector()`\n\n```ts\nselector(selector: string, style?: Style): Style\n```\n\nValidates the pseudo rule. See [example](#unknown-properties).\n\n#### `media()`\n\n```ts\nmedia(query: Query | string, style?: Style): Style\n```\n\nParse and validate [`Query`](https://github.com/frenic/glitz/blob/master/packages/core/src/types/query.ts) or string into a valid media **rule**. See [example](#unknown-properties).\n\n#### `query()`\n\n```ts\nquery(query: Query): string\n```\n\nParse and validate [`Query`](https://github.com/frenic/glitz/blob/master/packages/core/src/types/query.ts) into a valid media query.\n\n## Playground\n\nTo play around with Glitz, just:\n\n```bash\n$ git clone https://github.com/frenic/glitz.git\n$ cd glitz\n$ npm install\n$ npm example\n```\n\nOpen http://localhost:1234 in your browser and edit the code in `packages/example`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrenic%2Fglitz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrenic%2Fglitz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrenic%2Fglitz/lists"}