{"id":36539417,"url":"https://github.com/tinwatchman/grawlix","last_synced_at":"2026-01-12T05:38:52.704Z","repository":{"id":57253824,"uuid":"85797324","full_name":"tinwatchman/grawlix","owner":"tinwatchman","description":"Make the Internet swear like a cartoon","archived":false,"fork":false,"pushed_at":"2017-04-19T08:52:00.000Z","size":154,"stargazers_count":13,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-22T09:05:45.446Z","etag":null,"topics":["curse","cuss","filter","grawlix","obscene","obscenity","profanity","profanity-filter","regexp","swear","swearword","vulgar"],"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/tinwatchman.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":"2017-03-22T07:21:27.000Z","updated_at":"2023-12-01T10:50:33.000Z","dependencies_parsed_at":"2022-09-10T21:51:40.071Z","dependency_job_id":null,"html_url":"https://github.com/tinwatchman/grawlix","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tinwatchman/grawlix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinwatchman%2Fgrawlix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinwatchman%2Fgrawlix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinwatchman%2Fgrawlix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinwatchman%2Fgrawlix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinwatchman","download_url":"https://codeload.github.com/tinwatchman/grawlix/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinwatchman%2Fgrawlix/sbom","scorecard":{"id":887435,"data":{"date":"2025-08-11","repo":{"name":"github.com/tinwatchman/grawlix","commit":"235cd9629992b97c62953b813d5034a9546211f1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"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":"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":"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":"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":"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":"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":"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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":"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":"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"}}]},"last_synced_at":"2025-08-24T10:31:37.647Z","repository_id":57253824,"created_at":"2025-08-24T10:31:37.647Z","updated_at":"2025-08-24T10:31:37.647Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28335226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"online","status_checked_at":"2026-01-12T02:00:08.677Z","response_time":98,"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":["curse","cuss","filter","grawlix","obscene","obscenity","profanity","profanity-filter","regexp","swear","swearword","vulgar"],"created_at":"2026-01-12T05:38:52.037Z","updated_at":"2026-01-12T05:38:52.696Z","avatar_url":"https://github.com/tinwatchman.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"grawlix\n=======\n\u003e Make the Internet swear like a cartoon\n\n[![Build Status](https://travis-ci.org/tinwatchman/grawlix.svg?branch=master)](https://travis-ci.org/tinwatchman/grawlix)\n[![Dependency Status](https://gemnasium.com/tinwatchman/grawlix.svg)](https://gemnasium.com/tinwatchman/grawlix)\n[![Coverage Status](https://coveralls.io/repos/github/tinwatchman/grawlix/badge.svg?branch=master)](https://coveralls.io/github/tinwatchman/grawlix?branch=master)\n\n`grawlix` is a configurable `RegExp`-based profanity filter that swaps out obscene words for [grawlixes](https://en.wiktionary.org/wiki/grawlix) -- long strings of emoticons or typographical symbols often used to represent swearing in comic strips and cartoons. Primarily aimed at George Carlin's [\"Seven Dirty Words\"](https://en.wikipedia.org/wiki/Seven_dirty_words), the library's default filters have been [rigorously tested](https://github.com/tinwatchman/grawlix/blob/master/spec/filter-spec.js#L412) against potential false positives and [Scunthorpe problems](https://en.wikipedia.org/wiki/Scunthorpe_problem). It's highly extensible, allowing new words and grawlix styles to be easily added as needed.\n\nPlease note that, due to the subject matter, the `grawlix` source code may be considered **NSFW/Not Safe For Work**, depending on an individual reader's circumstances. To see the full list of the words the library currently targets, see [this file](https://github.com/tinwatchman/grawlix/blob/master/WORDS.json).\n\n## Installation\n\n```sh\nnpm install grawlix --save\n```\n\n## Usage\n\n```javascript\nvar grawlix = require('grawlix');\nvar censored = grawlix(text, { /* options go here */ }); // outputs '%!@*'\n```\n\nAlternately, if you prefer not having to pass in options with every call, you can also configure the library's default settings with the `setDefaults` method:\n\n```javascript\ngrawlix.setDefaults({\n  // set default options here\n});\n// options will apply to every call made after this point\nvar censored = grawlix(text); // outputs '@$^!#@%@!#'\n```\n\n### Options\n\n```javascript\ngrawlix.setDefaults({\n  style: 'ascii',\n  randomize: true,\n  filters: [],\n  allowed: [],\n  plugins: []\n});\n```\n\nFor even more options, see the [full API documentation](https://github.com/tinwatchman/grawlix/blob/master/docs/API.md).\n\n##### style\n\nType: `String` or `Object`\u003cbr\u003e\nDefault: `'ascii'`\n\nWhat style of grawlix the function should use when replacing curse words. To see the list of available styles, see the [Grawlix Styles](#styles) section below. To learn how to create your own styles, see the [full Styles documentation](https://github.com/tinwatchman/grawlix/blob/master/docs/STYLES.md).\n\n##### randomize\n\nType: `Boolean`\u003cbr\u003e\nDefault: `true`\n\nSets whether or not grawlixes should be built by randomly selecting from a list of characters, or taken directly from a map of fixed replacements. Ignored when using a single-character style.\n\n##### filters\n\nType: `Array`\u003cbr\u003e\nDefault: `[]`\n\nAn optional `Array` of objects, representing either new words that should be replaced or configuration options for existing filters. For more information on how to use this property, see [Adding New Filters](#adding_new_filters) below.\n\n##### allowed\n\nType: `Array`\u003cbr\u003e\nDefault: `[]`\n\nAn optional `Array` of strings, representing a whitelist of words that shouldn't be replaced. Passing in a word or list of words that's [targeted by default](https://github.com/tinwatchman/grawlix/blob/master/WORDS.json) will deactivate their associated filters.\n\nFor example -- the following code deactivates the filter `grawlix` uses to replace the word 'bastard':\n\n```javascript\nvar censored = grawlix(text, {\n  allowed: [ 'bastard' ]\n});\n```\n\n##### plugins\n\nType: `Array`\u003cbr\u003e\nDefault: `[]`\n\nAn optional `Array` of plugins to include. See [Using Plugins](#using_plugins) below for more details.\n\n\u003ca name=\"styles\"\u003e\u003c/a\u003e\n\n## Grawlix Styles\n\nSeven different styles of grawlixes are available within the library by default. The three primary styles are:\n\n+ `'ascii'`: the default style. Generates grawlixes from the following standard typographical symbols: `@!#$%^\u0026*`.\n+ `'dingbats'`: Generates grawlixes from this list of Unicode-only symbols: `★☒☎☠☢☣☹♡♢♤♧⚓⚔⚑⚡♯✓☝`.\n+ `'unicode'`: Generates grawlixes from this combined list of standard typographical and Unicode-only symbols: `!@#$%★☒☎☠☢☣☹♡♢♤♧⚓⚔⚑⚡`.\n\nIn addition, the following 'single-character' styles are also available:\n\n+ `'asterix'`: Replaces targeted words with asterixes, e.g. `*`.\n+ `'nextwave'`: Replaces targeted words with skull (`☠`) symbols. Requires Unicode support.\n+ `'redacted'`: Replaces targeted words with `█` symbols. Requires Unicode support.\n+ `'underscore'`: Replaces targeted words with underscores, e.g. `_`.\n\nTo use one of these styles, simply pass in the desired style's name in the `options` object:\n\n```javascript\nvar censored = grawlix(text, {\n  style: 'nextwave'\n});\n// outputs '☠☠☠☠☠☠'\n```\n\nFor information on advanced options, including on how to create new grawlix styles, see the [full Styles documentation](https://github.com/tinwatchman/grawlix/blob/master/docs/STYLES.md).\n\n\u003ca name=\"adding_new_filters\"\u003e\u003c/a\u003e\n\n## Adding New Filters\n\nTo ease the process of adapting to new demands (such as targeting obscene words not supported by default, or supporting languages other than English), `grawlix` accepts new filters via the `options` object. Let's say, for example, that you decide you want to prevent your forum users from discussing Unix's [File System Consistency ChecK](https://en.wikipedia.org/wiki/Fsck) tool. You can add a filter targeting the word to the library's default settings like so:\n\n```javascript\ngrawlix.setDefaults({\n  filters: [\n    {\n      word: 'fsck',\n      pattern: /fsck/i\n    }\n  ]\n});\n```\n\nFor more information on creating and configuring filters, see the [full Filters documentation](https://github.com/tinwatchman/grawlix/blob/master/docs/FILTERS.md).\n\n\u003ca name=\"using_plugins\"\u003e\u003c/a\u003e\n\n## Using Plugins\n\nPlugins are modules with additional functionality (such as new filters and styles) for `grawlix` that can be easily shared among developers. Here's a running list of the plugins that are currently available:\n\n+ [grawlix-racism](https://www.npmjs.com/package/grawlix-racism): targets racial and ethnic slurs.\n\nTo use a plugin, install the module into your project and pass it in as part of your `grawlix` options:\n\n```javascript\nvar plugin = require('grawlix-example-plugin-module');\ngrawlix.setDefaults({\n  plugins: [\n    {\n      plugin: plugin,\n      options: {\n        // plugin-specific options go here\n      }\n    }\n  ]\n});\n// or alternately\ngrawlix.loadPlugin(plugin, {\n  // plugin-specific options go here\n});\n```\n\nFor more information on plugins (including how to create your own), see the [full Plugin documentation](https://github.com/tinwatchman/grawlix/blob/master/docs/PLUGINS.md).\n\n## Testing\n\n```sh\nnpm test\n```\n\n## Contributing\n\nForks and pull requests welcome.\n\nDepending on community response, the following areas and/or features could potentially be explored in the future:\n\n- [ ] Default support for more curse words (depending on community needs)\n- [ ] Browser support\n- [ ] Internationalization / support for languages other than English\n- [ ] Regular expression optimization\n- [X] Plugin framework\n- [X] Improve test coverage for util.js\n\n## Release History\n\n- 1.0.6\n  * 100% complete test coverage achieved (as rated by [istanbul](https://www.npmjs.com/package/istanbul).)\n  * Added documentation on the [custom Error subclasses](https://github.com/tinwatchman/grawlix/blob/master/docs/ERRORS.md) thrown by the package.\n- 1.0.5\n  * Switched to using [style objects](https://github.com/tinwatchman/grawlix/blob/master/docs/STYLES.md#style-objects) for consistency.\n  * Different styles can now be set on individual filters. [See here](https://github.com/tinwatchman/grawlix/blob/master/docs/FILTERS.md#style) for details.\n  * New plugin: [grawlix-racism](https://github.com/tinwatchman/grawlix-racism)\n- 1.0.4\n  * First draft of plugin framework. Feedback would be appreciated.\n- 1.0.3\n  * Added `grawlix.isObscene` function as per the suggestion of /u/calsosta on [/r/node](https://www.reddit.com/r/node/).\n  * Removed tests from package as per [issue #1](https://github.com/tinwatchman/grawlix/issues/1).\n- 1.0.2\n  * Added digits to separator checks in filter regex patterns.\n\n## Credits and Licensing\n\nCreated by [Jon Stout](http://www.jonstout.net). Licensed under [the MIT license](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinwatchman%2Fgrawlix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinwatchman%2Fgrawlix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinwatchman%2Fgrawlix/lists"}