<?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: Fuat Keleş</title>
    <description>The latest articles on DEV Community by Fuat Keleş (@fuat_kele_4949d4be6c99d8).</description>
    <link>https://dev.to/fuat_kele_4949d4be6c99d8</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%2F3731391%2F1a9ed809-1fcd-44ba-9304-c8d7d210ac38.png</url>
      <title>DEV Community: Fuat Keleş</title>
      <link>https://dev.to/fuat_kele_4949d4be6c99d8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fuat_kele_4949d4be6c99d8"/>
    <language>en</language>
    <item>
      <title>How UIQuarter analyzes UI codebases and what it finds</title>
      <dc:creator>Fuat Keleş</dc:creator>
      <pubDate>Wed, 25 Feb 2026 19:35:58 +0000</pubDate>
      <link>https://dev.to/fuat_kele_4949d4be6c99d8/how-uiquarter-analyzes-ui-codebases-and-what-it-finds-2moa</link>
      <guid>https://dev.to/fuat_kele_4949d4be6c99d8/how-uiquarter-analyzes-ui-codebases-and-what-it-finds-2moa</guid>
      <description>&lt;p&gt;&lt;a href="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%2Farticles%2Footdjk9k4q2a484ndo7w.png" class="article-body-image-wrapper"&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%2Farticles%2Footdjk9k4q2a484ndo7w.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've been working on a CLI tool called UIQuarter that does static analysis on UI codebases. It uses AST parsing to understand component structures, map dependencies, detect styling patterns, and find architectural issues. Then it can generate context files for AI coding tools, but the analysis itself is useful on its own.&lt;/p&gt;

&lt;p&gt;I wanted to write about what the tool actually detects and how, since "static analysis for UI codebases" is pretty vague.&lt;/p&gt;

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

&lt;p&gt;UIQuarter has 20 analyzers. When you run &lt;code&gt;uiquarter init&lt;/code&gt; on a project, here's what happens under the hood.&lt;/p&gt;

&lt;h3&gt;
  
  
  Component detection
&lt;/h3&gt;

&lt;p&gt;The ComponentAnalyzer uses ts-morph to parse the AST of every file. For React, it finds functional components by looking for functions that return JSX. For each one it extracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component name and file path&lt;/li&gt;
&lt;li&gt;Props (with TypeScript types if available)&lt;/li&gt;
&lt;li&gt;Hooks used (&lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt;, custom hooks)&lt;/li&gt;
&lt;li&gt;Whether it's a default or named export&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Vue it parses Single File Components — &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; and Options API. On Svelte it parses &lt;code&gt;.svelte&lt;/code&gt; files. Angular gets special treatment for decorators (&lt;code&gt;@Component&lt;/code&gt;, &lt;code&gt;@Injectable&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;p&gt;The point isn't just listing files. It's understanding what each component &lt;em&gt;is&lt;/em&gt; — what it accepts, what it depends on, where it lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency graph
&lt;/h3&gt;

&lt;p&gt;The DependencyAnalyzer builds a graph with typed edges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Render edges&lt;/strong&gt;: Component A renders Component B in its JSX&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hook edges&lt;/strong&gt;: Component A uses a hook exported from module B&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HOC edges&lt;/strong&gt;: Component A is wrapped by a higher-order component from B&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider edges&lt;/strong&gt;: Component A provides context consumed by Component B&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This graph is what powers the &lt;code&gt;query&lt;/code&gt; commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter query deps Dashboard      &lt;span class="c"&gt;# what Dashboard depends on&lt;/span&gt;
uiquarter query dependents Button   &lt;span class="c"&gt;# everything that renders Button&lt;/span&gt;
uiquarter query hubs                &lt;span class="c"&gt;# most-connected components&lt;/span&gt;
uiquarter query chains              &lt;span class="c"&gt;# deepest dependency chains&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hub components are interesting — they're the nodes with the highest connectivity. Everything depends on them, so they're risky to change. UIQuarter flags these as architectural insights.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling patterns
&lt;/h3&gt;

&lt;p&gt;The StylingAnalyzer detects which approach your project uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind&lt;/strong&gt; — reads your &lt;code&gt;tailwind.config.js&lt;/code&gt; to understand custom classes. Captures the actual tokens used in the codebase: &lt;code&gt;bg-[#0A0A10]&lt;/code&gt;, &lt;code&gt;rounded-2xl&lt;/code&gt;, &lt;code&gt;text-[#B4A5BD]&lt;/code&gt;. Not just "this project uses Tailwind."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Modules&lt;/strong&gt; — maps which &lt;code&gt;.module.css&lt;/code&gt; file belongs to which component&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;styled-components / Emotion&lt;/strong&gt; — detects template literal styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plain CSS&lt;/strong&gt; — tracks stylesheet imports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters for AI context generation. When an AI tool knows your project uses &lt;code&gt;rounded-2xl bg-[#0A0A10] border border-white/10&lt;/code&gt; for cards, it generates matching code instead of &lt;code&gt;rounded-lg bg-gray-800&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  UX patterns
&lt;/h3&gt;

&lt;p&gt;The UxAnalyzer checks each component for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error states (try/catch, error boundaries, error message rendering)&lt;/li&gt;
&lt;li&gt;Loading states (spinner rendering, skeleton UIs, loading flags)&lt;/li&gt;
&lt;li&gt;Empty states (zero-data handling, empty list messages)&lt;/li&gt;
&lt;li&gt;Accessibility (ARIA labels, roles, keyboard handlers, focus management)&lt;/li&gt;
&lt;li&gt;Responsive patterns (media queries, responsive class variants)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is per-component data. So you can see that &lt;code&gt;DataTable&lt;/code&gt; handles loading and empty states but &lt;code&gt;UserCard&lt;/code&gt; doesn't have error handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Naming and structure
&lt;/h3&gt;

&lt;p&gt;The FileStructureAnalyzer extracts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File naming convention (PascalCase, kebab-case, camelCase)&lt;/li&gt;
&lt;li&gt;Directory roles (what lives in &lt;code&gt;pages/&lt;/code&gt; vs &lt;code&gt;components/&lt;/code&gt; vs &lt;code&gt;hooks/&lt;/code&gt; vs &lt;code&gt;lib/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Barrel exports (index files that re-export)&lt;/li&gt;
&lt;li&gt;Import alias patterns (&lt;code&gt;@/components/...&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Co-location patterns (test files next to source, styles next to components)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture insights
&lt;/h3&gt;

&lt;p&gt;The InsightEngine processes all analyzer results and detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hub components&lt;/strong&gt; — high connectivity, many dependents. Risky to refactor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orphan components&lt;/strong&gt; — nothing renders them. Dead code candidates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circular dependencies&lt;/strong&gt; — A imports B imports A.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep chains&lt;/strong&gt; — A → B → C → D → E. Long dependency paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing barrel exports&lt;/strong&gt; — directories without index files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Naming inconsistencies&lt;/strong&gt; — mixed conventions in the same directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Framework-specific analyzers
&lt;/h3&gt;

&lt;p&gt;7 framework analyzers handle framework-specific patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt; — pages vs app router, API routes, middleware, layouts, server/client components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nuxt&lt;/strong&gt; — pages, composables, server routes, middleware&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SvelteKit&lt;/strong&gt; — routes, load functions, server endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angular&lt;/strong&gt; — components, services, modules, directives, pipes, routes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solid&lt;/strong&gt; — signals, effects, resources, stores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lit&lt;/strong&gt; — custom elements, shadow DOM, reactive properties&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qwik&lt;/strong&gt; — resumable components, server functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend analyzers
&lt;/h3&gt;

&lt;p&gt;4 analyzers for backend patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API routes&lt;/strong&gt; — Express, Fastify, NestJS, Hono, tRPC, GraphQL endpoint detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; — Prisma, TypeORM, Drizzle, Sequelize, Mongoose model detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt; — JWT, sessions, OAuth, guards, RBAC patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Env config&lt;/strong&gt; — .env parsing, secret detection, validation patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The analysis output
&lt;/h2&gt;

&lt;p&gt;Everything goes into a &lt;code&gt;.uiq/&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.uiq/
  index.json      # master intelligence index
  meta.json       # timestamps, stats, build hash
  insights.json   # architectural issues
  snapshot.json   # baseline for drift detection
  cache/          # analyzer result cache (SHA-256)
  patterns/       # per-pattern detail files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The index is a structured JSON with every component, edge, convention, pattern, and insight. You can query it directly or use it to generate context files.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI context generation
&lt;/h2&gt;

&lt;p&gt;This is the part that connects the analysis to AI coding tools.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter generate &lt;span class="nt"&gt;--target&lt;/span&gt; all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reads the analysis index and produces:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;claude&lt;/td&gt;
&lt;td&gt;CLAUDE.md&lt;/td&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;codex&lt;/td&gt;
&lt;td&gt;AGENTS.md&lt;/td&gt;
&lt;td&gt;OpenAI Codex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cursor&lt;/td&gt;
&lt;td&gt;.cursorrules&lt;/td&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;windsurf&lt;/td&gt;
&lt;td&gt;.windsurfrules&lt;/td&gt;
&lt;td&gt;Windsurf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cline&lt;/td&gt;
&lt;td&gt;.clinerules&lt;/td&gt;
&lt;td&gt;Cline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;copilot&lt;/td&gt;
&lt;td&gt;copilot-instructions.md&lt;/td&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;aider&lt;/td&gt;
&lt;td&gt;CONVENTIONS.md&lt;/td&gt;
&lt;td&gt;Aider&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each file is formatted for the specific tool's conventions. The content includes component maps, dependency relationships, styling tokens, naming conventions, and architecture warnings — compressed from the full analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real numbers
&lt;/h3&gt;

&lt;p&gt;On a React + Tailwind project (11 key files, 71,322 chars of source code):&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Farticles%2Ftnqfuyyc22tn3egkl14i.png" class="article-body-image-wrapper"&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%2Farticles%2Ftnqfuyyc22tn3egkl14i.png" alt=" " width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;71,322 characters compressed to 1,299 characters of structured context. 55x compression ratio. The AI reads one file instead of twelve and gets accurate information about every component, dependency, and convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other features
&lt;/h2&gt;

&lt;p&gt;Beyond analysis and context generation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task resolver&lt;/strong&gt; — fuzzy match a description to relevant files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter resolve &lt;span class="s2"&gt;"add dark mode toggle"&lt;/span&gt;
&lt;span class="c"&gt;# returns scored list of files that are likely relevant&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uses an inverted index with synonym expansion and fuzzy matching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drift detection&lt;/strong&gt; — track architectural changes over time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter drift &lt;span class="nt"&gt;--save&lt;/span&gt;     &lt;span class="c"&gt;# save current state as baseline&lt;/span&gt;
uiquarter drift            &lt;span class="c"&gt;# compare current vs baseline&lt;/span&gt;
&lt;span class="c"&gt;# Patterns: 53 → 58 (+5)&lt;/span&gt;
&lt;span class="c"&gt;# Insights: 5 → 7 (+2 new)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CI/CD integration&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter ci &lt;span class="nt"&gt;--fail-on&lt;/span&gt; warning
uiquarter ci &lt;span class="nt"&gt;--pr&lt;/span&gt; 42 &lt;span class="nt"&gt;--repo&lt;/span&gt; owner/repo  &lt;span class="c"&gt;# posts as PR comment&lt;/span&gt;
uiquarter ci &lt;span class="nt"&gt;--template&lt;/span&gt;                 &lt;span class="c"&gt;# generates GitHub Action&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Convention linting&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter lint
&lt;span class="c"&gt;# checks: file-naming, barrel-exports, circular-deps,&lt;/span&gt;
&lt;span class="c"&gt;# max-nesting-depth, single-styling, min-accessibility&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MCP server&lt;/strong&gt; for real-time AI tool integration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter serve                              &lt;span class="c"&gt;# stdio&lt;/span&gt;
uiquarter serve &lt;span class="nt"&gt;--transport&lt;/span&gt; http &lt;span class="nt"&gt;--port&lt;/span&gt; 3100 &lt;span class="c"&gt;# HTTP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exposes tools like &lt;code&gt;uiq_scope_context&lt;/code&gt;, &lt;code&gt;uiq_query_component&lt;/code&gt;, &lt;code&gt;uiq_resolve_task&lt;/code&gt;, &lt;code&gt;uiq_find_insights&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML dashboard&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uiquarter report &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;span class="c"&gt;# generates self-contained HTML with dependency graphs and tables&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tech
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript (strict mode)&lt;/li&gt;
&lt;li&gt;ts-morph for AST parsing&lt;/li&gt;
&lt;li&gt;SHA-256 caching with analyzer versioning&lt;/li&gt;
&lt;li&gt;Commander for CLI&lt;/li&gt;
&lt;li&gt;tsup for dual ESM + CJS builds&lt;/li&gt;
&lt;li&gt;500+ tests across 36 test files&lt;/li&gt;
&lt;li&gt;Zero external runtime dependencies&lt;/li&gt;
&lt;li&gt;Node.js &amp;gt;= 18&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/fuatkeles/uiquarter" rel="noopener noreferrer"&gt;github.com/fuatkeles/uiquarter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;code&gt;npm install -g uiquarter&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Website: &lt;a href="https://uiquarter.com" rel="noopener noreferrer"&gt;uiquarter.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MIT licensed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you work on UI projects with AI tools, give it a try. If you have ideas for what else the analyzers should detect, I'd like to hear about it.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
