<?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: MattQ</title>
    <description>The latest articles on DEV Community by MattQ (@mattqdev).</description>
    <link>https://dev.to/mattqdev</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%2F3462033%2F574cf805-7304-4445-bf10-aa7eae7dec26.png</url>
      <title>DEV Community: MattQ</title>
      <link>https://dev.to/mattqdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mattqdev"/>
    <language>en</language>
    <item>
      <title>I built a tool that turns any GitHub repo into a tech-stack card - Discover Stack Fingerprint</title>
      <dc:creator>MattQ</dc:creator>
      <pubDate>Thu, 01 Oct 2026 09:27:27 +0000</pubDate>
      <link>https://dev.to/mattqdev/i-built-a-tool-that-turns-any-github-repo-into-a-tech-stack-card-discover-stack-fingerprint-15mp</link>
      <guid>https://dev.to/mattqdev/i-built-a-tool-that-turns-any-github-repo-into-a-tech-stack-card-discover-stack-fingerprint-15mp</guid>
      <description>&lt;p&gt;Every README has the same section: a wall of hand-picked shields.io badges, half of them out of date. The project moved from Webpack to Vite two years ago, but the badge is still there.&lt;/p&gt;

&lt;p&gt;I wanted the opposite: &lt;strong&gt;point a tool at a repo and let the repo tell you what it's built with.&lt;/strong&gt; That's &lt;a href="https://stackfingerprint.vercel.app" rel="noopener noreferrer"&gt;Stack Fingerprint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackfingerprint.vercel.app/?repo=mattqdev/stackfingerprint" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fmattqdev%2Fstackfingerprint%2Fmain%2Fassets%2Fstack-fingerprint.svg" alt="Stack Fingerprint card" width="600" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That card above is generated from the Stack Fingerprint repo itself. Nobody typed "Next.js" or "Tailwind" anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it in 10 seconds
&lt;/h2&gt;

&lt;p&gt;Paste this into your README, replacing &lt;code&gt;OWNER/REPO&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;![Stack Fingerprint&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://stackfingerprint.vercel.app/api/card?repo=OWNER/REPO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;](https://stackfingerprint.vercel.app/?repo=OWNER/REPO)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No token, no sign-up, no config file.&lt;/p&gt;

&lt;p&gt;If you'd rather tweak it visually, the &lt;a href="https://stackfingerprint.vercel.app" rel="noopener noreferrer"&gt;web builder&lt;/a&gt; gives you a live preview with 10+ themes, 10 layouts (&lt;code&gt;classic&lt;/code&gt;, &lt;code&gt;terminal&lt;/code&gt;, &lt;code&gt;banner&lt;/code&gt;, &lt;code&gt;cards&lt;/code&gt;…), four sizes and different icon styles, then copies the Markdown or HTML snippet for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  How detection works
&lt;/h2&gt;

&lt;p&gt;The scanner makes &lt;strong&gt;one&lt;/strong&gt; call to the GitHub Git Trees API with &lt;code&gt;recursive=1&lt;/code&gt;, which returns the entire file tree flattened. No crawling directory by directory, so a scan costs a single request no matter how deep the repo is.&lt;/p&gt;

&lt;p&gt;From there it runs two passes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. File signals.&lt;/strong&gt; Each technology is a small object with a &lt;code&gt;check&lt;/code&gt; function that runs against file paths:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;astro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Astro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#FF5D01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;textColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ffffff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;iconSlug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;astro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;framework&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/^astro&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;config/&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;f&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;&lt;code&gt;astro.config.mjs&lt;/code&gt; exists? It's an Astro project. &lt;code&gt;Dockerfile&lt;/code&gt;? Docker. &lt;code&gt;*.tf&lt;/code&gt;? Terraform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Manifest signals.&lt;/strong&gt; Lots of libraries don't have a config file (think &lt;code&gt;zod&lt;/code&gt; or &lt;code&gt;@supabase/supabase-js&lt;/code&gt;), so the scanner also reads &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;pyproject.toml&lt;/code&gt;, &lt;code&gt;Gemfile&lt;/code&gt; and &lt;code&gt;composer.json&lt;/code&gt; and maps dependencies to signals:&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;const&lt;/span&gt; &lt;span class="nx"&gt;DEP_SIGNALS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nextjs&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="s2"&gt;@sveltejs/kit&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="s2"&gt;sveltekit&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="s2"&gt;@prisma/client&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="s2"&gt;prisma&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="s2"&gt;drizzle-orm&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="s2"&gt;drizzle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;vitest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vitest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also remembers &lt;em&gt;where&lt;/em&gt; each dependency came from. Anything that only shows up in &lt;code&gt;devDependencies&lt;/code&gt; gets tagged as dev-only, and that turned out to matter a lot (more on that below).&lt;/p&gt;

&lt;p&gt;Right now there are 200+ signals across languages, frameworks, UI libraries, databases, testing, build tools and infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that taught me how GitHub serves images
&lt;/h2&gt;

&lt;p&gt;The first version looked perfect on the website and broken on GitHub. Every icon was missing.&lt;/p&gt;

&lt;p&gt;The SVG used &lt;code&gt;&amp;lt;image href="https://cdn.../react.svg"&amp;gt;&lt;/code&gt; for each logo. Problem: GitHub doesn't serve README images directly. It proxies them through &lt;strong&gt;Camo&lt;/strong&gt;, which serves them with a strict Content Security Policy (&lt;code&gt;img-src data:&lt;/code&gt;). An SVG loaded through Camo can't fetch any external resource, so every icon was blocked.&lt;/p&gt;

&lt;p&gt;The fix: resolve icons server-side from the &lt;a href="https://simpleicons.org" rel="noopener noreferrer"&gt;&lt;code&gt;simple-icons&lt;/code&gt;&lt;/a&gt; npm package and inline each one as a base64 &lt;code&gt;data:&lt;/code&gt; URI inside the SVG. The card is now a single self-contained file with zero external requests, which also makes it faster and makes caching straightforward.&lt;/p&gt;

&lt;p&gt;If you're ever building a dynamic README image, keep this in mind: &lt;strong&gt;the SVG must be fully self-contained.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Listening to feedback: "too many badges"
&lt;/h2&gt;

&lt;p&gt;After the first launch, the feedback was clear and fair:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some detected technologies were unused, false positives, or not worth showing.&lt;/li&gt;
&lt;li&gt;In monorepos, a full scan picked up signals from unrelated sub-projects.&lt;/li&gt;
&lt;li&gt;Long lists of pills put contributors off and gave a misleading picture of the real stack.&lt;/li&gt;
&lt;li&gt;An image from a third-party domain in your README is a supply-chain risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these became a feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filtering.&lt;/strong&gt; &lt;code&gt;categoryFilter&lt;/code&gt; decides what the card shows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Shows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Everything, with dev-only signals dimmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;prodonly&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only production dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;top&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only languages + frameworks, max 5: the minimal badge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Monorepos.&lt;/strong&gt; &lt;code&gt;?path=apps/web&lt;/code&gt; scans a single sub-directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config file.&lt;/strong&gt; Drop a &lt;code&gt;.stackfingerprint.json&lt;/code&gt; in your repo for full control:&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;"ignore"&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;"babel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pin"&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;"nextjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"labels"&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;"nextjs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Next.js 14"&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;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps/web"&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;p&gt;&lt;strong&gt;Supply-chain safety.&lt;/strong&gt; This was the most important one. Embedding an image from a third-party domain in a popular README means trusting whoever owns that domain. So I built a &lt;strong&gt;GitHub Action&lt;/strong&gt; that generates the SVG on GitHub's runners and commits it to your repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Stack Fingerprint&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;4&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt; &lt;span class="c1"&gt;# weekly refresh&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;card&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mattqdev/stackfingerprint-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scanner&lt;/span&gt;
          &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;classic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your README then points to a local file (&lt;code&gt;./assets/stack-fingerprint.svg&lt;/code&gt;), served by GitHub. No runtime dependency on my server, and it refreshes on every push. If you don't want to trust a third-party Action either, the repo has a plain &lt;code&gt;curl&lt;/code&gt; workflow you can audit line by line, or you can deploy your own instance on Vercel in one click.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;Fittingly, here's what it's built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt; (App Router) for the builder UI and the &lt;code&gt;/api/card&lt;/code&gt; route&lt;/li&gt;
&lt;li&gt;A hand-written &lt;strong&gt;SVG builder&lt;/strong&gt;, no canvas or headless browser, just string templates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;simple-icons&lt;/strong&gt; for logos, inlined at render time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; for the site&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt; for the showcase of projects using the card&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt; for hosting, with &lt;code&gt;Cache-Control&lt;/code&gt; + &lt;code&gt;stale-while-revalidate&lt;/code&gt; to keep GitHub's rate limits happy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎃 Hacktoberfest: come contribute
&lt;/h2&gt;

&lt;p&gt;Stack Fingerprint is taking part in &lt;strong&gt;Hacktoberfest&lt;/strong&gt;, and it's a really friendly place for a first PR. Most &lt;a href="https://github.com/mattqdev/stackfingerprint/issues?q=is%3Aopen+label%3A%22good+first+issue%22" rel="noopener noreferrer"&gt;&lt;code&gt;good first issue&lt;/code&gt;&lt;/a&gt;s are self-contained:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Add a technology&lt;/strong&gt;: one object in &lt;code&gt;src/data/signals.js&lt;/code&gt; (plus one line in the dependency map if needed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a theme&lt;/strong&gt;: one entry in &lt;code&gt;src/data/themes.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each issue tells you exactly which files to touch. Is your favorite framework missing from the card? That's your PR. 😉&lt;/p&gt;




&lt;p&gt;👉 &lt;strong&gt;Try it:&lt;/strong&gt; &lt;a href="https://stackfingerprint.vercel.app" rel="noopener noreferrer"&gt;stackfingerprint.vercel.app&lt;/a&gt;&lt;br&gt;
⭐ &lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/mattqdev/stackfingerprint" rel="noopener noreferrer"&gt;github.com/mattqdev/stackfingerprint&lt;/a&gt;&lt;br&gt;
⚙️ &lt;strong&gt;Action:&lt;/strong&gt; &lt;a href="https://github.com/marketplace/actions/stack-fingerprint" rel="noopener noreferrer"&gt;GitHub Marketplace&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the card in your README? &lt;a href="https://github.com/mattqdev/stackfingerprint/issues/new?template=4_showcase.yml" rel="noopener noreferrer"&gt;Open a showcase request&lt;/a&gt; and I'll feature your project on the site.&lt;/p&gt;

&lt;p&gt;What would you want it to detect next? Tell me in the comments 👇&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>hacktoberfest</category>
      <category>cli</category>
    </item>
    <item>
      <title>Thank you for your valuable fix! Our repo needed this a lot!</title>
      <dc:creator>MattQ</dc:creator>
      <pubDate>Fri, 06 Feb 2026 14:06:34 +0000</pubDate>
      <link>https://dev.to/mattqdev/thank-you-for-your-valuable-fix-our-repo-needed-this-a-lot-4coh</link>
      <guid>https://dev.to/mattqdev/thank-you-for-your-valuable-fix-our-repo-needed-this-a-lot-4coh</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/oleksandrakordonets/fixing-the-bouncingball-trail-background-bug-4p9f" class="crayons-story__hidden-navigation-link"&gt;Fixing the BouncingBall “trail” background bug&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
      &lt;a href="https://dev.to/oleksandrakordonets/fixing-the-bouncingball-trail-background-bug-4p9f" class="crayons-article__context-note crayons-article__context-note__feed"&gt;&lt;p&gt;Hacktoberfest: Contribution Chronicles&lt;/p&gt;

&lt;/a&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/oleksandrakordonets" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3482391%2Fe5e8d0ed-b15e-4c6c-8f76-25d12df2c19d.png" alt="oleksandrakordonets profile" class="crayons-avatar__image" width="420" height="420"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/oleksandrakordonets" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Oleksandra
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Oleksandra
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" width="166" height="102"&gt;&lt;/a&gt;
                
              
              &lt;div id="story-author-preview-content-2963595" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/oleksandrakordonets" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3482391%2Fe5e8d0ed-b15e-4c6c-8f76-25d12df2c19d.png" class="crayons-avatar__image" alt="" width="420" height="420"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Oleksandra&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/oleksandrakordonets/fixing-the-bouncingball-trail-background-bug-4p9f" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 27 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/oleksandrakordonets/fixing-the-bouncingball-trail-background-bug-4p9f" id="article-link-2963595"&gt;
          Fixing the BouncingBall “trail” background bug
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/hacktoberfest"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;hacktoberfest&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/frontend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;frontend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/oleksandrakordonets/fixing-the-bouncingball-trail-background-bug-4p9f" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;9&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/oleksandrakordonets/fixing-the-bouncingball-trail-background-bug-4p9f#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              1&lt;span class="hidden s:inline"&gt;&amp;nbsp;comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>hacktoberfest</category>
      <category>frontend</category>
      <category>opensource</category>
      <category>react</category>
    </item>
    <item>
      <title>Discover koalaz: a simple npm package to generate mock data about koalas!</title>
      <dc:creator>MattQ</dc:creator>
      <pubDate>Tue, 25 Nov 2025 21:49:40 +0000</pubDate>
      <link>https://dev.to/mattqdev/discover-koalaz-a-simple-npm-package-to-generate-mock-data-about-koalas-4pa3</link>
      <guid>https://dev.to/mattqdev/discover-koalaz-a-simple-npm-package-to-generate-mock-data-about-koalas-4pa3</guid>
      <description>&lt;p&gt;&lt;strong&gt;koalaz&lt;/strong&gt; is a mock data generator, designed for tests, prototypes, and developers who want something simple, fast, and a little fun.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐨 Why “koalaz”?&lt;/strong&gt; Because koalas are chill animals, they sleep all day… and “koala” was already taken lol.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚙️ What does it do?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generates placeholder data (names, numbers, objects, arrays…)&lt;/li&gt;
&lt;li&gt;Supports tons of different data types (text, number, JSON, table, color, ASCII, email, password, and more)&lt;/li&gt;
&lt;li&gt;Works offline too, with no external calls and no third-party dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📦 npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/koalaz" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/koalaz&lt;/a&gt; &lt;br&gt;
💻 GitHub: github.com/mattqdev/koalaz&lt;/p&gt;

&lt;p&gt;If you need a lighter and more fun alternative to Faker or Lorem Ipsum, or just want a meme-style mock tool, try koalaz. &lt;/p&gt;

&lt;p&gt;Feedback, stars, forks, contributions—all welcome!&lt;/p&gt;

</description>
      <category>npm</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>data</category>
    </item>
    <item>
      <title>How to learn physics easily: discover PhysicsHub.</title>
      <dc:creator>MattQ</dc:creator>
      <pubDate>Wed, 27 Aug 2025 14:18:49 +0000</pubDate>
      <link>https://dev.to/mattqdev/how-to-learn-physics-easily-discover-physicshub-1aj</link>
      <guid>https://dev.to/mattqdev/how-to-learn-physics-easily-discover-physicshub-1aj</guid>
      <description>&lt;p&gt;Studying physics shouldn’t be a race to memorise formulas.&lt;br&gt;&lt;br&gt;
With &lt;strong&gt;PhysicsHub&lt;/strong&gt;, you can &lt;strong&gt;experience physics in real time&lt;/strong&gt;, uncover the concepts behind the equations, and instantly see how they apply to the real world.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;What it is&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
An &lt;strong&gt;open‑source&lt;/strong&gt; project created by students, for students (and curious minds of all ages), designed to turn learning into an &lt;strong&gt;interactive, accessible, and free&lt;/strong&gt; experience.&lt;br&gt;&lt;br&gt;
No commercial interest — just a passion for knowledge.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What you’ll find on PhysicsHub
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In‑browser simulations&lt;/strong&gt;: from the motion of a pendulum to the laws of dynamics, all just a click away.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real‑time controls&lt;/strong&gt;: sliders and inputs to tweak parameters and instantly see the results.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Targeted insights&lt;/strong&gt;: clear explanations and links to high‑quality resources.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Why we created it
&lt;/h2&gt;

&lt;p&gt;We want learning physics to be:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clear&lt;/strong&gt; — making complex concepts visible.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engaging&lt;/strong&gt; — experiment, observe, understand.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Universal&lt;/strong&gt; — online, free, forever.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤝 How you can contribute
&lt;/h2&gt;

&lt;p&gt;The project grows thanks to the community: you can help with code, design, theory content, testing, or simply sharing ideas.&lt;br&gt;&lt;br&gt;
Every contribution, big or small, makes a difference.&lt;/p&gt;

&lt;p&gt;Features described here but not yet live on the website — such as most of the theory sections — will be added soon, and support from contributors is highly needed.&lt;/p&gt;

&lt;p&gt;Many parts, like the theory sections, are still in progress: your help can speed up their release.  &lt;/p&gt;

&lt;p&gt;The project is very simple, making it easy for contributors to understand and modify the source code.&lt;/p&gt;




&lt;p&gt;🔗 &lt;strong&gt;Discover it now&lt;/strong&gt;: &lt;a href="https://physicshub.github.io" rel="noopener noreferrer"&gt;physicshub.github.io&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💻 &lt;strong&gt;Collaborate on GitHub&lt;/strong&gt;: &lt;a href="https://github.com/physicshub/physicshub.github.io" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
