Zum Hauptinhalt springen
•
Sichere ProgrammierungThe Jevons Paradox of Judgment(03.10.2026 um 03:12 Uhr)
•
Sichere ProgrammierungI built a game so my family could see who always gets skipped(03.10.2026 um 03:13 Uhr)
••••
Sichere ProgrammierungTrack which companies are hiring (and closing roles) with a jobs API(03.10.2026 um 03:16 Uhr)
•
Sichere ProgrammierungAI Coding Has Made Project-Switching Way Too Easy(03.10.2026 um 03:16 Uhr)
••••
Sichere ProgrammierungThe Jevons Paradox of Judgment(03.10.2026 um 03:12 Uhr)
•
Sichere ProgrammierungI built a game so my family could see who always gets skipped(03.10.2026 um 03:13 Uhr)
••••
Sichere ProgrammierungTrack which companies are hiring (and closing roles) with a jobs API(03.10.2026 um 03:16 Uhr)
•
Sichere ProgrammierungAI Coding Has Made Project-Switching Way Too Easy(03.10.2026 um 03:16 Uhr)
•••
Intelligence View
⚡ tsecurity.de Intelligence

Build a Hemingway Editor Clone with TypeScript in 50 Lines

The Hemingway Editor highlights hard-to-read sentences, flags adverbs, and shows your text's grade level. It costs $20 and doesn't have an API. You can't plug…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

The Hemingway Editor highlights hard-to-read sentences, flags adverbs, and shows your text's grade level. It costs $20 and doesn't have an API. You can't plug it into a build step, run it against your docs folder, or automate it in any way.



Let's build a readability checker for developers that does what Hemingway does — from the command line, in about 50 lines of TypeScript.






What We're Building



A CLI tool called hemingway-check that:




  1. Reads a markdown or text file

  2. Reports the grade level and Flesch Reading Ease score

  3. Flags hard-to-read sentences (grade 10+)

  4. Flags very hard sentences (grade 14+)

  5. Counts adverbs

  6. Exits with code 1 if the text is too complex (for CI use)






Setup






mkdir hemingway-check && cd hemingway-check
npm init -y
npm install textlens
npm install -D typescript @types/node
npx tsc --init --target es2020 --module nodenext --moduleResolution nodenext --outDir dist









The Full Script



Create src/index.ts:




import { readFileSync } from 'fs';
import { readability, statistics } from 'textlens';

const file = process.argv[2];
if (!file) {
console.error('Usage: hemingway-check <file>');
process.exit(1);
}

const text = readFileSync(file, 'utf8');
const scores = readability(text);
const stats = statistics(text);

// Split into sentences and score each one
const sentences = text
.replace(/\n/g, ' ')
.split(/(?<=[.!?])\s+/)
.filter(s => s.trim().length > 0);

let hard = 0;
let veryHard = 0;
const flagged: { sentence: string; grade: number; level: string }[] = [];

for (const sentence of sentences) {
if (sentence.split(/\s+/).length < 5) continue; // skip short fragments
const r = readability(sentence);
const grade = r.consensusGrade;
if (grade >= 14) {
veryHard++;
flagged.push({ sentence: sentence.slice(0, 80), grade, level: 'VERY HARD' });
} else if (grade >= 10) {
hard++;
flagged.push({ sentence: sentence.slice(0, 80), grade, level: 'HARD' });
}
}

// Count adverbs (words ending in -ly, with common exceptions)
const exceptions = new Set(['only', 'early', 'daily', 'likely', 'family', 'apply', 'supply', 'reply', 'holy', 'july', 'fly', 'rely', 'ally', 'italy', 'belly', 'jelly', 'bully', 'ugly']);
const words = text.toLowerCase().match(/\b\w+\b/g) || [];
const adverbs = words.filter(w => w.endsWith('ly') && w.length > 3 && !exceptions.has(w));
const adverbTarget = Math.max(1, Math.floor(stats.sentences * 0.3));

// Report
console.log(`\n Hemingway Check: ${file}\n`);
console.log(` Grade Level: ${scores.consensusGrade.toFixed(1)}`);
console.log(` Flesch Ease: ${scores.fleschReadingEase.score.toFixed(1)} (${scores.fleschReadingEase.interpretation})`);
console.log(` Words: ${stats.words}`);
console.log(` Sentences: ${stats.sentences}`);
console.log(` Avg sentence: ${stats.avgSentenceLength.toFixed(1)} words`);
console.log(` Hard sentences: ${hard}`);
console.log(` Very hard: ${veryHard}`);
console.log(` Adverbs: ${adverbs.length} (target: <${adverbTarget})`);

if (flagged.length > 0) {
console.log('\n Flagged sentences:\n');
for (const f of flagged) {
const color = f.level === 'VERY HARD' ? '\x1b[31m' : '\x1b[33m';
console.log(` ${color}[${f.level}]\x1b[0m Grade ${f.grade.toFixed(1)}: "${f.sentence}..."`);
}
}

const pass = scores.consensusGrade <= 10 && veryHard === 0;
console.log(`\n Result: ${pass ? '\x1b[32mPASS\x1b[0m' : '\x1b[31mFAIL\x1b[0m'}\n`);
process.exit(pass ? 0 : 1);






That's 50 lines of logic (excluding blank lines and the shebang). Let's break down the key parts.






How It Works






Grade-level scoring






const scores = readability(text);
console.log(scores.consensusGrade); // e.g., 7.2






textlens runs 8 readability formulas (Flesch-Kincaid, Coleman-Liau, Gunning Fog, SMOG, ARI, Dale-Chall, Linsear Write, and Flesch Reading Ease) and averages the grade-level results into consensusGrade. One function call gives you a number backed by seven formulas.






Sentence-level analysis



The Hemingway Editor highlights individual sentences. We do the same by splitting the text on sentence boundaries and scoring each one:




const sentences = text.split(/(?<=[.!?])\s+/);
for (const sentence of sentences) {
const r = readability(sentence);
if (r.consensusGrade >= 14) { /* very hard */ }
else if (r.consensusGrade >= 10) { /* hard */ }
}






Sentences at grade 10+ are "hard to read." Grade 14+ is "very hard." These thresholds match what the Hemingway Editor uses internally.






Adverb detection



A simple but effective heuristic: words ending in "-ly" that aren't in an exception list. This catches "quickly," "extremely," "very" but skips "family," "apply," "only."




const adverbs = words.filter(w =>
w.endsWith('ly') && w.length > 3 && !exceptions.has(w)
);






Professional editors recommend keeping adverbs under 30% of your sentence count. The tool calculates this target automatically.






Running It



Add to package.json:




{
"scripts": {
"build": "tsc",
"check": "node dist/index.js"
},
"bin": {
"hemingway-check": "./dist/index.js"
}
}









npx tsc
node dist/index.js README.md






Sample output:




  Hemingway Check: README.md

Grade Level: 6.2
Flesch Ease: 68.4 (Standard / average)
Words: 342
Sentences: 28
Avg sentence: 12.2 words
Hard sentences: 3
Very hard: 0
Adverbs: 2 (target: <8)

[HARD] Grade 11.2: "The formula penalizes complex words with three or more syllables..."

Result: PASS









Adding It to CI



Add a prepublish script or a GitHub Actions step:




- name: Readability check
run: |
npm install textlens
npx tsc
node dist/index.js docs/guide.md






The script exits with code 1 when it fails, so it blocks merges automatically.






How This Compares to the Real Hemingway Editor





















































Feature Hemingway Editor hemingway-check
Grade level Yes Yes (8 formulas + consensus)
Hard sentence highlighting Yes (color-coded) Yes (terminal colors)
Adverb detection Yes Yes (heuristic)
Passive voice Yes Not yet
Simpler alternatives Yes Not yet
Works in CI No Yes
API/programmatic use No Yes (textlens library)
Price $20 Free (MIT)


The Hemingway Editor has a better UI and catches passive voice. Our CLI version works in automation pipelines and costs nothing.






Extending It



Want to add passive voice detection? Sentence simplification suggestions? The textlens analyze() function gives you everything you need as a foundation:




const { analyze } = require('textlens');
const result = analyze(text);
// result.readability — all 8 formulas
// result.sentiment — is the tone appropriate?
// result.keywords — what's the text about?
// result.statistics — word/sentence/syllable counts






You could build a full writing assistant with readability scoring, tone checking, keyword analysis, and SEO optimization — all from one zero-dependency package.






Source Code



The complete source for this tutorial is about 50 lines. No framework, no build tool beyond TypeScript itself.





This is part of the textlens series — tutorials on text analysis in JavaScript and TypeScript.

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

ATT&CK-Navigator · IoC-Radar · Exploit-Belege
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
2 Knoten · 1 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Build a Hemingway Editor Clone with TypeScript in 50 Lines

Thematisch verwandte Begriffe: Build, Hemingway, Editor, Clone · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag