textlens
v1.0.10
Published
Fast, zero-dependency text analysis and readability toolkit for Node.js
Maintainers
Keywords
Readme
textlens
Fast, zero-dependency text analysis and readability toolkit for Node.js.
Documentation & Examples | GitHub | npm
Why textlens?
Replace multiple single-purpose packages with one:
# Before: 7 packages for text analysis
npm install flesch flesch-kincaid coleman-liau automated-readability sentiment keyword-extractor reading-time
# After: 1 package
npm install textlens| Capability | Separate packages | textlens |
|---|---|---|
| Flesch Reading Ease | flesch | readability(text).fleschReadingEase |
| Flesch-Kincaid Grade | flesch-kincaid | readability(text).fleschKincaidGrade |
| Coleman-Liau Index | coleman-liau | readability(text).colemanLiau |
| Automated Readability | automated-readability | readability(text).automatedReadability |
| Sentiment analysis | sentiment | sentiment(text) |
| Keyword extraction | keyword-extractor | keywords(text) |
| Reading time | reading-time | readingTime(text) |
| Gunning Fog, SMOG, Dale-Chall, Linsear Write | no popular package | Included |
| Keyword density (n-grams) | no popular package | density(text) |
| SEO scoring | no popular package | seoScore(text) |
| Extractive summarization | no popular package | summarize(text) |
| CLI tool | assemble yourself | npx textlens file.txt |
| TypeScript types | varies | Built-in |
One import. One API. Zero dependencies.
Installation
npm install textlensQuick Start
import { analyze } from 'textlens';
const result = analyze('Your text goes here. It can be multiple sentences or paragraphs.');
console.log(result.statistics.words); // word count
console.log(result.readability.consensusGrade); // grade level
console.log(result.readingTime.minutes); // estimated reading time
console.log(result.sentiment.label); // 'positive', 'negative', or 'neutral'
console.log(result.keywords); // top keywords by TF-IDF score
console.log(result.summary.sentences); // extractive summaryFeatures
- Text Statistics — word, sentence, paragraph, and syllable counts
- 8 Readability Formulas — Flesch-Kincaid, Coleman-Liau, Gunning Fog, SMOG, ARI, Dale-Chall, Linsear Write, and Flesch Reading Ease
- Consensus Grade — weighted average across all formulas
- Reading Time — estimated minutes to read, with configurable WPM
- Keyword Extraction — TF-IDF based keyword scoring
- Keyword Density — unigram, bigram, and trigram frequency analysis
- Sentiment Analysis — AFINN-165 lexicon-based positive/negative/neutral scoring
- SEO Scoring — content quality grade with actionable suggestions
- Extractive Summarization — sentence ranking for automatic summaries
- CLI Tool — analyze files or piped text from the terminal
- Zero Dependencies — no runtime dependencies, small bundle size
- Dual Format — ships ESM and CommonJS builds with full TypeScript types
API Reference
analyze(text: string): AnalysisResult
Run all analyses at once. Returns statistics, readability, reading time, sentiment, keywords, and summary in a single call.
import { analyze } from 'textlens';
const result = analyze('The quick brown fox jumps over the lazy dog.');
// result.statistics — TextStatistics
// result.readability — ReadabilityResult (all 8 formulas + consensus)
// result.readingTime — ReadingTimeResult
// result.sentiment — SentimentResult
// result.keywords — Keyword[]
// result.summary — SummaryResultstatistics(text: string): TextStatistics
Count characters, words, sentences, paragraphs, syllables, and compute averages.
import { statistics } from 'textlens';
const stats = statistics('Hello world. This is a test.');
// {
// characters: 28, charactersNoSpaces: 23,
// words: 6, sentences: 2, paragraphs: 1,
// syllables: 7, avgWordLength: 3.5,
// avgSentenceLength: 3, avgSyllablesPerWord: 1.17
// }readability(text: string): ReadabilityResult
Compute all 8 readability formulas plus a consensus grade level.
import { readability } from 'textlens';
const r = readability(text);
console.log(r.fleschReadingEase.score); // 0-100 (higher = easier)
console.log(r.fleschKincaidGrade.grade); // US grade level
console.log(r.consensusGrade); // weighted average gradeEach formula returns a ReadabilityScore with formula, score, grade, and interpretation fields.
readingTime(text: string, options?: ReadingTimeOptions): ReadingTimeResult
Estimate how long it takes to read the text.
import { readingTime } from 'textlens';
const rt = readingTime(text);
console.log(`${rt.minutes} min read (${rt.words} words at ${rt.wpm} wpm)`);
// Custom WPM and image count
const rt2 = readingTime(text, { wpm: 200, imageCount: 3 });Options:
wpm— words per minute (default: 238)imageCount— number of images to factor in (adds ~12s for first, decreasing for subsequent)
keywords(text: string, options?: KeywordOptions): Keyword[]
Extract top keywords using TF-IDF scoring. Stop words are filtered automatically.
import { keywords } from 'textlens';
const kw = keywords(text, { topN: 5, minLength: 3 });
// [{ word: 'example', score: 0.42, count: 3, density: 0.05 }, ...]Options:
topN— number of keywords to return (default: 10)minLength— minimum word length (default: 3)
density(text: string): KeywordDensityResult
Analyze word frequency as unigrams, bigrams, and trigrams.
import { density } from 'textlens';
const d = density(text);
console.log(d.unigrams); // [{ text: 'word', count: 5, density: 0.03 }, ...]
console.log(d.bigrams); // [{ text: 'two words', count: 2, density: 0.01 }, ...]
console.log(d.trigrams); // [{ text: 'three word phrase', count: 1, density: 0.007 }, ...]sentiment(text: string): SentimentResult
Analyze sentiment using the AFINN-165 word list.
import { sentiment } from 'textlens';
const s = sentiment('I love this amazing product!');
// {
// score: 0.47, comparative: 1.4,
// label: 'positive', confidence: 0.4,
// positive: ['love', 'amazing'], negative: []
// }Returns score (raw sum), comparative (score / word count), label, confidence, and lists of matched positive/negative words.
Note: This uses a lexicon-based approach (~60% accuracy). It works well for general English text but may miss sarcasm, context-dependent sentiment, or domain-specific language.
seoScore(text: string, options?: SEOOptions): SEOResult
Score content for SEO quality with readability, length, keyword usage, and sentence variety checks.
import { seoScore } from 'textlens';
const seo = seoScore(text, { targetKeyword: 'typescript' });
console.log(seo.score); // 0-100
console.log(seo.grade); // 'A', 'B', 'C', 'D', or 'F'
console.log(seo.issues); // ['Content is too short', ...]
console.log(seo.suggestions); // ['Add more content...', ...]Options:
targetKeyword— keyword to check for density and placementtargetGrade— desired readability grade level (default: 7)
summarize(text: string, options?: SummaryOptions): SummaryResult
Generate an extractive summary by ranking and selecting top sentences.
import { summarize } from 'textlens';
const summary = summarize(text, { sentences: 2 });
console.log(summary.sentences); // ['Most important sentence.', 'Second most important.']
console.log(summary.ratio); // compression ratio (e.g., 0.33)Options:
sentences— number of sentences to extract (default: 3)
CLI Usage
# Analyze a file
textlens article.txt
# Pipe from stdin
cat article.txt | textlens
# JSON output
textlens article.txt --json
# Output formats: pretty (default), json, minimal
textlens article.txt --format minimal
# Show specific sections
textlens article.txt --keywords 5 # top 5 keywords
textlens article.txt --sentiment # sentiment analysis
textlens article.txt --density # keyword density
textlens article.txt --seo typescript # SEO score targeting a keyword
textlens article.txt --summary 2 # 2-sentence summary
# Show everything
textlens article.txt --all
# Help and version
textlens --help
textlens --versionReadability Formulas
| Formula | What It Measures | |---|---| | Flesch Reading Ease | Score from 0-100. Higher = easier to read. Based on sentence length and syllables per word. | | Flesch-Kincaid Grade | US grade level needed to understand the text. Based on the same factors as Flesch Reading Ease. | | Coleman-Liau Index | Grade level based on character counts rather than syllables. More reliable for technical text. | | Automated Readability Index (ARI) | Grade level using characters per word and words per sentence. Fast to compute. | | Gunning Fog Index | Grade level emphasizing complex words (3+ syllables). Targets clear business writing. | | SMOG Index | Grade level based on polysyllabic word count. Best predictor for healthcare texts. Requires 30+ sentences for accuracy. | | Dale-Chall Score | Grade level based on percentage of "difficult" words not on a list of ~3,000 common words. | | Linsear Write Formula | Grade level designed for technical documents. Weights easy vs. hard words differently. |
The consensus grade is a weighted average of all formula results, providing a single reliable estimate.
Accuracy Notes
Syllable counting uses a rule-based algorithm with common English patterns. It handles most words correctly but may miscount unusual words, proper nouns, or borrowed foreign words. Accuracy is approximately 95% for standard English text.
Sentiment analysis uses the AFINN-165 lexicon which contains ~3,300 English words rated for sentiment. This approach is fast and predictable but has limitations:
- Cannot detect sarcasm or irony
- Misses context-dependent sentiment (e.g., "sick" as positive slang)
- Limited coverage of domain-specific vocabulary
- Accuracy is roughly 60% compared to human judgment
Readability formulas were developed for English text. Results for other languages will not be meaningful. Most formulas assume prose — results for poetry, code, or structured data may be unreliable.
SMOG Index requires at least 30 sentences for a statistically valid result. For shorter texts, the score is an estimate.
Sponsor
If textlens saves you time, consider sponsoring the project. Sponsorship funds ongoing development and new features.
npm fund textlensTry ProseScore
ProseScore is a free web tool powered by textlens. Paste text, get readability grades, sentiment, keywords, and SEO scores. All analysis runs in your browser.
License
MIT
