- JavaScript 99.5%
- Dockerfile 0.5%
Generated automatically with structured sections (overview, project structure, installation, usage, contributing, license, repository links). Original README content preserved under "Original README". |
||
|---|---|---|
| bin | ||
| lib | ||
| test | ||
| .dockerignore | ||
| .eslintrc | ||
| .gitignore | ||
| .npmignore | ||
| .pre-commit-hooks.yaml | ||
| .travis.yml | ||
| Dockerfile | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| write-good.js | ||
write-good
Overview
Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too.
Detected project types: Node.js / JavaScript, Docker.
This repository was migrated from upstream source github.com/shafiqalibhai/write-good and is preserved here for archival, reference, or continued local development.
At a glance
- Default branch:
master - Visibility: public
- Size: 337 KB
- Created: 2026-04-27
- Last updated: 2026-04-27
- Stars / Forks / Open issues: 0 / 0 / 0
- License: MIT
Languages
| Language | Bytes | Share |
|---|---|---|
| JavaScript | 28,530 bytes | 99.5% |
| Dockerfile | 154 bytes | 0.5% |
Repository structure
bin/lib/test/.dockerignore(80 B).eslintrc(133 B).gitignore(229 B).npmignore(23 B).pre-commit-hooks.yaml(181 B).travis.yml(52 B)Dockerfile(154 B)LICENSE(1,082 B)package-lock.json(133,694 B)package.json(1,611 B)README.md(9,762 B)write-good.js(3,594 B)
Getting started
Clone the repository:
git clone https://forgejo.deployview.com/ssa/write-good.git
cd write-good
Installation
npm install
# or
yarn install
# or
pnpm install
docker build -t image-name .
docker run --rm -it image-name
# or with compose
docker compose up -d
Usage
Run scripts defined in package.json:
npm start # or whatever script your project defines
npm test
After building, run the container with the command shown above. Mount volumes and forward ports as required by the application.
Original README
The content below is preserved from the previous README. Headings have been demoted so they don't compete with the new top-level sections.
write good 
Naive linter for English prose for developers who can't write good and wanna learn to do other stuff good too.
Use
npm install write-good
Important: Do not use this tool to be a jerk to other people about their writing.
API
writeGood is a function that takes a string and returns an array of suggestions.
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen.');
// suggestions:
//
// [{
// reason: "omit 'So' from the beginning of sentences",
// index: 0, offset: 2
// }, {
// reason: "'was stolen' is passive voice",
// index: 11, offset: 10
// }]
writeGood takes an optional second argument that allows you to disable certain checks.
You can disable checking for passive voice like this:
var writeGood = require('write-good');
var suggestions = writeGood('So the cat was stolen', { passive: false });
// suggestions: []
You can use the second argument's checks property to pass in custom checks instead of write-good's default linting configuration.
Like this, you can check non-English documents, for example with the linter extension for German, schreib-gut:
var schreibGut = require('schreib-gut');
writeGood('Aller Wahrscheinlichkeit nach können Entwickler nicht gut schreiben', { weasel-words: false, checks: schreibGut });
// suggestions
// [{index : 0, offset : 29, reason : '"Aller Wahrscheinlichkeit nach" is wordy or unneeded' }]
You can use the second argument's whitelist property to pass in a list of strings to whitelist from suggestions.
For example, normally only would be picked up as a bad word to use, but you might want to exempt read-only from that:
var writeGood = require('write-good');
var suggestions = writeGood('Never write read-only sentences.');
// suggestions: [{ index: 17, offset: 4, reason: '"only" can weaken meaning' }]
var filtered = writeGood('Never write read-only sentences.', { whitelist: ['read-only'] });
// filtered: []
CLI
You can use write-good as a command-line tool by installing it globally:
npm install -g write-good
If you have npm version 5.2.0 or later installed, you can use npx to run write-good without installing it:
npx write-good *.md
write-good takes a glob and prints suggestions to stdout:
$ write-good *.md
In README.md
=============
= writeGood('So the cat was stolen.');
^^^^^^^^^^
"was stolen" is passive voice on line 20 at column 40
-------------
// suggestion: "'was stolen' is passive voice",
^^^^^^^^^^
"was stolen" is passive voice on line 28 at column 19
You can run just specific checks like this:
write-good *.md --weasel --so
Or exclude checks like this:
write-good *.md --no-passive
Or include checks like this:
### E-Prime is disabled by default.
write-good *.md --yes-eprime
Note: The --yes prefix only works for E-Prime, because the other checks are included by default, anyway.
You can run just with text without supplying files:
write-good --text="It should have been defined there."
You can even supply multi-line text:
write-good --text="I can't see a problem there that's not been defined yet.
Should be defined again."
You can also pass other arguments:
write-good --text="It should have been defined there." --no-passive
You can even fetch output from a remote file:
write-good --text="$(curl https://raw.githubusercontent.com/btford/write-good/master/README.md)"
Use the --parse option to activate parse-happy output and a more conventional Unix exit code:
write-good *.md --parse
To specify a custom checks extension, for example schreib-gut, run:
npm install -g schreib-gut
write-good *.md --checks=schreib-gut
To view all available options use the --help option:
write-good --help
Checks
You can disable any combination of the following by providing a key with value false as the second argument to writeGood.
passive
Checks for passive voice.
illusion
Checks for lexical illusions – cases where a word is repeated.
so
Checks for so at the beginning of the sentence.
thereIs
Checks for there is or there are at the beginning of the sentence.
weasel
Checks for "weasel words."
adverb
Checks for adverbs that can weaken meaning: really, very, extremely, etc.
tooWordy
Checks for wordy phrases and unnecessary words.
cliches
Checks for common cliches.
eprime
Checks for "to-be" verbs. Disabled by default
Extensions
Users can create their own write-good language checks. As described above,
you can specify such extensions when running write-good on the command line
or calling it in your JavaScript code.
The following 3rd-party write-good extensions are available:
- schreib-gut: A basic extension for the German language
If you know of any write-good extensions that are not in this list, please open a pull request!
Interface
An extension is a Node.js module that exposes an object containing a check
function (fn) and an explanation string for each new check:
module.exports = {
check1: {
fn: function(text) {
…
},
explanation: '…'
},
check2: {
fn: function(text) {
…
},
explanation: '…'
}
}
Each check function takes a string input and determines a list of style
violation objects, each with an index and an offset:
/**
* @param {text} text Input text
* @return {{index:number, offset:number}[]} List of all violations
*/
The index defines the position of the match in the input text, whereas the
offset specifies the length of the match.
The following example extension provides a check that determines if the input text contains a set of forbidden terms (Tom Riddle and Voldemort):
module.exports = {
voldemort: {
fn: function (text) {
var positives = ['Tom Riddle', 'Voldemort']
var re = new RegExp('\\b(' + positives.join('|') + ')\\b', 'gi');
var suggestions = [];
while (match = re.exec(text)) {
suggestions.push({
index: match.index,
offset: match[0].length,
});
}
return suggestions;
},
explanation: 'You must not name Him-Who-Must-Not-Be-Named'
}
}
Docker
From Dockerhub
You can also run this application in Docker. Using a pre-built image from Dockerhub, the write-good can be run with this command:
docker run --rm --volume $PWD:/app hochzehn/write-good *.md
Building locally
Or you can first build the image locally:
docker build -t btford/write-good .
And then run using:
docker run -it --rm -v "$(pwd)":/srv/app -w /srv/app btford/write-good:latest *.md
See also
I came across these resources while doing research to make this module. They might be helpful.
Code
- shell script for avoiding "weasel words" – I based my initial implementation on this
- Academic Writing Check – a perl script similar to above
- writegood mode for emacs
- natural – general purpose NLP toolkit in JavaScript
- WordNet – lexical database of the English language
- LanguageTool – style and grammar checker implemented in Java
Prose
- Elements of Style
- Flesch–Kincaid readability
- Fear and Loathing of the English passive
- Words to Avoid in Educational Writing
Apps
This is not an endorsement. These apps have similar functionality that you may find useful.
Other projects using write good
- linter-write-good for Atom
- Write Good action for Drafts iOS App
- Write Good for Obsidian
- Write Good Linter for Visual Studio Code
- Write Good Linter for Vim by coc.nvim
- Vim ALE realtime linter for Vim with included support for write-good.
- Write Better A Chrome extension for Google Docs.
- Statick plugin to combine results with other linters.
License
MIT
Contributing
Contributions are welcome. The typical workflow is:
- Open an issue describing the change you'd like to make.
- Fork the repository (or create a feature branch if you have write access).
- Commit your changes with clear, descriptive messages.
- Open a pull request against the
masterbranch.
Please follow the existing code style and include tests or reproduction steps where relevant.
License
This project is licensed under the MIT license. See the LICENSE file for the full text.
Repository
- Browse: https://forgejo.deployview.com/ssa/write-good
- Clone (HTTPS):
https://forgejo.deployview.com/ssa/write-good.git - Clone (SSH):
ssh://git@forgejo.deployview.com:30143/ssa/write-good.git - Upstream / origin: github.com/shafiqalibhai/write-good
This README was generated automatically based on repository metadata, contents, and any prior README content. Edit any section above to add project-specific detail.