<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: member_ce2645ea</title>
    <description>The latest articles on DEV Community by member_ce2645ea (@member_ce2645ea).</description>
    <link>https://dev.to/member_ce2645ea</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3975425%2Fe8a6e105-d28c-4047-8616-e2ed96f7abfa.png</url>
      <title>DEV Community: member_ce2645ea</title>
      <link>https://dev.to/member_ce2645ea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/member_ce2645ea"/>
    <language>en</language>
    <item>
      <title>I Analyzed 200 Rejection Emails and Built an AI That Fixes Resumes</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:57:17 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/i-analyzed-200-rejection-emails-and-built-an-ai-that-fixes-resumes-5g00</link>
      <guid>https://dev.to/member_ce2645ea/i-analyzed-200-rejection-emails-and-built-an-ai-that-fixes-resumes-5g00</guid>
      <description>&lt;p&gt;Last year I was laid off. Like a lot of people, I sent out hundreds of applications. Unlike most people, I saved every rejection email and tried to figure out what was actually happening.&lt;/p&gt;

&lt;p&gt;The result was a rabbit hole that ended with me building a resume analyzer. Here's what I found.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem Isn't Your Resume
&lt;/h2&gt;

&lt;p&gt;After reading 200+ rejections (yes, I kept a spreadsheet), I noticed a pattern. The companies that actually interviewed me didn't have better resumes — they had resumes that matched their specific job description better.&lt;/p&gt;

&lt;p&gt;Most resume advice is generic: "use action verbs," "keep it to one page," "quantify your impact." That advice is fine, but it misses the point. The goal isn't a good resume. The goal is a resume that passes the specific filter of a specific job at a specific company.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Analyzer Works
&lt;/h2&gt;

&lt;p&gt;The approach is simple: compare a resume against a job description and measure the overlap across four dimensions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scoreResume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resumeText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jobDescription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractKeywords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jobDescription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;matched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;resumeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;matchRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;matched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;missingKeywords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;resumeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;keywordDensity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;resumeText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The keyword extraction strips common words and pulls out the meaningful terms: technologies, certifications, industry-specific phrases. If the JD mentions "Kubernetes" three times and your resume doesn't mention it once, that's a problem — regardless of whether you think you can learn it on the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Surprised Me
&lt;/h2&gt;

&lt;p&gt;Two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Soft skills are invisible to filters.&lt;/strong&gt; "Great communicator" and "team player" mean nothing to an ATS parser. The system is looking for concrete terms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The same resume can score 20% against one JD and 80% against another.&lt;/strong&gt; The difference isn't you — it's how well your wording overlaps with what they're asking for.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Run Your Own Resume Check
&lt;/h2&gt;

&lt;p&gt;The tool I built is at &lt;a href="https://resumeaiopt.com" rel="noopener noreferrer"&gt;resumeaiopt.com&lt;/a&gt;. Paste your resume and a job description, and it'll show you where the gaps are. No account needed, no data stored — just analysis.&lt;/p&gt;

</description>
      <category>career</category>
      <category>javascript</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I Stopped Proofreading Manually and Built a Grammar Checker Instead</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:54:11 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/why-i-stopped-proofreading-manually-and-built-a-grammar-checker-instead-22bp</link>
      <guid>https://dev.to/member_ce2645ea/why-i-stopped-proofreading-manually-and-built-a-grammar-checker-instead-22bp</guid>
      <description>&lt;p&gt;I was that person who would write a single email, read it eight times, still hit send, and immediately spot a typo. Every. Single. Time.&lt;/p&gt;

&lt;p&gt;Writing is hard enough without having to also be your own copy editor. After spending way too much time proofreading blog posts, work emails, and even Slack messages, I decided to automate at least the mechanical part of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Most Grammar Checkers Get Wrong
&lt;/h2&gt;

&lt;p&gt;The existing tools I tried had two problems:&lt;/p&gt;

&lt;p&gt;First, they were too opinionated. Grammarly would tell me to rewrite half my sentence because of some stylistic preference. I don't need suggestions — I need to know if I wrote "their" when I meant "there."&lt;/p&gt;

&lt;p&gt;Second, they wanted too much access. Browser extensions reading everything you type? No thanks. I wanted something I could paste text into, get a clean report, and leave.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Minimal Grammar Check
&lt;/h2&gt;

&lt;p&gt;The core approach is straightforward: break the text into sentences, check each one against known patterns, flag the matches. Here's the sentence splitter I ended up using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;splitSentences&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;([&lt;/span&gt;&lt;span class="sr"&gt;.?!&lt;/span&gt;&lt;span class="se"&gt;])\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$1&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple regex splitting handles most cases. The hard part was the pattern library — things like subject-verb agreement, common homophone mistakes, and punctuation rules. Each rule is just a function that takes a sentence and returns a list of issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkHomophones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;their&lt;/span&gt;&lt;span class="se"&gt;\b(?=\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(?:&lt;/span&gt;&lt;span class="sr"&gt;going|not|is|are&lt;/span&gt;&lt;span class="se"&gt;))&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Did you mean "they&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;re"?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;youre&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Did you mean "you&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;re"?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rules&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;homophone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The biggest insight was that &lt;strong&gt;most writing errors fall into a small set of patterns&lt;/strong&gt;. You don't need a machine learning model to catch 80% of mistakes. A well-crafted ruleset catches the common stuff, and for the remaining 20%, you should probably just read it yourself.&lt;/p&gt;

&lt;p&gt;Also, the tool helped me write better over time. When you see the same mistake flagged repeatedly, you eventually stop making it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check Your Own Writing
&lt;/h2&gt;

&lt;p&gt;The tool I built is at &lt;a href="https://grammaraicheck.com" rel="noopener noreferrer"&gt;grammaraicheck.com&lt;/a&gt; — paste your text, get instant feedback on grammar, spelling, and punctuation. No signup, no data collection, just a text box and a red underline.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>javascript</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Built a DCA Calculator to Understand Dollar Cost Averaging</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:54:09 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/how-i-built-a-dca-calculator-to-understand-dollar-cost-averaging-3a8p</link>
      <guid>https://dev.to/member_ce2645ea/how-i-built-a-dca-calculator-to-understand-dollar-cost-averaging-3a8p</guid>
      <description>&lt;p&gt;I've been putting money into the stock market for about three years now. Nothing fancy — just S&amp;amp;P 500 ETFs, auto-invest every month, same amount regardless of what the market is doing. That's dollar cost averaging in a nutshell.&lt;/p&gt;

&lt;p&gt;But for the first year, I kept second-guessing myself. "Should I wait for a dip?" "Should I put in a lump sum instead?" I wanted to see, with actual numbers, whether DCA actually made sense in different scenarios.&lt;/p&gt;

&lt;p&gt;So I built a calculator.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Dollar Cost Averaging Actually Does
&lt;/h2&gt;

&lt;p&gt;DCA means you invest a fixed amount of money at regular intervals. When the price is high, you buy fewer shares. When it's low, you buy more. Over time, your average cost per share ends up lower than the average price per share during the same period.&lt;/p&gt;

&lt;p&gt;That sounds like magic until you run the numbers yourself. Here's the core logic I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dcaSimulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;monthlyInvestment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;monthlyPrices&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;totalShares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;totalInvested&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="nx"&gt;monthlyPrices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;monthlyInvestment&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;
    &lt;span class="nx"&gt;totalShares&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;shares&lt;/span&gt;
    &lt;span class="nx"&gt;totalInvested&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;monthlyInvestment&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;finalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalShares&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;monthlyPrices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;monthlyPrices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;avgCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalInvested&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;totalShares&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;totalInvested&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;finalValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;avgCost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalShares&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple math. But seeing the output for different price patterns — steady growth, volatile flat, crash then rebound — was way more convincing than reading blog posts about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Feature That Changed My Mind
&lt;/h2&gt;

&lt;p&gt;The most interesting part wasn't the DCA mode itself. I added a lump sum comparison: what if you had all the money upfront instead?&lt;/p&gt;

&lt;p&gt;In a pure bull market, lump sum wins every time. But most of us don't have a lump sum. We have a paycheck every two weeks. DCA isn't about maximizing returns — it's about removing the emotional tax of trying to time the market.&lt;/p&gt;

&lt;p&gt;That's the real value. Not beating lump sum, but beating the alternative (which for most people is not investing at all because they're scared of buying at the top).&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Building It
&lt;/h2&gt;

&lt;p&gt;Three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Date math is surprisingly annoying.&lt;/strong&gt; Monthly intervals sound simple until you deal with uneven months and weekends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inflation visualization matters.&lt;/strong&gt; Seeing nominal returns versus inflation-adjusted returns changes how you think about long-term projections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People love sliders.&lt;/strong&gt; I added a slider for monthly contribution amount and everyone who tried the tool spent more time playing with it than expected.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;If you want to play with the calculator I built, it's live at &lt;a href="https://financalcai.com" rel="noopener noreferrer"&gt;financalcai.com&lt;/a&gt;. You can adjust the monthly amount, time horizon, and expected return rate to see how DCA plays out in different scenarios. No signup, no email required — just numbers.&lt;/p&gt;

</description>
      <category>investing</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Forza Horizon 6: What's Actually Different From FH5 (And What's Just Hype)</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:53:14 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/forza-horizon-6-whats-actually-different-from-fh5-and-whats-just-hype-58o5</link>
      <guid>https://dev.to/member_ce2645ea/forza-horizon-6-whats-actually-different-from-fh5-and-whats-just-hype-58o5</guid>
      <description>&lt;p&gt;I've put about 60 hours into Forza Horizon 6 since launch, and I've seen a lot of takes that miss the point. Here's what actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Map: Germany vs. Mexico
&lt;/h2&gt;

&lt;p&gt;FH5 gave us a beautiful but somewhat monotonous Mexico — lots of desert, some jungle, a volcano. FH6 moves to Germany, and the variety is night and day. Dense forests, autobahn sections, medieval towns with actual narrow streets that force different driving lines, and the Nürburgring Nordschleife integrated into the open world.&lt;/p&gt;

&lt;p&gt;The big change isn't just scenery — it's road design. FH5 had long, sweeping corners that favored power builds. FH6 has technical sections that reward handling setups. If you're coming from FH5 with a garage full of 1500hp hypercars, you're going to struggle on the Black Forest roads. I wrote a &lt;a href="https://fh6wiki.com/fh6-vs-fh5" rel="noopener noreferrer"&gt;detailed FH6 vs FH5 comparison&lt;/a&gt; covering the physics engine changes, car list differences (630 vs 530), and whether the upgrade is actually worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Festival Playlist System
&lt;/h2&gt;

&lt;p&gt;FH6 revamped the weekly challenges. The Festival Playlist now has 8 different challenge types — PR Stunts, EventLab races, Championships, Playground Games, Photo Challenges, Treasure Hunts, Monthly Rivals, and Trials. Each awards different points toward the weekly car rewards.&lt;/p&gt;

&lt;p&gt;The optimization meta has shifted. A 20-point car takes about 90 minutes of focused play. The 40-point car is 2-3 hours. The 160-point series reward is spread across 4 weeks at roughly 3-4 hours per week. If you're grinding efficiently, you want to prioritize Trial events (10 points each, fastest completion) and skip Playground Games unless you have a coordinated group. I put together a &lt;a href="https://fh6wiki.com/seasonal-playlist" rel="noopener noreferrer"&gt;complete Festival Playlist optimization guide&lt;/a&gt; with point breakdowns and time estimates for every challenge type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tuning After the Tire Model Change
&lt;/h2&gt;

&lt;p&gt;FH6 introduced a new tire model that changed how grip works at the limit. The old FH5 tunes are mostly obsolete — cars that handled perfectly in FH5 now understeer on corner entry or snap-oversteer on exit in FH6.&lt;/p&gt;

&lt;p&gt;The new meta: S2 class is dominated by the Koenigsegg Jesko with specific downforce settings. S1 road racing is the Porsche 911 GT3 RS (2023). A class all-rounders lean on the Subaru WRX STI. For drifting, the Formula Drift 370Z is still king but requires a completely different alignment setup than FH5. I've been &lt;a href="https://fh6wiki.com/tuning-setups-share-codes" rel="noopener noreferrer"&gt;collecting and testing share codes for S2 through B class&lt;/a&gt; with tuner credits and spec sheets for each build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Buy It?
&lt;/h2&gt;

&lt;p&gt;If you're into the physics and online racing: yes, the tire model alone makes it worth it. If you're a solo player who already owns FH5: wait for a sale, the content volume is similar. If FH5 didn't click for you: FH6 won't change your mind — it's an evolution, not a revolution.&lt;/p&gt;

</description>
      <category>gaming</category>
      <category>forza</category>
      <category>racing</category>
      <category>review</category>
    </item>
    <item>
      <title>What Actually Happens During an El Niño Winter — A Practical Guide for 2026</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:53:13 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/what-actually-happens-during-an-el-nino-winter-a-practical-guide-for-2026-mm2</link>
      <guid>https://dev.to/member_ce2645ea/what-actually-happens-during-an-el-nino-winter-a-practical-guide-for-2026-mm2</guid>
      <description>&lt;p&gt;El Niño winters get a lot of hype, but most people don't understand what they actually mean for real life. After the last major El Niño event (2023-24), I spent time researching the upcoming 2026-27 season and came away with practical insights that go beyond the weather channel soundbites.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-Second Version
&lt;/h2&gt;

&lt;p&gt;El Niño is a warming of Pacific Ocean surface water near the equator. It happens every 2-7 years and shifts global weather patterns for 6-12 months. The next significant one is forecast for late 2026, and different regions will feel it very differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Actually Means for Your Winter
&lt;/h2&gt;

&lt;p&gt;If you ski or snowboard, this is the short version: the Sierras and southern Rockies tend to get dumped on during El Niño winters. The Pacific Northwest and Northeast? Not so much. I wrote a &lt;a href="https://elninoguide.com/el-nino-ski-season-2026-2027-forecast" rel="noopener noreferrer"&gt;region-by-region breakdown of what skiers should expect from the 2026-27 El Niño season&lt;/a&gt; if you're planning trips.&lt;/p&gt;

&lt;p&gt;If you're a homeowner, the bigger concern is flood and wind damage. Standard homeowners insurance doesn't cover flood damage — and most people don't realize this until it's too late. El Niño winters in California and the Gulf states mean saturated soil, atmospheric rivers, and a real risk of sewer backup flooding basements. I put together a &lt;a href="https://elninoguide.com/el-nino-home-insurance-guide-2026" rel="noopener noreferrer"&gt;detailed guide on El Niño home insurance gaps&lt;/a&gt; covering what standard policies miss and what riders you actually need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining This to a 10-Year-Old
&lt;/h2&gt;

&lt;p&gt;My kid asked me "why does the ocean getting warmer make it rain more here?" and I realized El Niño is surprisingly hard to explain well. The bathtub analogy works: imagine filling a bathtub with warm water — the steam rises, moves across the room, and condenses on the cold mirror. The Pacific Ocean is the bathtub, and the "steam" is the jet stream shifting south and getting stronger, pushing storms into California and the southern US. If you need a &lt;a href="https://elninoguide.com/el-nino-explained-for-kids-students" rel="noopener noreferrer"&gt;simple El Niño explainer for kids or students&lt;/a&gt;, I wrote one with monitoring technology (buoys + satellites) and a comparison with La Niña.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters More Than Before
&lt;/h2&gt;

&lt;p&gt;El Niño events aren't getting more frequent, but their impacts are getting more expensive. More people living in coastal and wildfire-adjacent areas. Aging infrastructure. Insurance markets pulling out of high-risk states. Understanding what's coming isn't just interesting — it's practical risk management.&lt;/p&gt;

&lt;p&gt;The good news: we can see these events coming 6-9 months in advance. NOAA's tropical Pacific buoy array gives real-time data, and seasonal forecast models have gotten remarkably good. If you're in an affected region, you have time to prepare. That's the whole point of understanding this stuff.&lt;/p&gt;

</description>
      <category>weather</category>
      <category>science</category>
      <category>climate</category>
      <category>guide</category>
    </item>
    <item>
      <title>What I Learned Designing 50 Logos With AI (and When It Actually Works)</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:52:16 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/what-i-learned-designing-50-logos-with-ai-and-when-it-actually-works-50j0</link>
      <guid>https://dev.to/member_ce2645ea/what-i-learned-designing-50-logos-with-ai-and-when-it-actually-works-50j0</guid>
      <description>&lt;p&gt;I can't design a logo. I've tried. Every time I open Illustrator I spend an hour making something that looks like a first-grade art project.&lt;/p&gt;

&lt;p&gt;So when AI image generation got good enough to produce usable graphics, I got curious: could I build something that generates actual logos, not just pretty pictures?&lt;/p&gt;

&lt;p&gt;After making about 50 attempts, here's what I figured out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Most AI Logo Generators
&lt;/h2&gt;

&lt;p&gt;Most AI image generators don't understand what a logo is. They generate beautiful illustrations that would never work as a logo — too much detail, wrong aspect ratio, text that looks correct from a distance but is gibberish up close.&lt;/p&gt;

&lt;p&gt;A logo needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt; — has to work at 16x16 pixels&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; — one version for a favicon, another for a billboard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readability&lt;/strong&gt; — if there's text, it has to actually be readable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generative models are surprisingly bad at the third one. They'll produce something that looks like it says "TechCorp" until you zoom in and realize it's just shapes that vaguely resemble letters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Works
&lt;/h2&gt;

&lt;p&gt;The sweet spot is generative AI for the icon, plus programmatic rendering for the text and layout. Keep the AI part focused and constrained:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateLogoPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;business&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;minimal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flat vector, minimal, one or two shapes, clean lines, no text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;geometric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;symmetric geometric shape, abstract, sharp lines, solid colors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Professional business logo for "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;business&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;": &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;. Solid background, simple composition, suitable for a website header.`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feed that to an image model, get a clean icon back, then layer the text programmatically with proper fonts. The result looks much more like a real logo than anything the model produces on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Style Selection Matters More Than You Think
&lt;/h2&gt;

&lt;p&gt;I added 8 style presets after watching people generate 30 logos in the "default" style and hate all of them. Minimalist, geometric, vintage, tech — different businesses genuinely look better in different styles. Giving people a choice upfront saves a lot of iterations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;If you need a logo, the generator I built is at &lt;a href="https://aielogo.com" rel="noopener noreferrer"&gt;aielogo.com&lt;/a&gt;. Pick a style, type your business name, and see what comes out. No signup needed — it's just a tool.&lt;/p&gt;

</description>
      <category>design</category>
      <category>ai</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Tracked My Body Fat for 90 Days and Built a Calculator That Actually Makes Sense</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:50:37 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/i-tracked-my-body-fat-for-90-days-and-built-a-calculator-that-actually-makes-sense-2i0</link>
      <guid>https://dev.to/member_ce2645ea/i-tracked-my-body-fat-for-90-days-and-built-a-calculator-that-actually-makes-sense-2i0</guid>
      <description>&lt;p&gt;For three months, I weighed myself every morning and took body measurements every Sunday. I used a caliper, a tape measure, and a scale that probably lies to me about hydration levels.&lt;/p&gt;

&lt;p&gt;The goal wasn't to get ripped. It was to understand whether any of these measurements actually mean something day to day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Most Health Calculators
&lt;/h2&gt;

&lt;p&gt;Most body fat calculators fall into one of two camps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Too simple&lt;/strong&gt; — plug in height and weight, get a BMI number that tells you nothing about your actual composition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too complicated&lt;/strong&gt; — requires measurements you need a degree to take correctly, plus an email signup and a paid subscription.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither is useful for someone who just wants to know "am I making progress?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Something Practical
&lt;/h2&gt;

&lt;p&gt;I put together a calculator that uses the Navy Method — it takes neck, waist, and hip measurements and estimates body fat percentage. The math has been around since the 80s and correlates reasonably well with DEXA scans for most people:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;navyBodyFat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;neck&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gender&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;male&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;86.010&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;waist&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;neck&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
           &lt;span class="mf"&gt;70.041&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;36.76&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;163.205&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;waist&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;hip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;neck&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
         &lt;span class="mf"&gt;97.684&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;78.387&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The inputs are simple enough that anyone can take them with a tape measure. The output gives you a ballpark number that's consistent enough to track trends over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 90 Days of Data Taught Me
&lt;/h2&gt;

&lt;p&gt;Three things stood out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Daily weight is useless; weekly trend is everything.&lt;/strong&gt; My weight would swing 2-3 pounds daily due to water, food, and sleep. The weekly moving average was the only signal worth watching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Body fat percentage changes slowly.&lt;/strong&gt; Like, frustratingly slowly. In 90 days of consistent training, I moved maybe 2%. But that's real — if a calculator tells you you dropped 5% body fat in a month, it's broken.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency beats precision.&lt;/strong&gt; Taking measurements at the same time, under the same conditions, with the same method matters more than which formula you use.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The calculator I built is at &lt;a href="https://bodycalctool.com" rel="noopener noreferrer"&gt;bodycalctool.com&lt;/a&gt;. It includes BMI, body fat estimation, and a few other health metrics. No frills, no accounts — just input fields and numbers.&lt;/p&gt;

</description>
      <category>health</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>data</category>
    </item>
    <item>
      <title>"I Built a Free AI Grammar Checker That Runs Entirely in the Browser"</title>
      <dc:creator>member_ce2645ea</dc:creator>
      <pubDate>Thu, 25 Jun 2026 07:29:29 +0000</pubDate>
      <link>https://dev.to/member_ce2645ea/i-built-a-free-ai-grammar-checker-that-runs-entirely-in-the-browser-hmo</link>
      <guid>https://dev.to/member_ce2645ea/i-built-a-free-ai-grammar-checker-that-runs-entirely-in-the-browser-hmo</guid>
      <description>&lt;h1&gt;
  
  
  I Built a Free AI Grammar Checker That Runs Entirely in the Browser
&lt;/h1&gt;

&lt;p&gt;A few months ago I got tired of copy-pasting my writing between five different tools — Grammarly for grammar, Hemingway for readability, some word counter for stats. So I built &lt;a href="https://grammaraicheck.com/" rel="noopener noreferrer"&gt;AI Grammar Checker&lt;/a&gt; — a single tool that does all of that in one shot, for free, with no signup.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;You paste English text, hit check, and get back:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sentence-by-sentence grammar corrections&lt;/strong&gt; with explanations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style polish&lt;/strong&gt; — passive voice, weak adverbs, wordy phrases flagged&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flesch readability score&lt;/strong&gt; so you know if your text is actually readable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hemingway-style highlights&lt;/strong&gt; — hard sentences, very hard sentences, adverb count&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CEFR level&lt;/strong&gt; (A1–C2) so non-native speakers know where they stand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tone detection&lt;/strong&gt; — formal, casual, neutral&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All client-side except the AI check call. No server stores your text.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack is stupidly simple
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTML + vanilla JS + CSS
↓
DeepSeek API (OpenAI-compatible, $0.27/million tokens)
↓
Result rendered directly in the DOM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No React. No Next.js. No build step. Just &lt;code&gt;app.js&lt;/code&gt;, &lt;code&gt;style.css&lt;/code&gt;, and &lt;code&gt;index.html&lt;/code&gt;. The "backend" is a tiny Cloudflare Worker that proxies the DeepSeek API call so the API key stays server-side.&lt;/p&gt;

&lt;p&gt;Here's roughly how the grammar check works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runGrammarCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;intensity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`You are a professional English editor.
Analyze the text sentence by sentence.
For each issue, return: original text, corrected text, explanation.
Also return: readability score, CEFR level, tone.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/deepseek&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deepseek-chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intensity slider is the interesting bit — it adjusts the system prompt to be more or less aggressive about suggesting changes. At low intensity it only flags actual errors. At high intensity it rewrites for style too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DeepSeek over OpenAI
&lt;/h2&gt;

&lt;p&gt;Three reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost.&lt;/strong&gt; DeepSeek is roughly 1/10th the price of GPT-4o for comparable quality on grammar tasks. At the free tier usage levels, my API bill is literally under $2/month.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quality on structured output.&lt;/strong&gt; I tested both on the same 50-sample test set (emails, essays, blog posts). DeepSeek caught 91% of errors vs GPT-4o's 93%. The 2% gap isn't worth 10x the cost.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No content moderation false positives.&lt;/strong&gt; This is the one nobody talks about. OpenAI's moderation API sometimes flags academic writing about medical or legal topics. DeepSeek just checks the grammar.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Offline mode.&lt;/strong&gt; The Hemingway stats (passive voice, reading time, word count) are computed locally. The grammar check needs the API. I'd like to bundle a small on-device model via WebLLM eventually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Better mobile UX.&lt;/strong&gt; The tool works on mobile but the text area + results layout isn't great on narrow screens. Bootstrap or Tailwind would've helped but I wanted zero dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API key flow.&lt;/strong&gt; Right now users bring their own DeepSeek key. New DeepSeek users get 5M free tokens, which covers a LOT of grammar checks. But the UX of pasting an API key is friction. Considering a free tier with a shared key + rate limiting.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;→ &lt;a href="https://grammaraicheck.com/" rel="noopener noreferrer"&gt;grammaraicheck.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Completely free, no signup, no email. If you write in English regularly — especially if you're a non-native speaker — I'd love feedback on what's missing.&lt;/p&gt;

&lt;p&gt;Also have a comparison page if you're curious how it stacks up against Grammarly, ProWritingAid, and others: &lt;a href="https://grammaraicheck.com/best-ai-grammar-checkers/" rel="noopener noreferrer"&gt;Best AI Grammar Checkers 2026&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
