AI Dev Tools

Font Errors: 20% of Sites Get Primary Typeface Wrong

A new tool designed to feed design systems to AI coding agents is running into a surprising data quality problem: 1 in 5 websites can't even correctly identify their own primary font. This isn't just an edge case; it's a systemic issue.

Screenshot of a command line interface showing the brandmd tool running and extracting font information.

Key Takeaways

  • A tool designed to extract website design systems for AI agents failed to correctly identify the primary font on 20% of tested sites.
  • Common failure modes included mistaking code fonts or body text for primary brand fonts due to simple frequency counting.
  • The tool has been updated to prioritize hero fonts, exclude monospaced fonts, and ignore fallback fonts, significantly improving accuracy.

The cursor hovered over the command line, ready to deploy a new artifact into the developer ecosystem. Six months of work, distilled into an npm CLI named brandmd. The premise was elegant: scrape a website, distill its design tokens into a DESIGN.md file, and feed that to AI coding assistants like Claude Code or Cursor. The goal? To generate UIs that actually match a brand’s aesthetic, rather than defaulting to a generic shadcn-ui look. Stripe, GitHub, Vercel—these titans of industry seemed to play nice. Their primary fonts, at least according to the initial build, were rendered correctly.

Then came the user DM. A simple, brutal observation: “your tool says my primary font is Inter. it is actually Manrope, the brand is on the hero, not the paragraphs.” A gut punch, to be sure, but also a critical data point. If the tool couldn’t reliably extract the most fundamental visual identifier—the primary font—on even one site, something was fundamentally broken.

The fix? A broad sweep. The developer behind brandmd subjected the tool to a trial by fire, running it against 100 popular design system websites. The results were, frankly, alarming. A full 20%—9 out of 45 successfully parsed sites—returned the wrong primary font. This isn’t a minor bug; it’s a statistical indictment of the data extraction process.

Why the Font Failures?

This isn’t a simple case of a typo or a minor oversight. The failures manifested in predictable, and frankly, revealing patterns. Three culprits stood out:

  • Code Fonts Reign Supreme: Sites heavy with code examples, like mantine.dev or remix.run, had their primary fonts mistakenly identified as the code font. JetBrains Mono and Menlo, beloved by developers, were drowning out the actual brand typeface. This highlights an overreliance on sheer frequency count, ignoring semantic context.

  • Body Text Dominance: In a stark illustration of the principle of least effort, sprawling utility classes and verbose body text on sites like valura.ai could overwhelm the more strategic placement of brand fonts in hero sections. The tool was simply picking the most frequent font, not the most important one.

  • Fallback Fiction: Perhaps the most insidious failure involved sites with no explicit custom font declaration. These often default to browser fallbacks. Old logic in brandmd would then latch onto Times as the ‘primary’ font, creating a false positive when no actual brand font was present.

This situation is reminiscent of early attempts at web scraping for e-commerce data, where simply pulling the first price listed often led to erroneous data points because the truly important price was buried in a more complex DOM structure. The issue boils down to context. Frequency alone isn’t enough; you need to understand why a font is being used.

Here’s the original logic, a single line that encapsulates the problem:

// analyze.js, v0.7.2
const primaryFont = fontList[0]?.[0];

It’s brutal in its simplicity, and equally brutal in its inaccuracy. It just grabs the first font it sees.

A Smarter Approach to Typeface Detection

The revised logic in brandmd v0.8 attempts to address these pitfalls with a more nuanced approach, prioritizing visual hierarchy and brand intent:

// analyze.js, v0.8
const primaryFont =
  pickNonExcluded(displayFonts) || // fontSize >= 40px (hero)
  pickNonExcluded(headingFonts) || // h1-h6
  pickNonExcluded(bodyFonts) || // p, li, span, div
  fontList[0]?.[0];
// excluded from Primary: mono fonts (Menlo, JetBrains Mono, GeistMono, etc.),
// default fallbacks (Times, Arial, Georgia), icon fonts (Material Icons,
// Font Awesome, Heroicons).

This update introduces a crucial layer of intelligence:

  • Display First: Fonts used in large hero sections (defined as fontSize >= 40px) are now given precedence. This acknowledges that the brand’s most prominent typographic statement often resides in the initial, visually arresting elements.

  • Skip the Monospaced Noise: Code fonts, while important for developer experience, are explicitly excluded from the primary font calculation. They’re relegated to secondary roles.

  • Ignore Defaults: When a site lacks a distinct custom font, the tool now wisely avoids surfacing generic fallbacks like Times, opting instead for an honest representation of no primary brand font. This prevents the artificial inflation of data.

Beyond these core principles, the update also includes a more strong font-family parser capable of handling complex CSS, including variables and escaped characters, alongside per-role cascading logic and improved navigation timeouts for sluggish Single Page Applications. These are the necessary enhancements when dealing with the messy reality of the web.

After these revisions, 7 out of the 9 previously misidentified sites now correctly report their primary brand font. The remaining two, railway.app and workday.design, genuinely lack a distinct brand font on their hero sections, meaning the tool’s output is now an honest reflection of their design choices—or lack thereof.

What Does This Mean for AI and Design Systems?

This 20% error rate in primary font identification isn’t merely a technical footnote for brandmd; it’s a flashing neon sign for the entire AI-driven design and development workflow. If AI agents are to reliably generate on-brand UIs, they need accurate, unambiguous data. Garbage in, garbage out, as the old saying goes.

This problem extends beyond fonts. Imagine AI trying to interpret color palettes, spacing rules, or component libraries when the foundational data is flawed. The promise of AI coding assistants is immense, but their effectiveness is directly tethered to the quality of the inputs they receive. The brandmd experience serves as a vital, albeit inconvenient, reminder that data hygiene isn’t a secondary concern; it’s the bedrock upon which these new technologies will be built or will crumble.

It’s a wake-up call to developers and tool builders: precision matters, especially when you’re feeding systems that lack the human intuition to question ambiguous data. The next step isn’t just building more sophisticated AI; it’s building more reliable methods for extracting and validating the data that powers them. This 20% failure rate is a problem that needs solving, not glossing over.


🧬 Related Insights

Frequently Asked Questions

**What is brandmd? brandmd is an npm CLI tool that extracts a website’s design system information, including its primary font, into a DESIGN.md file for use by AI coding agents.

Alex Rivera
Written by

Developer tools reporter covering SDKs, APIs, frameworks, and the everyday tools engineers depend on.

Frequently asked questions

**What is `brandmd`?
`brandmd` is an npm CLI tool that extracts a website's design system information, including its primary font, into a `DESIGN.md` file for use by <a href="/tag/ai-coding-agents/">AI coding agents</a>.

Worth sharing?

Get the best Developer Tools stories of the week in your inbox — no noise, no spam.

Originally reported by dev.to

Stay in the loop

The week's most important stories from DevTools Feed, delivered once a week.