{"id":20704218,"url":"https://github.com/michaelmang/tempera","last_synced_at":"2025-06-23T06:37:49.017Z","repository":{"id":53905479,"uuid":"342394497","full_name":"michaelmang/tempera","owner":"michaelmang","description":"A CLI toolkit for aiding design tokens adoption.","archived":false,"fork":false,"pushed_at":"2021-03-22T19:03:42.000Z","size":3000,"stargazers_count":25,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-19T06:12:21.833Z","etag":null,"topics":["design-tokens","oclif","postcss"],"latest_commit_sha":null,"homepage":"https://tempera.netlify.app","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/michaelmang.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}},"created_at":"2021-02-25T22:19:53.000Z","updated_at":"2024-02-16T16:14:32.000Z","dependencies_parsed_at":"2022-08-13T04:00:36.096Z","dependency_job_id":null,"html_url":"https://github.com/michaelmang/tempera","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelmang%2Ftempera","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelmang%2Ftempera/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelmang%2Ftempera/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelmang%2Ftempera/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelmang","download_url":"https://codeload.github.com/michaelmang/tempera/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249729437,"owners_count":21317097,"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":["design-tokens","oclif","postcss"],"created_at":"2024-11-17T01:11:24.190Z","updated_at":"2025-04-23T01:18:43.756Z","avatar_url":"https://github.com/michaelmang.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eTempera\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://tempera.netlify.app\"\u003e\n    \u003cimg alt=\"tempera\" src=\"https://dam-13749.kxcdn.com/wp-content/uploads/2017/01/simonetta-vespucci.jpg\" width=\"750\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  A CLI toolkit for aiding design tokens adoption.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://tempera.netlify.app\"\u003e\n    View Docs\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://oclif.io\"\u003e\u003cimg alt=\"Oclif\" src=\"https://img.shields.io/badge/cli-oclif-brightgreen.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://app.netlify.com/sites/tempera/deploys\"\u003e\u003cimg alt=\"Netlify Status\" src=\"https://api.netlify.com/api/v1/badges/733b8d33-26d3-4182-be30-388b8bc57737/deploy-status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://npmjs.org/package/tempera\"\u003e\u003cimg alt=\"Version\" src=\"https://img.shields.io/npm/v/tempera.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://npmjs.org/package/tempera\"\u003e\u003cimg alt=\"Downloads\" src=\"https://img.shields.io/npm/dw/tempera.svg\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/michaelmang/tempera/blob/master/package.json\"\u003e\u003cimg alt=\"Downloads\" src=\"https://img.shields.io/npm/l/tempera.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c!-- toc --\u003e\n\n- [Usage](#usage)\n- [Contributing](#contributing)\n- [Packages](#packages)\n\u003c!-- tocstop --\u003e\n\n# Usage\n\n\u003c!-- usage --\u003e\n\n## Install\n\n```sh-session\n$ npm install -g tempera\n$ yarn add global tempera\n```\n\n## Run Commands\n\n**Note:** This package is experimental. You may have better success by running the command locally:\n\n```sh-session\nUSAGE\n  $ git clone https://github.com/michaelmang/tempera.git\n  $ yarn install\n  $ ./bin/run [COMMAND]\n```\n\n### Scorecard\n\nGather metrics around the adoption of a design system.\n\n```sh-session\nUSAGE\n  $ tempera scorecard -s https://www.figma.com/developers -t ./tokens.js\n\nOPTIONS\n  -s, --site=site  site url to analyze\n  -t, --tokens=tokens  relative path to tokens file\n  -j, --json=json  (optional) flag to enable printing output as a JSON blob; requires -o, --output to be set\n  -o, --output=output  (optional) relative path for a JSON file to output; requires -j, --json to be enabled\n\nDESCRIPTION\n  ...\n  Scorecard analyzes a web app or web page,\n  collecting design system adoption metrics\n  and insights for adoption.\n```\n\n#### Tokens\n\nDesign tokens are key-value pairs that represent a specification (aka \"spec\") of a design system.\n\nIf you are new to design tokens, [here's a good place to start](https://www.michaelmang.dev/blog/introduction-to-design-tokens).\n\nTempera's `scorecard` command expects these tokens to be in the [javascript/es6 format which you can generate using Style Dictionary](https://amzn.github.io/style-dictionary/#/formats?id=javascriptes6) except exported as CommonJS modules.\n\nIn other words, flat CommonJS modules in PascalCase are expected.\n\nExample:\n\n```js\nmodule.exports.ColorBackgroundBase = \"#ffffff\";\nmodule.exports.ColorBackgroundAlt = \"#fcfcfcfc\";\n```\n\nSupport for tokens in ES6 format is on the roadmap.\n\nThe `scorecard` command expects the tokens to match against one of the following matchers after being transformed to kebab case:\n\n```js\nmodule.exports.BORDER_RADIUS = /border-radius/g;\nmodule.exports.BREAKPOINT = /max-width/g;\nmodule.exports.COLOR = /color/g;\nmodule.exports.DELAY = /delay/g;\nmodule.exports.DURATION = /duration/g;\nmodule.exports.FONT_FAMILY = /font-family/g;\nmodule.exports.FONT_SIZE = /font-size/g;\nmodule.exports.FONT_WEIGHT = /font-weight/g;\nmodule.exports.LINE_HEIGHT = /line-height/g;\nmodule.exports.SPACING = /margin|padding/g;\nmodule.exports.TIMING = /timing/g;\n```\n\n[You can learn more about the underlying `css-types` package that utilizes these matchers.](/docs/packages#css-types)\n\n#### Output\n\n![design-scorecard](https://user-images.githubusercontent.com/22566333/109745214-88341d80-7ba1-11eb-9df3-89a947b36b1d.png)\n\n#### JSON Report\n\nUseful for creating custom reporters and tooling.\n\n```sh-session\nUSAGE\n  $ tempera scorecard -s https://www.figma.com/developers -t ./tokens.js -j -o report.json\n```\n\n##### Output\n\n```javascript\n{\n  \"unofficial\": [\n    {\n      \"type\": \"border-radius\",\n      \"attribute\": \"border-radius\",\n      \"unofficialValue\": \"0.500rem\",\n      \"nearestOfficialValue\": \"0.375rem\"\n    },\n    // ...\n  ],\n  \"summary\": [\n    { \"category\": \"Font Family\", \"correct\": 0, \"incorrect\": 79, \"percentage\": \"0.00\" },\n    { \"category\": \"Color\", \"correct\": 159, \"incorrect\": 195, \"percentage\": \"44.92\" },\n    { \"category\": \"Font Size\", \"correct\": 73, \"incorrect\": 104, \"percentage\": \"41.24\" },\n    { \"category\": \"Spacing\", \"correct\": 264, \"incorrect\": 322, \"percentage\": \"45.05\" },\n    { \"category\": \"Max Width\", \"correct\": 1, \"incorrect\": 25, \"percentage\": \"3.85\" },\n    { \"category\": \"Line Height\", \"correct\": 112, \"incorrect\": 14, \"percentage\": \"88.89\" },\n    { \"category\": \"Border Radius\", \"correct\": 16, \"incorrect\": 13, \"percentage\": \"55.17\" },\n    { \"category\": \"Font Weight\", \"correct\": 78, \"incorrect\": 2, \"percentage\": \"97.50\" }\n  ],\n  \"total\": { \"correct\": 703, \"incorrect\": 754, \"percentage\": \"48.25\", \"grade\": \"F\" }\n}\n```\n\n### Help\n\n```sh-session\n$ tempera --help [COMMAND]\nUSAGE\n  $ tempera COMMAND\n```\n\n\u003c!-- usagestop --\u003e\n\n# Contributing\n\n🤠 Howdy, developer! Thanks for being willing to contribute!\n\n## Project setup\n\n1.  Fork and clone the repo\n2.  Run `yarn install` to install dependencies\n3.  Create a branch for your PR with `git checkout -b pr/your-branch-name`\n4.  Run `.bin/run/ [COMMAND]` in the root of the repo to run commands locally\n\n\u003e Tip: Keep your `master` branch pointing at the original repository and make\n\u003e pull requests from branches on your fork. To do this, run:\n\u003e\n\u003e ```\n\u003e git remote add upstream https://github.com/michaelmang/tempera.git\n\u003e git fetch upstream\n\u003e git branch --set-upstream-to=upstream/master master\n\u003e ```\n\n## Committing and Pushing changes\n\nThere are currently no tests but please document manual testing on PRs with your changes.\n\n## Help needed\n\nPlease checkout the [the open issues][issues].\n\nAlso, please watch the repo and respond to questions/bug reports/feature\nrequests! Thanks!\n\n[issues]: https://github.com/michaelmang/tempera/issues\n\n# Packages\n\n## Tools\n\nIn addition to a CLI, Tempera offers other tools to improve design tokens adoption.\n\n### stylelint-tokens\n\nA Stylelint plugin that helps avoid the adoption of unofficial design specifications.\n\n#### Installation\n\n```bash\nyarn add @tempera/stylelint-tokens\n```\n\n#### Usage\n\nInstall [Stylelint](https://stylelint.io/user-guide/get-started) and update your configuration file to utilize the plugin.\n\n```js\n// stylelint.config.js\nconst tokens = require(\"./fixtures/example-tokens\");\n\nmodule.exports = {\n  // ...\n  plugins: [\"@tempera/stylelint-tokens\"],\n  rules: {\n    \"@tempera/official-specs\": tokens,\n  },\n};\n```\n\n##### Tokens\nThe plugin expects these tokens to be in the [javascript/es6 format which you can generate using Style Dictionary](https://amzn.github.io/style-dictionary/#/formats?id=javascriptes6) except exported as CommonJS modules.\n\nIn other words, flat CommonJS modules in PascalCase are expected.\n\nExample:\n\n```js\nmodule.exports.ColorBackgroundBase = \"#ffffff\";\nmodule.exports.ColorBackgroundAlt = \"#fcfcfcfc\";\n```\n\nSupport for tokens in ES6 format is on the roadmap.\n\n[View the source](https://github.com/michaelmang/tempera/tree/master/packages/stylelint)\n\n## Supporting Packages\n\nThe underlying packages that support Tempera are publicly accessible.\n\nYou are welcome and encouraged to use these packages directly should you need a custom solution.\n\n🚀 [Contributing](/docs/contributing) to these packages is also welcome.\n\n### css-types\n\nUtilities to categorize your CSS.\n\n#### Installation\n\n```bash\nyarn add @tempera/css-types\n```\n\n#### Usage\n\n```js\nconst {\n  // Example: matchers.SPACING\n  // Contains a list of regex matchers to help match common types in CSS\n  matchers,\n  // example: getMatcher(postcssProperty)\n  // Returns a regex matcher fitting for the provided property\n  getMatcher,\n  // Example: types.SPACING\n  // Contains a list of common types in CSS\n  types,\n  // Example: getType(postcssProperty)\n  // Returns a common type fitting for the provided property\n  getType,\n} = require(\"@tempera/css-types\");\n```\n\n[View the source](https://github.com/michaelmang/tempera/tree/master/packages/css-types)\n\n### postcss-scorecard\n\nA PostCSS plugin that exposes hooks into design token adoption validation.\n\n#### Installation\n\n```bash\nyarn add @tempera/postcss-scorecard\n```\n\n#### Usage\n\n```js\nconst pxToRem = require(\"postcss-pxtorem\");\nconst expandShorthand = require(\"postcss-shorthand-expand\");\n\nawait postcss()\n  .use(pxToRem())\n  .use(expandShorthand)\n  .use(\n    scorecard({\n      onInvalid: (score) =\u003e {\n        // do something when CSS property is not an official spec\n      },\n      onValid: (score) =\u003e {\n        // do something when CSS property is an official spec\n      },\n      onFinished: () =\u003e {\n        // do something after validation finishes\n      },\n      specs, // the official design tokens\n    })\n  )\n  .process(css, { from: undefined });\n```\n\n##### Specs\nThe plugin expects these specs/tokens to be in the [javascript/es6 format which you can generate using Style Dictionary](https://amzn.github.io/style-dictionary/#/formats?id=javascriptes6) except exported as CommonJS modules.\n\nIn other words, flat CommonJS modules in PascalCase are expected.\n\nExample:\n\n```js\nmodule.exports.ColorBackgroundBase = \"#ffffff\";\nmodule.exports.ColorBackgroundAlt = \"#fcfcfcfc\";\n```\n\nSupport for tokens in ES6 format is on the roadmap.\n\n[View the source](https://github.com/michaelmang/tempera/tree/master/packages/postcss)\n\n### tailwind-config\n\nAn API that generates a Tailwind configuration from a set of design tokens.\n\n#### Installation\n\n```bash\nyarn add @tempera/tailwind-config\n```\n\n#### Usage\n\n```js\nimport getTailwindConfig from \"@tempera/tailwind-config\";\n\nconst tailwindConfig = getTailwindConfig(tokens);\n\n// do something with the tailwind config\n```\n\n##### Tokens\nThe plugin expects these specs/tokens to be in the [javascript/es6 format which you can generate using Style Dictionary](https://amzn.github.io/style-dictionary/#/formats?id=javascriptes6).\n\nIn other words, flat modules in PascalCase are expected.\n\nExample:\n\n```js\nexport const ColorPrimary = blue;\nexport const ColorSecondary = yellow;\n```\n\n[View the source](https://github.com/michaelmang/tempera/tree/master/packages/tailwind)\n\n### twind\n\nAn API that generates a Twind instance from a set of design tokens.\n\n#### Installation\n\n```bash\nyarn add @tempera/twind\n```\n\n#### Usage\n\n```js\nimport getTwind from \"@tempera/twind\";\n\nconst { tw } = getTwind(tokens);\n\nfunction Demo() {\n  return (\n    \u003cdiv className={tw`text-primary`}\u003e\n  );\n}\n```\n\n##### Tokens\nThe plugin expects these specs/tokens to be in the [javascript/es6 format which you can generate using Style Dictionary](https://amzn.github.io/style-dictionary/#/formats?id=javascriptes6).\n\nIn other words, flat modules in PascalCase are expected.\n\nExample:\n\n```js\nexport const ColorPrimary = blue;\nexport const ColorSecondary = yellow;\n```\n\n[View the source](https://github.com/michaelmang/tempera/tree/master/packages/twind/base)\n\n### stitches\n\nAn API that generates twind/style shapes from a set of design tokens.\n\n#### Demo\n[View On CodeSandbox](https://codesandbox.io/s/temperastitches-0ogls?file=/src/tokens.js)\n\n#### Installation\n\n```bash\nyarn add @tempera/stitches\n```\n\n#### Usage\n\n```js\nimport getStitches from '@tempera/stitches';\nimport getTwind from '@tempera/twind';\nimport { style } from 'twind/style';\n\nimport tokens from './tokens';\n\nconst stitches = getStitches(tokens);\n\nconst { tw } = getTwind(tokens);\n\nfunction Demo() {\n  const button = style(stitches.button);\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton className={tw(button())}\u003eBase Button\u003c/button\u003e\n      \u003cbutton className={tw(button({ variant: 'secondary' }))}\u003e\n        Secondary Button\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n##### Tokens\nThe plugin expects these specs/tokens to be in the [javascript/es6 format which you can generate using Style Dictionary](https://amzn.github.io/style-dictionary/#/formats?id=javascriptes6).\n\nIn other words, flat modules in PascalCase are expected.\n\nThe tokens should follow the following format:\n\n```js\n// base format\nexport const Component[COMPONENT]Base[LONGHAND_CSS_PROPERTY];\n\n// size format\nexport const Component[COMPONENT][SIZE][LONGHAND_CSS_PROPERTY];\n\n// variant format\nexport const Component[COMPONENT][VARIANT][UI_STATE][LONGHAND_CSS_PROPERTY];\n```\n\nExamples:\n\n```js\nexport const ComponentButtonBaseFontSize = '1rem';\nexport const ComponentButtonBaseColor = 'red';\nexport const ComponentButtonSmallFontSize = '0.75rem';\nexport const ComponentButtonSecondaryDefaultBackgroundColor = 'red';\nexport const ComponentButtonSecondaryDefaultColor = 'white';\nexport const ComponentButtonSecondaryDefaultFontSize = '0.875rem';\nexport const ComponentButtonSecondaryHoverFontSize = '0.75rem';\nexport const ColorPrimary = 'red';\nexport const ColorWhite = 'white';\nexport const FontSizeTiny = '0.75rem';\nexport const FontSizeSmall = '0.875rem';\nexport const FontSizeMedium = '1rem';\nexport const LineHeightTiny = '1rem';\nexport const LineHeightSmall = '1.25rem';\nexport const LineHeightMedium = '1.5rem';\n```\n\n[View the source](https://github.com/michaelmang/tempera/tree/master/packages/twind/stitches)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelmang%2Ftempera","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelmang%2Ftempera","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelmang%2Ftempera/lists"}