{"id":42269471,"url":"https://github.com/artemshitov/propmods","last_synced_at":"2026-01-27T07:12:04.375Z","repository":{"id":65475932,"uuid":"70728065","full_name":"artemshitov/propmods","owner":"artemshitov","description":"Turn your React props and state into BEM modifiers","archived":false,"fork":false,"pushed_at":"2017-06-21T15:32:07.000Z","size":27,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-20T21:57:23.709Z","etag":null,"topics":["bem","bem-modifiers","classname","component-props","css","react"],"latest_commit_sha":null,"homepage":null,"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/artemshitov.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":"2016-10-12T18:15:58.000Z","updated_at":"2019-01-31T13:30:39.000Z","dependencies_parsed_at":"2023-01-25T06:15:18.351Z","dependency_job_id":null,"html_url":"https://github.com/artemshitov/propmods","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/artemshitov/propmods","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artemshitov%2Fpropmods","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artemshitov%2Fpropmods/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artemshitov%2Fpropmods/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artemshitov%2Fpropmods/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artemshitov","download_url":"https://codeload.github.com/artemshitov/propmods/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artemshitov%2Fpropmods/sbom","scorecard":{"id":209115,"data":{"date":"2025-08-11","repo":{"name":"github.com/artemshitov/propmods","commit":"04f2e51ef89ac3d3ad66e5fd7ea97f423a8af598"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"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":"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":"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":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"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":"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":"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":"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":"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":"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":"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":"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":"Vulnerabilities","score":0,"reason":"13 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-h6ch-v84p-w6p9","Warn: Project is vulnerable to: GHSA-qh2h-chj9-jffq","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w9mr-4mfr-499f","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-662x-fhqg-9p8v","Warn: Project is vulnerable to: GHSA-394c-5j6w-4xmx","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3"],"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-17T00:23:57.782Z","repository_id":65475932,"created_at":"2025-08-17T00:23:57.782Z","updated_at":"2025-08-17T00:23:57.782Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28807556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T06:25:51.065Z","status":"ssl_error","status_checked_at":"2026-01-27T06:25:50.640Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["bem","bem-modifiers","classname","component-props","css","react"],"created_at":"2026-01-27T07:12:03.820Z","updated_at":"2026-01-27T07:12:04.371Z","avatar_url":"https://github.com/artemshitov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Propmods\n\nPropmods is a low-boilerplate way to BEM-annotate your React components. Propmods keeps your JSX clean by turning component props and state into BEM modifiers automatically.\n\n```js\nimport * as React from 'react';\nimport block from 'propmods';\n\nconst b = block('button');\n\nclass Button extends React.Component {\n    render() {\n        return \u003cbutton {...b(this)}\u003e\n            \u003ci {...b('icon', ['fa', 'fa-hand-pointer-o'])} /\u003e\n            {this.props.children}\n        \u003c/button\u003e;\n    }\n}\n\n\n// This React component:\n\u003cButton size=\"L\" theme=\"action\" blinking\u003ePush me!\u003c/Button\u003e\n\n// Turns into this DOM element:\n\u003cbutton class=\"button button_size_L button_theme_action button_blinking\"\u003e\n    \u003ci class=\"button__icon fa fa-hand-pointer-o\"\u003e\u003c/i\u003e\n    Push me!\n\u003c/button\u003e\n```\n\n## Install\n\nYarn:\n\n```\nyarn add propmods\n```\n\nNPM:\n\n```\nnpm install --save propmods\n```\n\n## Usage\n\nThis documentation assumes that you are using a modern JavaScript bundler like Webpack or Browserify, NPM package manager, and an ES2015 compiler (e.g. Babel).\n\nFirst, import Propmods and choose a block name:\n\n```js\nimport block from 'propmods';\nconst b = block('button');\n```\n\nIf you use CommonJS modules, you need to require `default` export:\n\n```js\nconst block = require('propmods').default;\nconst b = block('button');\n```\n\n### Blocks\n\nThe intended way to use Propmods is to call function `b` with your component as the argument and to merge results into the rendered component's props:\n\n```js\n\u003cbutton {...b(this)} /\u003e\n```\n\nPropmods will take your component's props and state, and will create appropriate classes. It is smart enough not to pick props which are not valid in CSS, so don't worry that a nested object or a page-long text gets into your class name.\n\nYou can also pass any other modifiers as arguments, or point directly to props, state or context if you don't wrap components into classes:\n\n```js\nconst Button = (props) =\u003e {\n    return \u003cbutton {...b({foo: 'bar'}, props)}\u003e{props.children}\u003c/button\u003e;\n};\n```\n\nYou can also mix in arbitrary classnames:\n\n```js\n\u003cbutton {...b(this, ['fancy-button', 'fancy-button-large'])} /\u003e\n```\n\n### Elements\n\nTo create BEM elements, pass the element's name as the first argument:\n\n```js\n\u003ci {...b('icon', {visible: false})} /\u003e\n```\n\n### Customization\n\n#### Q: What if I don't want all props to be used as modifiers?\n\nA: You can pick whatever props and state you like.\n\n```js\nimport * as _ from 'lodash';\n\n// ...\n\n\u003cbutton {...b(_.pick(this.props, ['size', 'theme']))} /\u003e\n```\n\n#### Q: JavaScript uses camel case in prop names, and I don't want camel case in my CSS. What do I do?\n\nA: Propmods will apply a case converting function if you supply one when creating your block.\n\n```js\nimport _ from 'lodash';\nconst b = block('button', {\n    transformKeys: _.kebabCase\n});\n```\n\n#### Q: I don't like your BEM conventions. Can I use my own BEM delimiters?\n\nA: Yes, you can configure Propmods to use any delimiters you prefer. These are the defaults:\n\n```js\nconst b = block('button', {\n    elementDelimiter: '__',\n    modDelimiter: '_',\n    modValueDelimiter: '_'\n});\n```\n\n#### Q: I don't want to pass these options each time\n\nA: Create a wrapped function and put it in a separate file in your project. For example:\n\n```js\n// lib/bem.js:\n\nimport block from 'propmods';\n\nconst options = {\n    // Your options\n}\n\nexport default function(name) {\n    return block(name, options);\n}\n\n\n// button.js:\n\nimport block from '../lib/bem';\n\nconst b = block('button');\n```\n\n### Typescript\n\nPropmods is written in Typescript and compiled down to ES5. This package already includes type declarations, so you can use it in your Typescript projects.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartemshitov%2Fpropmods","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartemshitov%2Fpropmods","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartemshitov%2Fpropmods/lists"}