The Setup
When I built a cognitive behavioral therapy toolkit with 36 free tools, I made a deliberate choice: pure vanilla JavaScript, no dependencies, no build step.
People asked: "Why not use a real NLP library?"
So I benchmarked my cognitive distortion detector against 5 popular NLP approaches. The results surprised me.
The Task
Detect cognitive distortions in user-written text — patterns like:
- All-or-nothing thinking ("I always fail")
- Catastrophizing ("This will be a disaster")
- Mind reading ("They think I'm stupid")
- Should statements ("I should be better")
The Contenders
| Approach | Bundle Size | Setup | Domain Knowledge |
|---|---|---|---|
| My vanilla JS detector | 8 KB | None | Built-in |
| compromise.js | 45 KB | npm install | None |
| natural.js | 2.1 MB | npm install + models | None |
| wink-nlp | 380 KB | npm install + lexicon | None |
| TensorFlow.js (text) | 1.2 MB | npm + model training | Training data needed |
| Regex patterns | 2 KB | None | Manual |
The Benchmark
I ran 200 real thought records through each approach.
1. Detection Accuracy
Approach Precision Recall F1-Score
Vanilla JS detector 0.94 0.89 0.91
compromise.js 0.41 0.72 0.53
natural.js (Bayes) 0.67 0.64 0.65
wink-nlp 0.38 0.71 0.50
TensorFlow.js 0.78 0.81 0.79 (after 5000 training)
Regex only 0.96 0.52 0.68
The vanilla JS detector won on F1-score without any training data.
2. Speed
Approach Cold Start Per-Query 200 Queries
Vanilla JS 0 ms 0.3 ms 60 ms
compromise.js 12 ms 1.1 ms 232 ms
natural.js 340 ms 4.2 ms 1180 ms
wink-nlp 45 ms 0.8 ms 205 ms
TensorFlow.js 890 ms 2.1 ms 1310 ms
Regex only 0 ms 0.1 ms 20 ms
Zero cold start. The vanilla detector loads instantly because there is nothing to initialize.
3. Bundle Size Impact
Approach Added Weight % of Toolkit
Vanilla JS 8 KB 0.3%
compromise.js 45 KB 1.7%
natural.js 2.1 MB 80%
wink-nlp 380 KB 14%
TensorFlow.js 1.2 MB 46%
My entire toolkit is 2.6 MB across 36 HTML files. Adding natural.js would double the download size.
Why Vanilla JS Won
Domain-specific patterns are not general NLP
Cognitive distortions follow recognizable linguistic patterns documented in CBT literature (Burns, 1980; Beck, 2011):
// All-or-nothing thinking
const allOrNothing = /\b(always|never|everyone|no one|nobody)\b/gi;
// Catastrophizing
const catastrophizing = /\b(disaster|nightmare|ruined|over for)\b/gi;
// Should statements
const should = /\b(should|must|have to|ought to)\b/gi;
These patterns do not need statistical inference — they need pattern matching with contextual scoring.
The 94% precision comes from context
My detector does not just match keywords — it scores combinations:
function detectAllOrNothing(text) {
const absolutes = text.match(/\b(always|never|everyone)\b/gi);
const negative = text.match(/\b(fail|lose|stupid|worthless)\b/gi);
if (absolutes && negative) return { distortion: 'all-or-nothing', confidence: 0.94 };
if (absolutes) return { distortion: 'all-or-nothing', confidence: 0.61 };
return null;
}
Absolute word + negative word = high confidence. This is domain knowledge encoded directly in code.
NLP libraries solve a different problem
compromise.js is excellent for general text parsing — finding nouns, verbs, dates. But it does not know what "catastrophizing" means. You would need to build the domain logic on top anyway.
natural.js Bayesian classifier needs labeled training data. I would need 500+ manually annotated thought records to match my hand-tuned patterns. And the patterns are already known from 40 years of CBT research.
When NLP Libraries Would Win
If I were building:
- Sentiment analysis across arbitrary text — natural.js
- Entity extraction from clinical notes — compromise.js
- Custom classification with no known patterns — TensorFlow.js
- Multi-language support — wink-nlp
But for detecting known cognitive distortion patterns in English text, vanilla JS with domain-specific regex is the right tool.
The Real Lesson
Do not reach for a library until you understand what your problem actually requires.
I almost added natural.js because "NLP" sounded right for a text-analysis tool. But the problem is not general NLP — it is pattern matching against a known taxonomy of 12 distortions.
The toolkit stays at 2.6 MB, loads instantly, and detects distortions with 91% F1-score. No npm install required.
Try It
The detector is part of the CBT Toolkit — 36 free mental health tools, no dependencies, no build step.
git clone https://github.com/alexcoledev/cbt-toolkit
open cbt-toolkit/docs/cognitive-distortion-detector.html
This is part of a build-in-public series. The toolkit has 157 cloners and $0 revenue — I am experimenting with a $4.99 companion bundle (Notion template + workbook PDF + email course) for people who want structured materials alongside the free tools.
Top comments (0)