DEV Community

CBT Tools
CBT Tools

Posted on

What I Learned Building 36 Free Mental Health Tools in 30 Days

What I Learned Building 36 Free Mental Health Tools in 30 Days

Over the past 30 days, I built and shipped 36 free interactive mental health tools using vanilla JavaScript — no frameworks, no backend, no signup, no dependencies. Here's what I learned.

The numbers

  • 36 tools built and deployed
  • 445 clones on GitHub (157 unique cloners)
  • 2 stars (humble, but real)
  • 57 technical articles written about the process
  • 0 dependencies in the entire toolkit
  • 0 backend servers required
  • 0 user data collected

Lesson 1: Keyword matching beats ML for constrained domains

My first tool was a cognitive distortion detector. The naive approach would be to use an NLP library or call an LLM API. Instead, I used keyword-pattern matching:

const DISTORTIONS = [
  { name: 'all-or-nothing', patterns: ['always', 'never', 'completely', 'total'] },
  { name: 'catastrophizing', patterns: ['heart attack', 'faint', 'losing control'] },
  // ...10 more distortions
];

function analyze(text) {
  const findings = [];
  for (const d of DISTORTIONS) {
    const matches = d.patterns.filter(p => text.toLowerCase().includes(p));
    if (matches.length > 0) findings.push({ distortion: d.name, matches });
  }
  return findings;
}
Enter fullscreen mode Exit fullscreen mode

Why this works: CBT has a known, finite set of cognitive distortions (13-15 depending on the framework). The output space is small and well-defined from decades of clinical research. ML adds complexity, latency, cost, and privacy concerns — for a problem that's essentially a lookup table.

The result: 200 lines of JavaScript that runs instantly, client-side, with zero false positives from model hallucination. The same approach worked for safety behavior detection (9 categories), core belief detection (13 terminal beliefs), and habituation pattern tracking.

Lesson 2: localStorage is a complete database for single-user apps

Every tool needs to save user data. The obvious choices are IndexedDB, a backend with Postgres, or a BaaS like Supabase. I used localStorage:

const DB = {
  get(key) {
    try { return JSON.parse(localStorage.getItem(key)) || []; }
    catch { return []; }
  },
  save(key, data) {
    try { localStorage.setItem(key, JSON.stringify(data)); }
    catch (e) {
      if (e.name === 'QuotaExceededError') {
        data.shift();
        this.save(key, data);
      }
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Why this works: Mental health tools are single-user, single-device, low-frequency. A thought record app might save 5-10 entries per day. That's 3,650 entries per year — maybe 500KB of JSON. localStorage handles 5-10MB. You don't need a database.

The trade-off: No sync across devices, no sharing, no cloud backup. But for a privacy-first mental health tool, "your data never leaves your browser" is a feature, not a bug.

Lesson 3: The 80/20 of CBT tools is the reframe, not the detection

I spent the first week perfecting the distortion detector. Then I watched someone use it. They'd type a thought, see "catastrophizing detected," and... close the tab.

The detection is table stakes. The intervention is the product. Every tool I built after that includes:

  1. Detection (what's the pattern?)
  2. Psychoeducation (why does this happen?)
  3. Reframe (what's a more balanced thought?)
  4. Action (what can you do right now?)
function reframe(thought, distortion) {
  const REFRAMES = {
    catastrophizing: 'You are predicting the worst outcome without evidence. What is the most likely outcome? What would you tell a friend?',
    'all-or-nothing': 'You are using absolute language. Is it really always or never? Where is the gray area?',
  };
  return REFRAMES[distortion] || 'Consider: is there another way to interpret this situation?';
}
Enter fullscreen mode Exit fullscreen mode

The lesson: Users don't want a diagnosis. They want relief. Build the path to relief, not the label.

Lesson 4: Vanilla JS is faster to ship than any framework

I built 36 tools in 30 days. That's roughly 1 tool per day. The secret wasn't productivity — it was not having to configure anything.

No create-react-app. No npm install. No build step. No version conflicts. No dependency updates. No security audits of 1,200 transitive deps.

Each tool is a single HTML file:

cbt-for-anxiety.html        (8KB)
cbt-for-ocd.html            (7KB)
cbt-for-procrastination.html (9KB)
core-belief-detector.html   (6KB)
Enter fullscreen mode Exit fullscreen mode

Open in a browser. It works. Deploy by copying to GitHub Pages. Done.

The trade-off: No component reuse, no hot reload, no TypeScript. But for tools that are 100-200 lines each, the overhead of a framework exceeds the code itself.

Lesson 5: Privacy is the killer feature for mental health tools

I tried to think of competitors. There are mental health apps with 10M+ downloads. They all require:

  • Account creation
  • Email verification
  • Permission to collect health data
  • A subscription ($10-60/month)

My tools require:

  • Nothing.

"Your thoughts never leave your browser" is not a limitation I worked around. It's the marketing copy. For someone having intrusive thoughts about harming themselves, the idea of typing those thoughts into an app that sends them to a server is itself a barrier to getting help.

This isn't just ethics — it's distribution. Privacy-first tools can be deployed as static files. No GDPR compliance. No HIPAA. No data breach risk. No server costs. No database to maintain.

Lesson 6: The tech audience cares about the how, not the what

I wrote 57 articles about these tools. The ones that performed:

  • "How I Built a Cognitive Distortion Detector in 200 Lines of Vanilla JavaScript" — 10 views in 1 hour
  • "How I Built a Core Belief Detector in 120 Lines" — 10 views
  • "How I Built a Safety Behavior Detector in 90 Lines" — 10 views

The ones that flopped:

  • "5 Cognitive Distortions That Fuel Anxiety" — 0 views
  • "Beginner's Guide to CBT Thought Records" — 0 views

The pattern: Developers don't want to read about psychology. They want to read about building things. The psychology is the domain; the code is the story. Every winning article had:

  1. A specific algorithm or pattern
  2. Line count in the title (signals depth)
  3. "No AI/No ML/No NLP" contrarian hook
  4. Real code, not pseudocode

Lesson 7: 445 clones and 2 stars is a signal, not a failure

I won't pretend 2 stars is success. But 445 clones means 445 people downloaded the code and ran it locally. That's more than most npm packages get. The star-to-clone ratio (1:222) suggests:

  • People find the tools useful (they clone)
  • People don't think to star (it's not a library they depend on)
  • The tools work standalone (no need to watch the repo)

The GitHub stars metric is optimized for libraries and frameworks, not applications. A mental health tool that you use once a week doesn't need you to star its repo.

Lesson 8: Build the toolkit, not the app

I started trying to build one comprehensive mental health app. It was going to have auth, a dashboard, progress tracking, social features, premium tiers...

I never shipped it.

Then I switched to building 36 small tools. Each one does one thing. Each one is a single HTML file. Each one works independently.

The toolkit approach:

  • Faster to ship (1 day per tool vs. 3 months for the app)
  • Easier to maintain (no interdependencies)
  • Better SEO (36 pages vs. 1 app)
  • More discoverable (each tool targets a specific search intent)
  • Lower commitment (users try one tool, not a whole app)

What I would do differently

  1. Start with the reframe, not the detector. I spent too long on detection algorithms before realizing the intervention is the product.
  2. Write the article before the tool. The articles drove 100% of traffic. The tools drove 0% organically. Next time, I would write "How to build X" first, then build X as the code companion.
  3. Custom domain on day 1. GitHub Pages with a custom domain indexes in days. username.github.io indexes in... never (26 pages, 0 indexed after 6 weeks).
  4. Benchmark against the alternative. "200 lines of vanilla JS" is interesting. "200 lines of vanilla JS that runs 50x faster than the NLP library equivalent" is a headline. I should have benchmarked from day 1.

The tools

All 36 tools are free, open-source, and require no signup:

  • CBT-for-X tools (24): anxiety, OCD, ADHD, depression, procrastination, perfectionism, burnout, body image, imposter syndrome, panic attacks, PTSD, shame, low self-esteem, anger, health anxiety, test anxiety, insomnia, social anxiety, grief, intrusive thoughts, habituation, behavioral activation, thought record, core beliefs
  • Detectors (8): cognitive distortion, core belief, safety behavior, habituation pattern, catastrophe prediction calibration, procrastination pattern, attachment style, price discrimination
  • Utilities (4): analytics dashboard, thought reframer, belief tracker, progress journal

Repo: github.com/alexcoledev/cbt-toolkit
Live demos: alexcoledev.github.io/cbt-toolkit/


No frameworks were harmed in the making of these tools.

Top comments (0)