<?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: Kim</title>
    <description>The latest articles on DEV Community by Kim (@chillkimtestoss).</description>
    <link>https://dev.to/chillkimtestoss</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3780435%2F54a834da-b7a9-4e45-b57b-19e7040c80bd.png</url>
      <title>DEV Community: Kim</title>
      <link>https://dev.to/chillkimtestoss</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chillkimtestoss"/>
    <language>en</language>
    <item>
      <title>How to Format Your ChatGPT Resume into a Clean PDF (Free, No Sign Up)</title>
      <dc:creator>Kim</dc:creator>
      <pubDate>Wed, 18 Mar 2026 03:15:19 +0000</pubDate>
      <link>https://dev.to/chillkimtestoss/how-to-format-your-chatgpt-resume-into-a-clean-pdf-free-no-sign-up-101</link>
      <guid>https://dev.to/chillkimtestoss/how-to-format-your-chatgpt-resume-into-a-clean-pdf-free-no-sign-up-101</guid>
      <description>&lt;p&gt;You asked ChatGPT to write your resume. It gave you great bullet points, a strong summary, maybe even a cover letter.&lt;/p&gt;

&lt;p&gt;Then you pasted it into Word.&lt;/p&gt;

&lt;p&gt;And spent 20 minutes fighting margins, spacing, and font sizes. Changed one bullet point and the whole second page broke. Tried Google Docs instead — different problems, same frustration.&lt;/p&gt;

&lt;p&gt;Sound familiar? You're not alone. This is the gap nobody talks about: AI can &lt;em&gt;write&lt;/em&gt; your resume, but it can't &lt;em&gt;format&lt;/em&gt; it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with "Free" Resume Builders
&lt;/h2&gt;

&lt;p&gt;Your first instinct was probably to Google "free resume builder." You found Zety, Resume.io, or Resume Genius. You spent 30 minutes entering your info section by section. It looked great.&lt;/p&gt;

&lt;p&gt;Then you hit Download.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Subscribe for $24.95/month to download your resume as PDF."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your only free option? A plain text file. No formatting. No columns. Just the text you already had.&lt;/p&gt;

&lt;p&gt;This isn't a bug — it's their business model. Let you invest time, then charge you to get your own work back.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Actually Need
&lt;/h2&gt;

&lt;p&gt;You don't need a resume &lt;em&gt;builder&lt;/em&gt;. You already built it — ChatGPT did the hard part. You need a resume &lt;em&gt;formatter&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Something where you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paste your text&lt;/li&gt;
&lt;li&gt;See it formatted instantly&lt;/li&gt;
&lt;li&gt;Download the PDF&lt;/li&gt;
&lt;li&gt;No login, no email, no credit card&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OhMyDoc: Paste, Format, Download
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ohmydoc.vercel.app" rel="noopener noreferrer"&gt;OhMyDoc&lt;/a&gt; does exactly this. Here's the whole process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy your resume text from ChatGPT (or wherever you wrote it)&lt;/li&gt;
&lt;li&gt;Paste it into OhMyDoc&lt;/li&gt;
&lt;li&gt;See a formatted preview instantly&lt;/li&gt;
&lt;li&gt;Click Export PDF&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No account. No email. No "free trial." The PDF is yours.&lt;/p&gt;

&lt;p&gt;It's also open source — your resume text never leaves your browser. Nothing is stored on a server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is It ATS-Friendly?
&lt;/h2&gt;

&lt;p&gt;Yes. OhMyDoc outputs clean, single-column PDFs with standard fonts. No images, no columns that confuse parsers, no invisible text boxes. The kind of format that ATS systems can actually read.&lt;/p&gt;

&lt;p&gt;If you've been using Canva for your resume — stop. Canva resumes look beautiful but ATS systems can't parse them. (Ask any recruiter. They'll tell you the same thing.)&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use OhMyDoc vs. Other Tools
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your Situation&lt;/th&gt;
&lt;th&gt;Best Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"I need help &lt;em&gt;writing&lt;/em&gt; my resume"&lt;/td&gt;
&lt;td&gt;ChatGPT, Claude, or a career coach&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I have text and need it to &lt;em&gt;look good&lt;/em&gt;"&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;OhMyDoc&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I need a creative/design resume"&lt;/td&gt;
&lt;td&gt;Canva (but know ATS won't read it)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I need a full resume management system"&lt;/td&gt;
&lt;td&gt;Teal, Reactive Resume&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The 2-Minute Resume Workflow
&lt;/h2&gt;

&lt;p&gt;Here's what I recommend for anyone job hunting right now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write&lt;/strong&gt; your resume with ChatGPT or Claude (use the job description as context)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format&lt;/strong&gt; it with &lt;a href="https://ohmydoc.vercel.app" rel="noopener noreferrer"&gt;OhMyDoc&lt;/a&gt; — paste, preview, export&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check&lt;/strong&gt; the PDF by uploading it back to an ATS checker&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Apply&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total time from AI draft to submitted application: under 5 minutes.&lt;/p&gt;

&lt;p&gt;No accounts created. No subscriptions. No fighting with Word margins.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://ohmydoc.vercel.app" rel="noopener noreferrer"&gt;ohmydoc.vercel.app&lt;/a&gt; — paste your resume, get a PDF. That's the whole pitch.&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>resume</category>
      <category>jobsearch</category>
    </item>
    <item>
      <title>I Let AI Agents Build My Entire Side Project — Here's What Happened</title>
      <dc:creator>Kim</dc:creator>
      <pubDate>Sun, 15 Mar 2026 06:45:01 +0000</pubDate>
      <link>https://dev.to/chillkimtestoss/i-let-ai-agents-build-my-entire-side-project-heres-what-happened-2bbg</link>
      <guid>https://dev.to/chillkimtestoss/i-let-ai-agents-build-my-entire-side-project-heres-what-happened-2bbg</guid>
      <description>&lt;p&gt;I had a simple problem: every "free" resume formatter online requires an account, upsells you to a paid plan, or rewrites your content with AI. I just wanted to paste text, make it look decent, and save as PDF.&lt;/p&gt;

&lt;p&gt;So I did something weird — I let AI agents build the entire thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Frustration
&lt;/h2&gt;

&lt;p&gt;Here's what happens when you google "free resume formatter":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Canva&lt;/strong&gt; — free to format, $12.99/month to export without watermark&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resume.io&lt;/strong&gt; — free to build, paywall on download&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zety&lt;/strong&gt; — 14-day "trial" that auto-charges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Docs&lt;/strong&gt; — actually free but requires opening Google Docs (the horror)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every single one wants your email. Most want your credit card. None of them just... format text and let you save it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Experiment
&lt;/h2&gt;

&lt;p&gt;I gave Claude Code a simple prompt: build a web app where I paste my resume as plain text on the left, see it formatted on the right, and can export to PDF.&lt;/p&gt;

&lt;p&gt;The result is &lt;a href="https://ohmydoc.vercel.app" rel="noopener noreferrer"&gt;OhMyDoc&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the AI Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The core flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Left pane: paste your resume or cover letter as plain text&lt;/li&gt;
&lt;li&gt;Right pane: instantly see it with clean, professional typography&lt;/li&gt;
&lt;li&gt;One click: export to PDF via the browser's print dialog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The surprise feature — XML editor:&lt;/strong&gt;&lt;br&gt;
This is the part I didn't ask for but love. When AI generates your resume content (ChatGPT, Claude, etc.), you always want to change a few words before sending. Most tools force you back through the AI. OhMyDoc has an XML editor that lets you tweak specific text directly in the document structure.&lt;/p&gt;

&lt;p&gt;Why is this useful? Because when an AI writes "Spearheaded cross-functional synergies" and you want to change it to "Led the project," you don't need another AI round-trip. Just edit it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it doesn't do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No login or signup&lt;/li&gt;
&lt;li&gt;No email capture&lt;/li&gt;
&lt;li&gt;No AI rewriting your content ("Your content has been formatted but not rewritten")&lt;/li&gt;
&lt;li&gt;No data leaves your browser&lt;/li&gt;
&lt;li&gt;No freemium upsell — it's genuinely, completely free&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Reality
&lt;/h2&gt;

&lt;p&gt;ClaudeCode built the entire thing as a Next.js app deployed on Vercel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Framework:&lt;/strong&gt; Next.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting:&lt;/strong&gt; Vercel (free tier)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; None — everything runs client-side&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly cost:&lt;/strong&gt; $0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI involvement in runtime:&lt;/strong&gt; Zero — the AI built the app, but the app itself uses no AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point is important. OhMyDoc doesn't use GPT or Claude to format your document. It uses deterministic parsing and CSS. Same input, same output, every time. The AI wrote the code; the code does the work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned About AI-Built Projects
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;It's fast.&lt;/strong&gt; The initial version was functional in under an hour. Styling, layout, PDF export, sample templates — all generated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It over-engineers.&lt;/strong&gt; The XML editor? I didn't ask for it. Claude Code decided the app needed it and built it. Turns out it was right — it's genuinely the most useful feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It under-designs.&lt;/strong&gt; The visual design is competent but not memorable. An AI can build a clean UI but it won't build a &lt;em&gt;distinctive&lt;/em&gt; one. Every AI-built app has the same Tailwind energy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It ships.&lt;/strong&gt; This is the part that matters. The app works. It solves the problem. It's live, it's free, and it took negligible human effort to build.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://ohmydoc.vercel.app" rel="noopener noreferrer"&gt;OhMyDoc&lt;/a&gt; — paste your resume, get a clean PDF. Try the sample to see it in action.&lt;/p&gt;

&lt;p&gt;The entire source is on &lt;a href="https://github.com/kimwwk/ohmydoc-using-claude-code-agent" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've built something interesting with AI coding agents, I'd love to hear about it in the comments. Especially curious about projects where the AI surprised you with features you didn't ask for.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by AI agents. Maintained by a human who just wanted a simple PDF.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Built a Personal Trainer Matching Algorithm (That Actually Works)</title>
      <dc:creator>Kim</dc:creator>
      <pubDate>Sat, 14 Mar 2026 03:26:50 +0000</pubDate>
      <link>https://dev.to/chillkimtestoss/how-i-built-a-personal-trainer-matching-algorithm-that-actually-works-17f4</link>
      <guid>https://dev.to/chillkimtestoss/how-i-built-a-personal-trainer-matching-algorithm-that-actually-works-17f4</guid>
      <description>&lt;p&gt;Most people find their personal trainer the same way they find a plumber: Google Maps, check a few reviews, and hope for the best.&lt;/p&gt;

&lt;p&gt;I thought we could do better.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Here's what happens when you search "personal trainer Toronto":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Google shows you whoever paid for ads&lt;/li&gt;
&lt;li&gt;Yelp shows you whoever has the most reviews (correlation with quality: questionable)&lt;/li&gt;
&lt;li&gt;Instagram shows you whoever posts the most shirtless photos&lt;/li&gt;
&lt;li&gt;Your friend recommends whoever &lt;em&gt;they&lt;/em&gt; like — which might be a terrible fit for you&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these answer the actual question: &lt;strong&gt;will this trainer's coaching style work for me?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A powerlifter who wants someone screaming at them during sets needs a very different trainer than someone recovering from an injury who wants gentle guidance. Both are valid. Neither will be happy with the other's trainer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hypothesis
&lt;/h2&gt;

&lt;p&gt;What if we could match people to trainers the same way dating apps match people — not on location or price, but on &lt;strong&gt;compatibility&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://fitmatch-inky.vercel.app" rel="noopener noreferrer"&gt;FitMatch&lt;/a&gt; to test this. It's a 60-second quiz that scores you against 30 real Toronto personal trainers across 5 dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Five Dimensions
&lt;/h2&gt;

&lt;p&gt;After researching what actually matters in a trainer-client relationship, I landed on five scoring dimensions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Training Goal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;A bodybuilding coach and a rehab specialist are different species&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coaching Style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;td&gt;Drill sergeant vs. supportive guide — this is the #1 mismatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feedback Style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;td&gt;Some people want data and metrics. Others want 'great job, keep going'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Programming Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;td&gt;Rigid periodized plans vs. flexible 'let's see how you feel today'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Check-in Frequency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;Daily accountability vs. weekly touchpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The weights aren't arbitrary. Training goal gets 30% because if a trainer specializes in marathon prep and you want to powerlift, nothing else matters. Check-ins get 10% because it's the easiest dimension to adjust.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scoring Math
&lt;/h2&gt;

&lt;p&gt;Each dimension produces a score from 0-100 based on how closely the user's answer matches the trainer's profile.&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="nx"&gt;fitScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;goalMatch&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;styleMatch&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feedbackMatch&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structureMatch&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkinMatch&lt;/span&gt; &lt;span class="err"&gt;×&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each dimension, matching works like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exact match:&lt;/strong&gt; 100 points&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adjacent preference:&lt;/strong&gt; 50-75 points (e.g., 'structured' trainer with a 'somewhat flexible' user)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opposite ends:&lt;/strong&gt; 0-25 points&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a score from 0-100 for every trainer, which maps to labels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🟢 &lt;strong&gt;75-100:&lt;/strong&gt; 'Strong fit' — your styles align&lt;/li&gt;
&lt;li&gt;🟡 &lt;strong&gt;50-74:&lt;/strong&gt; 'Decent fit' — could work with some adjustment&lt;/li&gt;
&lt;li&gt;🔴 &lt;strong&gt;Below 50:&lt;/strong&gt; 'Different styles' — probably not your person&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Not Use AI/ML?
&lt;/h2&gt;

&lt;p&gt;I hear you. 'Why not throw embeddings at this?'&lt;/p&gt;

&lt;p&gt;Because the dataset is 30 trainers, not 30,000. Machine learning on 30 data points is just overfitting with extra steps. The weighted scoring approach is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transparent:&lt;/strong&gt; Users can understand why they matched&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debuggable:&lt;/strong&gt; When a match feels wrong, I can trace exactly which dimension caused it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tunable:&lt;/strong&gt; Adjusting weights based on user feedback is trivial&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast:&lt;/strong&gt; No model inference, no API calls — runs entirely client-side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes the boring solution is the right solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cold Start Problem
&lt;/h2&gt;

&lt;p&gt;The tricky part wasn't the algorithm — it was getting trainer data. Trainers didn't sign up for this. I had to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Research 30 real Toronto trainers manually&lt;/li&gt;
&lt;li&gt;Infer their quiz answers based on their websites, social media, and client testimonials&lt;/li&gt;
&lt;li&gt;Build profiles that honestly represent their coaching style&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the uncomfortable truth about two-sided marketplaces: someone has to go first. My bet is that trainers will opt in &lt;em&gt;after&lt;/em&gt; they see 'someone took a quiz and matched with you as a Strong Fit — want their contact info?'&lt;/p&gt;

&lt;p&gt;That email pipeline isn't wired yet. Right now, FitMatch is a discovery tool: take the quiz, browse your matches, visit their websites directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The UX Decisions
&lt;/h2&gt;

&lt;p&gt;A few things I got right (I think):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One question per screen.&lt;/strong&gt; Early versions showed all 6 questions on one page. Completion rates were terrible. One-per-screen with tap-to-advance felt more like a personality quiz and less like a form. Completion jumped immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No account required.&lt;/strong&gt; Zero friction to results. You can take the quiz in 60 seconds and see every trainer ranked. Email capture is optional ('let your top matches know you're interested').&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Show all 30 trainers.&lt;/strong&gt; My instinct was to show only the top 5. But users want to scroll. Seeing a trainer ranked #22 with a 45% fit score actually &lt;em&gt;increases&lt;/em&gt; trust in the algorithm — 'oh, it's not just showing everyone as a perfect match.'&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;Nothing fancy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt; — pages + API routes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt; — hosting and edge functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No database&lt;/strong&gt; — trainer profiles are static JSON (for now)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total infra cost: $0/month.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Weight validation.&lt;/strong&gt; The 30/20/20/20/10 split was my best guess based on research. I should have A/B tested different weight distributions from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trainer opt-in first.&lt;/strong&gt; Bootstrapping with inferred profiles was pragmatic but creates a trust gap. If I were starting over, I'd cold-email 10 trainers first and build profiles collaboratively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer dimensions.&lt;/strong&gt; Five dimensions might be over-engineering it. I suspect goal + coaching style alone (two dimensions) would get you 80% of the matching accuracy. The other three add precision but also add quiz length.&lt;/p&gt;

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

&lt;p&gt;If you're in Toronto and looking for a trainer (or just curious), &lt;a href="https://fitmatch-inky.vercel.app" rel="noopener noreferrer"&gt;take the quiz&lt;/a&gt;. It's free, takes 60 seconds, and doesn't require an account.&lt;/p&gt;

&lt;p&gt;If you're a developer building a matching/recommendation system: weighted scoring is underrated. It's simple, interpretable, and works surprisingly well at small scale. Save the ML for when you have the data to justify it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building this as a solo side project. If you want to follow along or have feedback, drop a comment — I'm actively iterating based on what I hear.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>fitness</category>
    </item>
    <item>
      <title>I Analyzed 17 Popular GitHub Repos — Here's What Their Codebases Are Actually Made Of</title>
      <dc:creator>Kim</dc:creator>
      <pubDate>Sat, 07 Mar 2026 04:21:13 +0000</pubDate>
      <link>https://dev.to/chillkimtestoss/i-analyzed-17-popular-github-repos-heres-what-their-codebases-are-actually-made-of-1c8</link>
      <guid>https://dev.to/chillkimtestoss/i-analyzed-17-popular-github-repos-heres-what-their-codebases-are-actually-made-of-1c8</guid>
      <description>&lt;p&gt;I wanted to answer a simple question: &lt;strong&gt;what are popular open source projects actually made of?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not what their README says. Not what their marketing page claims. What does the code itself reveal?&lt;/p&gt;

&lt;p&gt;So I pointed &lt;a href="https://github.com/kimwwk/repocrunch" rel="noopener noreferrer"&gt;RepoCrunch&lt;/a&gt; — a deterministic repo analyzer I built — at 17 well-known GitHub repositories and collected the data.&lt;/p&gt;

&lt;p&gt;Here's what I found.&lt;/p&gt;

&lt;h2&gt;
  
  
  🦀 Rust is quietly eating JavaScript tooling
&lt;/h2&gt;

&lt;p&gt;This was the biggest surprise. Three "JavaScript ecosystem" tools have significant Rust codebases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;You'd think it's...&lt;/th&gt;
&lt;th&gt;Actually...&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;13.5% Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CSS/JS&lt;/td&gt;
&lt;td&gt;16.0% Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deno&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JavaScript runtime&lt;/td&gt;
&lt;td&gt;59.4% Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Next.js — the React meta-framework — is &lt;strong&gt;13.5% Rust&lt;/strong&gt;. Tailwind CSS is &lt;strong&gt;16% Rust&lt;/strong&gt;. These aren't Rust projects. They're JavaScript tools that have quietly moved performance-critical paths to Rust.&lt;/p&gt;

&lt;p&gt;And then there's Deno: marketed as a JavaScript/TypeScript runtime, but it's actually a &lt;strong&gt;Rust project&lt;/strong&gt; (59.4%) that &lt;em&gt;happens to run&lt;/em&gt; JavaScript.&lt;/p&gt;

&lt;p&gt;Meanwhile, &lt;strong&gt;uv&lt;/strong&gt; — Python's fastest package manager — is &lt;strong&gt;98.1% Rust&lt;/strong&gt;. A Python tool with essentially zero Python.&lt;/p&gt;

&lt;p&gt;The pattern is clear: &lt;strong&gt;Rust is becoming the systems language behind dynamic language ecosystems.&lt;/strong&gt; If you're building dev tools in 2026, Rust is the performance layer you reach for.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Dependency counts tell very different stories
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Direct Dependencies&lt;/th&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Django&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;87K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FastAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;96K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flask&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;71K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NestJS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;75K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Express&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;69K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VS Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;49&lt;/td&gt;
&lt;td&gt;182K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Angular&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;100K ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Django runs on 3 dependencies.&lt;/strong&gt; The most popular Python web framework, powering Instagram and Spotify, depends on just &lt;em&gt;three&lt;/em&gt; external packages.&lt;/p&gt;

&lt;p&gt;Compare that to Angular's &lt;strong&gt;104 direct dependencies&lt;/strong&gt;. That's not inherently bad — they're a full framework with more surface area. But it's a fundamentally different philosophy: &lt;em&gt;own everything&lt;/em&gt; vs. &lt;em&gt;compose from parts&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The Python ecosystem clearly leans minimal. FastAPI (5 deps) and Flask (6 deps) follow the same pattern. Node.js frameworks consistently pull in more.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏥 Open issues don't mean what you think
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Open Issues&lt;/th&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;Ratio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flask&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;71K&lt;/td&gt;
&lt;td&gt;1 per 23,777 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NestJS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;75K&lt;/td&gt;
&lt;td&gt;1 per 1,783 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tailwind&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;84&lt;/td&gt;
&lt;td&gt;94K&lt;/td&gt;
&lt;td&gt;1 per 1,118 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FastAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;96K&lt;/td&gt;
&lt;td&gt;1 per 662 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Angular&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1,131&lt;/td&gt;
&lt;td&gt;100K&lt;/td&gt;
&lt;td&gt;1 per 88 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prisma&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,505&lt;/td&gt;
&lt;td&gt;45K&lt;/td&gt;
&lt;td&gt;1 per 18 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;uv&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,716&lt;/td&gt;
&lt;td&gt;80K&lt;/td&gt;
&lt;td&gt;1 per 30 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;12,155&lt;/td&gt;
&lt;td&gt;111K&lt;/td&gt;
&lt;td&gt;1 per 9 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VS Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;14,704&lt;/td&gt;
&lt;td&gt;182K&lt;/td&gt;
&lt;td&gt;1 per 12 ⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Flask has &lt;strong&gt;3 open issues&lt;/strong&gt;. VS Code has &lt;strong&gt;14,704&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Does that mean Flask is better maintained? Not exactly. Flask is a mature, stable project with a narrow scope. VS Code is an IDE used by millions — every edge case becomes an issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue count scales with surface area and user base, not with code quality.&lt;/strong&gt; Rust (the language) has 12K open issues because building a compiler for millions of developers generates a &lt;em&gt;lot&lt;/em&gt; of edge cases.&lt;/p&gt;

&lt;p&gt;The interesting outlier is &lt;strong&gt;Prisma&lt;/strong&gt; — 2,505 open issues against just 45K stars. That's one of the highest issue-to-star ratios in this dataset. It suggests either a broader surface area than its star count implies, or maintenance challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧬 TypeScript won — but not everywhere
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Primary Language&lt;/th&gt;
&lt;th&gt;Projects&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Angular, VS Code, NestJS, Vue, Prisma, Supabase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JavaScript&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;React, Svelte, Express, Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Django, Flask, FastAPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;uv, Deno, Rust-lang&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;TypeScript is the plurality leader for large-scale projects. But look more closely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React is still primarily JavaScript&lt;/strong&gt; (68.1%) — Facebook's flagship UI library hasn't fully migrated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Svelte is 71.8% JavaScript&lt;/strong&gt; — Rich Harris chose to keep the compiler in JS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vue went all-in on TypeScript&lt;/strong&gt; (96.6%) — a deliberate rewrite choice for v3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The JS-vs-TS split often comes down to project age and rewrite ambition. Vue rewrote from scratch for v3 → TypeScript. React is incrementally migrating → still mostly JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  👥 Who actually builds these things?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Contributors&lt;/th&gt;
&lt;th&gt;Age (years)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8,257&lt;/td&gt;
&lt;td&gt;15.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4,060&lt;/td&gt;
&lt;td&gt;9.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Django&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3,405&lt;/td&gt;
&lt;td&gt;19.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VS Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,940&lt;/td&gt;
&lt;td&gt;10.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Angular&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2,577&lt;/td&gt;
&lt;td&gt;11.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;React&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1,971&lt;/td&gt;
&lt;td&gt;12.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supabase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1,852&lt;/td&gt;
&lt;td&gt;5.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Express&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;377&lt;/td&gt;
&lt;td&gt;14.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tailwind&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;344&lt;/td&gt;
&lt;td&gt;8.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prisma&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;355&lt;/td&gt;
&lt;td&gt;5.7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Express — the backbone of Node.js servers — has been maintained by just &lt;strong&gt;377 contributors&lt;/strong&gt; over 14.6 years. Compare that to Next.js with &lt;strong&gt;4,060 contributors&lt;/strong&gt; in under 10 years.&lt;/p&gt;

&lt;p&gt;Supabase stands out: 1,852 contributors in just 5.6 years. That's community velocity.&lt;/p&gt;

&lt;p&gt;And Tailwind CSS — used on millions of websites — has just 344 contributors. A small team can build something with massive reach.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I got this data
&lt;/h2&gt;

&lt;p&gt;All of this came from &lt;a href="https://github.com/kimwwk/repocrunch" rel="noopener noreferrer"&gt;RepoCrunch&lt;/a&gt; — a tool I built that analyzes GitHub repos into structured JSON. No AI, no LLMs, fully deterministic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;repocrunch
repocrunch analyze vercel/next.js &lt;span class="nt"&gt;--pretty&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It parses real repo data — languages, dependencies, CI setup, health metrics — and gives you structured facts. I built it because I was tired of asking ChatGPT "what's this repo built with?" and getting hallucinated answers.&lt;/p&gt;

&lt;p&gt;It also works as an &lt;a href="https://github.com/kimwwk/repocrunch#mcp-server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;, so your AI coding assistant can look up real repo data instead of guessing.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The raw data is what it is.&lt;/strong&gt; Next.js is 13.5% Rust. Django has 3 dependencies. Flask has 3 open issues. These aren't opinions — they're measurements.&lt;/p&gt;

&lt;p&gt;What surprised you most? I'd love to hear what repos you'd want to analyze next.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://getjustgo.com" rel="noopener noreferrer"&gt;getjustgo.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




</description>
      <category>github</category>
      <category>opensource</category>
      <category>python</category>
      <category>devtools</category>
    </item>
    <item>
      <title>I Analyzed 8 Popular Frameworks — Here's What Their Codebases Are Actually Hiding</title>
      <dc:creator>Kim</dc:creator>
      <pubDate>Fri, 06 Mar 2026 17:54:39 +0000</pubDate>
      <link>https://dev.to/chillkimtestoss/i-analyzed-8-popular-frameworks-heres-what-their-codebases-are-actually-hiding-3ej</link>
      <guid>https://dev.to/chillkimtestoss/i-analyzed-8-popular-frameworks-heres-what-their-codebases-are-actually-hiding-3ej</guid>
      <description>&lt;p&gt;GitHub tells you the "primary language" of a repo. That label is... incomplete.&lt;/p&gt;

&lt;p&gt;I've been building a tool that pulls structured data from any GitHub repo — language breakdown, dependencies, health metrics, CI setup, security signals — and decided to point it at some of the most popular frameworks on the planet.&lt;/p&gt;

&lt;p&gt;A few things caught me off guard.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Data
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;Open Issues&lt;/th&gt;
&lt;th&gt;Contributors&lt;/th&gt;
&lt;th&gt;Hidden Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;td&gt;137.6K&lt;/td&gt;
&lt;td&gt;3,298&lt;/td&gt;
&lt;td&gt;4,037&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;13% Rust&lt;/strong&gt; (Turbopack)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;132.3K&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;5.4% Assembly&lt;/strong&gt; (runtime)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FastAPI&lt;/td&gt;
&lt;td&gt;94.9K&lt;/td&gt;
&lt;td&gt;168&lt;/td&gt;
&lt;td&gt;886&lt;/td&gt;
&lt;td&gt;Only 5 direct dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Django&lt;/td&gt;
&lt;td&gt;86.7K&lt;/td&gt;
&lt;td&gt;405&lt;/td&gt;
&lt;td&gt;3,383&lt;/td&gt;
&lt;td&gt;Zero Docker config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flask&lt;/td&gt;
&lt;td&gt;71.1K&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;862&lt;/td&gt;
&lt;td&gt;3 issues. That's it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Express&lt;/td&gt;
&lt;td&gt;68.7K&lt;/td&gt;
&lt;td&gt;183&lt;/td&gt;
&lt;td&gt;373&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100% JavaScript&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rails&lt;/td&gt;
&lt;td&gt;58.2K&lt;/td&gt;
&lt;td&gt;1,457&lt;/td&gt;
&lt;td&gt;6,906&lt;/td&gt;
&lt;td&gt;Most contributors of any framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LangChain&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;407&lt;/td&gt;
&lt;td&gt;3,631&lt;/td&gt;
&lt;td&gt;3,631 contributors in 2 years&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Surprises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Next.js is 13% Rust
&lt;/h3&gt;

&lt;p&gt;Not a typo. Turbopack — the Rust-based bundler — accounts for a significant chunk of the Next.js codebase. GitHub labels it "JavaScript" because that's the plurality language, but the reality is JS (56%) + TypeScript (30%) + Rust (13%).&lt;/p&gt;

&lt;p&gt;If you're evaluating Next.js as a dependency, "it's a JavaScript framework" is technically true but practically misleading. Turbopack means Rust compilation is part of your build chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flask Has 3 Open Issues
&lt;/h3&gt;

&lt;p&gt;Three. On a 71,000-star project.&lt;/p&gt;

&lt;p&gt;Compare that to Next.js (3,298) or Rails (1,457). The Pallets team runs the tightest ship in open source. Some people see low issue counts and think "dead project." Flask proves that's wrong — it's just aggressively managed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Express Is Still 100% JavaScript
&lt;/h3&gt;

&lt;p&gt;No TypeScript migration. No Rust rewrite. No drama. Sixteen years, 68K stars, pure JavaScript.&lt;/p&gt;

&lt;p&gt;Every new Node framework launches in TypeScript these days. Express just... doesn't. And it works fine. Sometimes boring is the feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go Is 5.4% Assembly
&lt;/h3&gt;

&lt;p&gt;Makes total sense for a language runtime and compiler, but GitHub's language bar rounds this away. You'd never know from the repo page that a meaningful chunk of Go is hand-written assembly for the garbage collector and runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  FastAPI Has Only 5 Direct Dependencies
&lt;/h3&gt;

&lt;p&gt;For a full-featured web framework, that's remarkably lean: Starlette, Pydantic, typing-extensions, typing-inspection, annotated-doc. Minimal dependency surface = fewer supply chain risks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rails Has the Most Contributors by Far
&lt;/h3&gt;

&lt;p&gt;6,906 contributors — nearly double LangChain (3,631) despite Rails being 18 years old. That's not just open source; that's a civilization.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Got This Data
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://github.com/kimwwk/repocrunch" rel="noopener noreferrer"&gt;RepoCrunch&lt;/a&gt; — a Python CLI that analyzes any GitHub repo and returns structured JSON. No AI, no hallucination, just deterministic data from the GitHub API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;repocrunch
repocrunch analyze vercel/next.js &lt;span class="nt"&gt;--pretty&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns everything you see above: language breakdown, dependency count, CI setup, maintenance status, security signals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Structured Output Matters
&lt;/h3&gt;

&lt;p&gt;The real reason I built this: I wanted my AI coding tools to have &lt;em&gt;factual&lt;/em&gt; repo data instead of guessing. RepoCrunch has a built-in MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repocrunch mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add it to your Claude Desktop or Cursor config, and your AI assistant can answer "is this repo safe to depend on?" with actual data instead of its training weights.&lt;/p&gt;

&lt;p&gt;Sample output (FastAPI):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stars"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;94912&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"primary_language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tech_stack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"framework"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Starlette"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"package_manager"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pdm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"key_deps"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"starlette"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pydantic"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"health"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"open_issues"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;168&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"contributors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;886&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"commit_frequency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"maintenance_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"actively_maintained"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm thinking about running this against the top 50 Python packages and publishing the results. If there's interest, I'll do a follow-up with more repos and more surprising findings.&lt;/p&gt;

&lt;p&gt;Curious what metrics you'd actually want to see when evaluating a dependency. Stars? Commit frequency? Something else entirely?&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/kimwwk/repocrunch" rel="noopener noreferrer"&gt;kimwwk/repocrunch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyPI: &lt;code&gt;pip install repocrunch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;MCP mode: &lt;code&gt;repocrunch mcp&lt;/code&gt; (for Claude/Cursor integration)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>python</category>
      <category>opensource</category>
      <category>devtools</category>
    </item>
    <item>
      <title>My AI Agent Kept Recommending Abandoned Repos. So I Built RepoCrunch.</title>
      <dc:creator>Kim</dc:creator>
      <pubDate>Thu, 19 Feb 2026 04:42:05 +0000</pubDate>
      <link>https://dev.to/chillkimtestoss/my-ai-agent-kept-recommending-abandoned-repos-so-i-built-repocrunch-o00</link>
      <guid>https://dev.to/chillkimtestoss/my-ai-agent-kept-recommending-abandoned-repos-so-i-built-repocrunch-o00</guid>
      <description>&lt;p&gt;I've been building AI agents that evaluate GitHub repos — picking dependencies, reviewing codebases, comparing tools. The problem? They hallucinate.&lt;/p&gt;

&lt;p&gt;Ask an LLM "is this repo well-maintained?" and you'll get a confident answer based on vibes. Not data. My agent kept recommending packages that were archived, had 2 commits in the last year, or had open CVEs.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;RepoCrunch&lt;/strong&gt; — a CLI tool and MCP server that gives AI agents ground-truth GitHub intelligence.&lt;/p&gt;

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

&lt;p&gt;Point it at any public GitHub repo and get deterministic, structured JSON:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tech stack detection&lt;/strong&gt; — languages, frameworks, build tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency analysis&lt;/strong&gt; — what it uses, version info&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health metrics&lt;/strong&gt; — stars, issues, contributors, commit frequency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security indicators&lt;/strong&gt; — CI/CD setup, known vulnerability patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture signals&lt;/strong&gt; — project structure, patterns used&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key word is &lt;strong&gt;deterministic&lt;/strong&gt;. Same repo, same output. No interpretation, no hallucination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three ways to use it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;repocrunch
repocrunch analyze https://github.com/fastapi/fastapi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. MCP Server (for AI agents)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repocrunch mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop this into your Claude Desktop, Cursor, or any MCP-compatible client. Your agent gets real repo data instead of guessing.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. REST API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repocrunch serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why MCP matters here
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol lets AI agents call external tools. When your agent needs to evaluate a dependency, it can call RepoCrunch and get facts — not generate them from training data.&lt;/p&gt;

&lt;p&gt;This is the difference between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ "FastAPI appears to be well-maintained based on my knowledge"&lt;/li&gt;
&lt;li&gt;✅ "FastAPI has 847 contributors, 12.3k commits, last push 2 hours ago, MIT license, CI passing"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The real use case
&lt;/h2&gt;

&lt;p&gt;I built this for my own AI agent workflow. When my agent evaluates whether to use a library, it runs RepoCrunch first. The structured output feeds directly into the decision — no guessing.&lt;/p&gt;

&lt;p&gt;But it works for anyone who needs repo intelligence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dependency auditing&lt;/strong&gt; — are your deps actually maintained?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Due diligence&lt;/strong&gt; — evaluating repos before adoption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio monitoring&lt;/strong&gt; — tracking health of repos you depend on&lt;/li&gt;
&lt;/ul&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;repocrunch
repocrunch analyze https://github.com/your-favorite-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/kimwwk/repocrunch" rel="noopener noreferrer"&gt;github.com/kimwwk/repocrunch&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;PyPI:&lt;/strong&gt; &lt;a href="https://pypi.org/project/repocrunch" rel="noopener noreferrer"&gt;pypi.org/project/repocrunch&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open source, MIT licensed. Feedback welcome — especially from folks building MCP toolchains.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built this as a solo dev scratching my own itch. If you're doing anything with AI agents + code evaluation, I'd love to hear how you're solving the hallucination problem.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
    </item>
  </channel>
</rss>
