<?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: Peter Tamas</title>
    <description>The latest articles on DEV Community by Peter Tamas (@kondvik).</description>
    <link>https://dev.to/kondvik</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%2F3865877%2F6bf2c760-4e66-4d57-99bf-a118885f93d5.jpeg</url>
      <title>DEV Community: Peter Tamas</title>
      <link>https://dev.to/kondvik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kondvik"/>
    <language>en</language>
    <item>
      <title>AI FIELD NOTES #002 – Weekly memos for Engineering Leaders</title>
      <dc:creator>Peter Tamas</dc:creator>
      <pubDate>Tue, 07 Apr 2026 13:12:03 +0000</pubDate>
      <link>https://dev.to/kondvik/ai-field-notes-002-weekly-memos-for-engineering-leaders-1o52</link>
      <guid>https://dev.to/kondvik/ai-field-notes-002-weekly-memos-for-engineering-leaders-1o52</guid>
      <description>&lt;p&gt;You are a software engineer, so you know that feeling. You are deep in dependency hell, reading library docs, digging through version histories, staring at compatibility matrices. Running tools to detect transitive version conflicts.&lt;/p&gt;

&lt;p&gt;I got tired of it, too. So I asked Opus 4.6 to build a version checker hook and let AI deal with this problem instead of me. It turned out to be one of the most quietly impactful things I've added to my workflow.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://www.bobcatscoding.com/ai-field-notes" rel="noopener noreferrer"&gt;Bobcats Coding&lt;/a&gt;, we've deliberately built AI into our delivery system: how we specify, how we build, how we test, and how we learn. (Of course, if you are in the middle of a large legacy codebase with years of untouched dependencies, your mileage may vary, but that's a story for another time.:))&lt;/p&gt;

&lt;h2&gt;
  
  
  The core issue
&lt;/h2&gt;

&lt;p&gt;One of my recurring frustrations with AI-generated code was debugging problems caused by poorly selected dependency versions. When you let AI add a dependency to a project, it usually does &lt;strong&gt;not&lt;/strong&gt; install the latest version of the library. Instead, it often selects an artifact that is &lt;strong&gt;a few major versions behind&lt;/strong&gt; the latest release. This behavior caused two types of issues for me repeatedly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Usage of already deprecated functions&lt;/li&gt;
&lt;li&gt;Version mismatch bugs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you don’t have proper &lt;strong&gt;E2E tests&lt;/strong&gt; in the project, version mismatch bugs can be very difficult to detect. The feature simply doesn’t behave as expected, usually without any error messages, which makes debugging extremely frustrating.&lt;/p&gt;

&lt;p&gt;After running into this situation multiple times across several projects, I asked &lt;strong&gt;Opus 4.6&lt;/strong&gt; to create a &lt;a href="https://www.notion.so/Version-checker-hook-Claude-Code-31b1c06aab6e809496c2de877f9b77ab?pvs=21" rel="noopener noreferrer"&gt;version-checking script&lt;/a&gt; and &lt;a href="https://www.notion.so/Version-checker-hook-Claude-Code-31b1c06aab6e809496c2de877f9b77ab?pvs=21" rel="noopener noreferrer"&gt;integrated it into a PostToolUse hook&lt;/a&gt;, that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checks whether all project dependencies are up to date (similar to Dependabot)&lt;/li&gt;
&lt;li&gt;detects version mismatch issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Since I started using this hook, I’ve never had to struggle with dependency versions again.
&lt;/h3&gt;

&lt;p&gt;When AI adds a new dependency for a feature, even if I miss an E2E test for a particular scenario, this hook saves me a lot of time by catching hidden issues caused by version mismatches.&lt;/p&gt;

&lt;p&gt;After every change in my dependencies, it runs version checks and &lt;strong&gt;automatically iterates on dependency versions until they align and all tests pass&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;p&gt;Ask AI to create a &lt;strong&gt;version-checker PostToolUse&lt;/strong&gt; hook in projects that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shows a warning when it detects a newer version of a dependency&lt;/li&gt;
&lt;li&gt;checks for version mismatch issues and resolves them when found&lt;/li&gt;
&lt;li&gt;detects transitive dependency conflicts and resolves them automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update dependencies in a &lt;strong&gt;separate commit or PR&lt;/strong&gt; when warnings appear to keep the project up to date.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;TDD with BDD-style E2E tests&lt;/strong&gt; (only partially related, but still helpful for catching subtle runtime issues).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resulting Workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;AI adds dependencies during feature implementation&lt;/li&gt;
&lt;li&gt;The PostToolUse hook detects version issues&lt;/li&gt;
&lt;li&gt;The hook automatically aligns dependency versions&lt;/li&gt;
&lt;li&gt;Lint, type checks, and tests verify correctness&lt;/li&gt;
&lt;li&gt;Only stable commits enter the repository&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated dependency version assurance&lt;/li&gt;
&lt;li&gt;Reduced debugging time&lt;/li&gt;
&lt;li&gt;Safer AI-generated code&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In my full-stack TypeScript projects, the hook works surprisingly well. Even when the updated major versions were not yet compatible with each other. The feedback loops in the project recognized this and automatically iterated with minor versions, reading issues and forums, and also automatically came up with a small, effective, temporary patch that solved the incompatibility issue. &lt;/p&gt;

&lt;p&gt;The bottom line: connecting a version-checker pre-commit hook to all your projects isn't optional when you're working with AI-generated code. It's a mandatory feedback loop for maintaining developer productivity and saving a lot of my nerves.:) &lt;/p&gt;

&lt;h2&gt;
  
  
  Want to try it? Here is my implementation example
&lt;/h2&gt;

&lt;p&gt;In my TypeScript projects, I implemented this workflow with a small script:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.notion.so/bobcats-coding/Version-checker-hook-Claude-Code-31b1c06aab6e809496c2de877f9b77ab?source=copy_link#31c1c06aab6e804e9c2efe8509462cee" rel="noopener noreferrer"&gt;check-versions.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It performs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency outdated checks&lt;/li&gt;
&lt;li&gt;peer dependency mismatch detection&lt;/li&gt;
&lt;li&gt;transitive conflict detection&lt;/li&gt;
&lt;li&gt;optional automatic resolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;bun scripts/check-versions.ts              #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;All checks &lt;span class="o"&gt;(&lt;/span&gt;pre-commit&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;bun scripts/check-versions.ts --mismatch   #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Mismatch only &lt;span class="o"&gt;(&lt;/span&gt;fast&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;bun scripts/check-versions.ts --fix        #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Auto-resolve mismatches + transitive conflicts
&lt;span class="gp"&gt;bun scripts/check-versions.ts --json       #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;JSON output &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;Claude hook&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows different checks depending on the stage of the workflow.&lt;/p&gt;

&lt;p&gt;For example, the &lt;strong&gt;fast mismatch-only check&lt;/strong&gt; is ideal for pre-commit hooks.&lt;/p&gt;

&lt;p&gt;An example output of the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bun scripts/check-versions.ts 2&amp;gt;&amp;amp;1)
  ⎿  ⚠ OUTDATED PACKAGES:
       @vitejs/plugin-react           4.7.0 → 5.1.4        ▲ major
       vite                           6.4.1 → 7.3.1        ▲ major
       @colyseus/schema               2.0.37 → 4.0.17      ▲ major
       colyseus.js                    0.15.28 → 0.16.22    ▲ minor
       @colyseus/ws-transport         0.15.3 → 0.17.9      ▲ minor
       colyseus                       0.15.57 → 0.17.8     ▲ minor
       @colyseus/testing              0.15.4 → 0.17.11     ▲ minor
       @biomejs/biome                 2.4.4 → 2.4.6        ▲ patch
       @storybook/react               10.2.13 → 10.2.16    ▲ patch
       @storybook/react-vite          10.2.13 → 10.2.16    ▲ patch
       storybook                      10.2.13 → 10.2.16    ▲ patch

     ✓ No version mismatches or transitive conflicts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The &lt;code&gt;check-versions.sh&lt;/code&gt; hook
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;.claude/hooks&lt;/code&gt; folder, I created the &lt;code&gt;check-versions.sh&lt;/code&gt; script, where I run the &lt;code&gt;check-versions.ts&lt;/code&gt; script only when a package.json file is modified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="c"&gt;# Version checker hook — runs after PostToolUse on Edit/Write.&lt;/span&gt;
&lt;span class="c"&gt;# Only fires when the modified file is a package.json.&lt;/span&gt;
&lt;span class="c"&gt;# Runs mismatch check and injects result into Claude's context.&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;INPUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;ROOT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/Users/kond/kondfox/isuperhero-claude"&lt;/span&gt;

&lt;span class="c"&gt;# Extract the file path from the hook payload&lt;/span&gt;
&lt;span class="nv"&gt;TOOL_INPUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.tool_input // empty'&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;FILE_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TOOL_INPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.file_path // empty'&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Only run when a package.json was modified&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FILE_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FILE_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;"package.json"&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Run mismatch check only (fast, no network call)&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;RESULT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;~/.bun/bin/bun scripts/check-versions.ts &lt;span class="nt"&gt;--mismatch&lt;/span&gt; &lt;span class="nt"&gt;--json&lt;/span&gt; 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RESULT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;PostToolUse&lt;/code&gt; hook integration
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;.claude/settings.json&lt;/code&gt; I defined the &lt;code&gt;PostToolsUse&lt;/code&gt; hook:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&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;"PostToolUse"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Edit|Write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Users/kond/kondfox/isuperhero-claude/.claude/hooks/check-versions.sh"&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;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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&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;
  
  
  Pre-commit Integration (Husky)
&lt;/h2&gt;

&lt;p&gt;The script runs automatically before every commit via Husky.&lt;/p&gt;

&lt;p&gt;Example pre-commit hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env sh&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--show-toplevel&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

~/.bun/bin/bun scripts/check-versions.ts--fix
~/.bun/bin/bun run lint:fix
~/.bun/bin/bun run typecheck
~/.bun/bin/bun run &lt;span class="nb"&gt;test&lt;/span&gt;
~/.bun/bin/bun run &lt;span class="nb"&gt;test&lt;/span&gt;:e2e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency versions are aligned&lt;/li&gt;
&lt;li&gt;lint errors are fixed&lt;/li&gt;
&lt;li&gt;types compile&lt;/li&gt;
&lt;li&gt;unit tests pass&lt;/li&gt;
&lt;li&gt;E2E tests pass&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;before any commit enters the repository.&lt;/p&gt;

&lt;p&gt;This creates a &lt;strong&gt;tight feedback loop for AI-generated code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can see a full working example here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kondfox/isuperhero-claude" rel="noopener noreferrer"&gt;https://github.com/kondfox/isuperhero-claude&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository contains the full &lt;code&gt;check-versions.ts&lt;/code&gt; implementation and the Husky integration used in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Legacy project?
&lt;/h2&gt;

&lt;p&gt;I have doubts about how good idea it is to integrate the version checker feedback loop into a legacy project where the dependencies are far behind the actual versions. But I’m gonna give it a try in such a project shortly, and share the result with you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>productivity</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>AI Field Notes #001 | Is AI frontend development finally getting good? Our Opus 4.6 test says yes. (And no.)</title>
      <dc:creator>Peter Tamas</dc:creator>
      <pubDate>Tue, 07 Apr 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/kondvik/ai-field-notes-001-is-ai-frontend-development-finally-getting-good-our-opus-46-test-says-yes-5c0a</link>
      <guid>https://dev.to/kondvik/ai-field-notes-001-is-ai-frontend-development-finally-getting-good-our-opus-46-test-says-yes-5c0a</guid>
      <description>&lt;p&gt;In December 2025, &lt;a href="https://www.notion.so/bobcats-coding/UI-component-development-with-Windsurf-Gemini-3-Pro-Figma-MCP-Playwright-MCP-2c31c06aab6e80b8b570ecec267b2499" rel="noopener noreferrer"&gt;I wrote about trying to build a full page with AI&lt;/a&gt; with a much smaller scope, and it didn’t go well.&lt;/p&gt;

&lt;p&gt;At that time, my conclusion was that while implementing a simple, small UI component with AI and Figma MCP worked quite well, it was surprising how badly it handled the implementation of a full page. The small UI component generation wasn't perfect either. I could get a ~90% "close enough" output that I could quickly align to the requirements by hand. But when I asked AI to implement a simple login page that contained only already-existing components, even with Figma MCP, the result was disappointing. The layout was far from the design, and it hallucinated elements that weren't in the design at all. No matter how I prompted, it just produced different hallucinations. Which I really don't understand, because Figma MCP provides a structured description of the design. In the end, I spent much more time experimenting with AI than it would have taken to puzzle the components into their places by myself within a few minutes.&lt;/p&gt;

&lt;p&gt;My current experience is still not flawless, but I'm amazed by the improvement in this area over the past 3 months. &lt;strong&gt;I managed to implement a whole complex page, with existing and new components, that I had estimated at 48 hours, in just 8 hours.&lt;/strong&gt; Not in one iteration, not 100% AI-generated, not without refactoring and human code reviews, but the velocity is impressive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Context on the Comparison
&lt;/h2&gt;

&lt;p&gt;After having satisfying experiences with Opus 4.6 UI component implementation, I was eager to retry a full-page AI implementation experiment. When you don't have a strict specification, it's easy to vibe-code a fair-looking result, but it's hard to evaluate how well the output matches the client's needs. That's why I chose a project where we had clear requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Figma designs that we need to implement&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An OpenAPI specification of the backend API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are strict, structural anchors that provide clear and easy verification of the result.&lt;/p&gt;

&lt;p&gt;The state of the project when I ran my experiment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The project was already "Claude-ready". It had a well-set-up, project-specific Claude.md that my colleagues had been using for months.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;We already had an API client, but none of the endpoints that this page uses were defined in it yet.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The site layout, design system, and some of the UI components that the page needed were already in place, but the design also contained new, complex UI components.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, this was a client project we built at &lt;a href="https://www.bobcatscoding.com/ai-field-notes" rel="noopener noreferrer"&gt;Bobcats Coding&lt;/a&gt;, so screenshots, product details, and the repository stay private. But I'm going to write about everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first iteration
&lt;/h2&gt;

&lt;p&gt;The better you specify, the better outcome you can expect. This isn't a new directive; it was true before AI coding as well. But with agentic engineering, specification is the new code.&lt;/p&gt;

&lt;p&gt;So I spent ~1 hour specifying the task as my initial prompt. I gave a general context about the page we were building, linked the design of the whole page in Figma and the components one by one. I gave a clear specification for each element of the page: which API endpoint it gets its data from, what it represents, how it should work. I specified all the page actions as well. What should happen when a button is clicked, when a dropdown element is selected, and so on. I also instructed Claude to generate every new UI component in a reusable way within our UI library, test them, and provide Storybook stories and documentation.&lt;/p&gt;

&lt;p&gt;I asked AI to create an implementation plan that multiple agents could work on in parallel (because I was curious how this would work). I required a contract-first approach so that the results of the asynchronously working agents could be integrated at the end.&lt;/p&gt;

&lt;p&gt;Opus 4.6 worked for 9 minutes to create the plan. It correctly found all the files in the project that it needed to modify and the workspaces and folders where it should create the new files.&lt;/p&gt;

&lt;p&gt;It separated the work into 4 agents with clear responsibilities, tasks, and restrictions:&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent 1: API Layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Update the API schema&lt;/li&gt;
&lt;li&gt;Generate API types from the schema&lt;/li&gt;
&lt;li&gt;Create and export DTO types&lt;/li&gt;
&lt;li&gt;Add mapping functions&lt;/li&gt;
&lt;li&gt;Implement new API client methods based on the given interface&lt;/li&gt;
&lt;li&gt;Add unit tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agent 2: UI Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Implement the discovered new UI components (the plan listed their names, dependencies, and functional descriptions)&lt;/li&gt;
&lt;li&gt;Add unit tests&lt;/li&gt;
&lt;li&gt;Create Storybook stories&lt;/li&gt;
&lt;li&gt;Export the components from the UI library&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agent 3: Page Composition
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Replace the current placeholder component on the page (server component)&lt;/li&gt;
&lt;li&gt;Call the proper API client methods for data&lt;/li&gt;
&lt;li&gt;Feed the data to the created client component&lt;/li&gt;
&lt;li&gt;Implement the layout and state management of the client component&lt;/li&gt;
&lt;li&gt;Place the required UI components on the page&lt;/li&gt;
&lt;li&gt;Implement the page actions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agent 4: E2E Tests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write the necessary BDD-style E2E tests for the page (the BDD features were also included in the plan for quick human verification)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It created an execution order as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Phase 1 (parallel): Agent 1 (API) + Agent 2 (UI Components)
Phase 2 (after Phase 1): Agent 3 (Page Composition)
Phase 3 (after Phase 2): Agent 4 (E2E Tests)

Agents 1 and 2 have zero dependencies and run fully in parallel.
Agent 3 depends on both but can start skeleton code immediately.
Agent 4 runs last as it needs rendered DOM.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The execution of the plan took &lt;strong&gt;29 minutes and 25 seconds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The result at first glance was a bit odd. It clearly contained all the required elements and showed the data correctly from the API, but the layout was broken, and the component designs were only ~80–90% faithful to the Figma designs. No hallucinations, though!&lt;/p&gt;

&lt;p&gt;All in all, it was not great, not terrible for a first iteration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refining the design
&lt;/h2&gt;

&lt;p&gt;I asked Claude to use Playwright MCP to verify its result: find the differences from the Figma design and fix them.&lt;/p&gt;

&lt;p&gt;Using Playwright MCP as a feedback loop in frontend development works surprisingly well. Claude opens the page in a browser, takes screenshots, analyzes them, finds the problems, fixes them, verifies the fix with Playwright again, and iterates until it's solved.&lt;/p&gt;

&lt;p&gt;However, my prompt was too vague, and the use of Figma MCP is still far from perfect, so the result was also disappointing. What worked much better was creating screenshots of both the UI implementation and the expected design, then describing the problems. Most of the design issues could be solved this way.&lt;/p&gt;

&lt;p&gt;Creating a 100%, pixel-perfect design is still not something an LLM is capable of.&lt;/p&gt;

&lt;p&gt;You need to recognize the point when the agent gets stuck in a loop, when every iteration just makes the problem different, but you don't get any closer to the solution. That's the point when you need to take the keyboard and finish the job yourself.&lt;/p&gt;

&lt;p&gt;In the case of pixel-perfect design implementation, in my experience with current models and tools, you can usually reach a ~90–95% state with AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refining the code
&lt;/h2&gt;

&lt;p&gt;Opus 4.6 generates relatively decent code, but most of the time it needs some refactoring. In the case of this experiment, here's what I found during code review:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It didn't create components for all the UI elements it should have. This led to unnecessary duplication that would have been difficult to maintain.&lt;/li&gt;
&lt;li&gt;It didn't always use the tokens from the design system or our SASS mixins (e.g., for typography).&lt;/li&gt;
&lt;li&gt;I found some overcomplicated, mutating logic that could have been written more simply.&lt;/li&gt;
&lt;li&gt;It didn't create some of the components as reusable as I expected.&lt;/li&gt;
&lt;li&gt;It hardcoded some constants that shouldn't have been hardcoded.&lt;/li&gt;
&lt;li&gt;It wasn't forward-thinking enough to extract functionality we could reuse later into a hook or utility function.&lt;/li&gt;
&lt;li&gt;It used far more useMemo than necessary. But when I pointed these out to Claude, it could fix them much faster than I would have. With proper permissions, it can even read PR comments from GitHub, so you don't necessarily need to prompt these manually. You can just review on GitHub, then give a short fix my reviews on the PR instruction.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What didn’t work
&lt;/h2&gt;

&lt;p&gt;Figma MCP still surprisingly underperforms compared to a simple screenshot.&lt;/p&gt;

&lt;p&gt;The multi-agent implementation was fun to try, but resulted in a 3,000+ line PR, which is far from optimal. Next time, after I have the multi-agent implementation plan and the contracts (types, interfaces) in the code, I'd try to solve the task on separate branches using worktrees.&lt;/p&gt;

&lt;h2&gt;
  
  
  What worked
&lt;/h2&gt;

&lt;p&gt;With all the refinements, I could ship the module in ~8 hours instead of the estimated 48 hours. Fully tested and documented. Two things stood out from the start:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Playwright MCP is a MUST in frontend development.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;2. Creating the API schema mapping, types, and API client based on the given OpenAPI specification worked perfectly, even on the first iteration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't think AI frontend development is solved, but for the first time, the velocity feels real. One thing's for sure: I'll keep testing, and I'll keep writing when something interesting happens.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>frontend</category>
      <category>ui</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
