iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🍅

The Personalities of AI Coding Tools in UI/UX: Observing Everything from Planning to Implementation with the Same Prompt

に公開

Introduction

With tools featuring proprietary models like Claude Code, Codex, and Cursor leading the pack, we have an ever-expanding array of choices for AI coding tools.

At our company, we have established an environment where engineers and non-engineers alike can leverage multiple AI coding tools to improve operational efficiency, with tools like Claude leading the way.

My primary tasks involve coding and documentation, and my typical workflow looks like this:

  1. Plan with Claude Code × Opus
  2. Review the plan with Codex
  3. Implement using Claude Code × Sonnet
  4. Re-review the implemented code with Codex
  5. Handle minor fixes with Cursor IDE

While working this way, I began to wonder: "Is this the best way to leverage these tools and models?" and "Could I get better output by changing which tool handles which part of the process?"

Most comparison articles for AI coding tools tend to focus on "speed" or "code quality." However, as someone who has worked on many web applications, I am more interested in "what kind of UI actually gets produced."

Each tool and model has its own strengths and weaknesses, and the parts where the AI silently fills in the gaps—that is, the judgments that aren't explicitly instructed—should reveal their unique personalities. Furthermore, I hypothesize that these personalities appear at different layers: one during the planning mode and another during actual implementation.

To test this hypothesis, I fed the same prompt to 3 tools × 4 models and compared their planning mode output with their UI/UX-focused implementation.

Prerequisites

Tools and Models Used

Date: April 17, 2026 (Version info based on my local environment that day)

Tool Model
Claude Code Claude Opus 4.7
Claude Code Claude Sonnet 4.6
Codex CLI GPT-5.4
Cursor Composer 2
  • Claude Code: v2.1.112
  • Codex CLI: v0.121.0
  • Cursor: v3.1.15

Target Application

I asked them to create the ultimate Pomodoro timer, taking into account the following items:

  • Expected target and concept
  • Technology selection and design philosophy
  • Features and presentation plan
Actual Prompt
I want to create a Pomodoro timer web app using React (Vite) + TypeScript.
Using your best judgment, please consider and implement the "ultimate Pomodoro timer" that you believe provides the best user experience.
Include the following items in your consideration and provide the rationale for your decisions:
- Expected target and concept: Who do you see as the ideal user, and what experience do you want to provide them?
- Technology selection and design philosophy: Reasons for your styling approach (CSS structure, etc.), unique color palette (Hex values), and visual characteristics of the UI.
- Features and presentation plan: Unique ideas, and concepts for animations and interactions to enhance focus.

Procedure

  1. Feed the prompt above into Planning Mode and have it output a design plan.
  2. Implement based on that plan.
  3. Verify the completed app using npm run dev.

Considerations for Fairness

  • The prompt was identical for all, starting from an empty repository.
  • Since there is variation in output even with the same prompt, this is a "one-shot" trial.
  • No feedback was provided to the AI's responses; the initial implementation is the subject of observation.
  • The following observations are a single-point observation as of April 17, 2026, and may change with updates to tools and models.

UI/UX Result Comparison

Claude Code × Opus 4.7 finished screen
Claude Code × Opus 4.7 — "Quiet Ember" theme with purple-black and orange

Claude Code × Sonnet 4.6 finished screen
Claude Code × Sonnet 4.6 — "Ember" with black background and orange accents

Codex × GPT-5.4 finished screen
Codex × GPT-5.4 — "Quiet Orbit" with a light paper-colored theme

Cursor × Composer 2 finished screen
Cursor × Composer 2 — "Calm Focus" with GitHub Primer color scheme

Even with the same "Pomodoro Timer" request, there were clear differences in background brightness, functional density, and the intensity of completion effects. The details for each model are explored later in the section "Model Personalities Seen in Implementation Results."

Supplemental: Claude's Official "frontend-design" Skill

When I applied Anthropic's public frontend-design skill to Opus 4.7 and Composer 2, the designs changed as follows.

Opus 4.7 after applying frontend-design
Opus 4.7 + frontend-design — From purple-black to "Rekijitsudo" with Japanese paper, ink, and vermilion

Composer 2 after applying frontend-design
Composer 2 + frontend-design — A warm texture applied to the GitHub-style base

Both changed their atmosphere while keeping the functional parts intact. It's interesting to try this when exploring different approaches while the design is still undecided.

Tool Personalities in the Planning Stage

Next, I compared the planning mode outputs across the three tools. The moment I fed them the same prompt, the "format" of the plans branched into three directions.

Claude Code — "Reading Material" with Structured Chapters

Claude Code, whether using Opus or Sonnet, produces plans in the form of structured reading material.

## Context
## 1. Expected Target and Concept
## 2. Technology Selection and Design Philosophy
## 3. Features and Presentation
## 4. File Structure
## 5. Verification
## 6. Implementation Order

Under each chapter, there are tables, code snippets, and directory trees packed inside. As a design document that could be handed over to someone else as-is, the level of completion is high, and it covered all the required study items without omission.

Claude Code × Opus 4.7 Plan
# Pomodoro Timer — Implementation Plan

## Context

This project is essentially empty (only `README.md` and `node_modules`/`dist` exist; no `package.json` or `src` created). I will design and implement a "Best Pomodoro Timer" from scratch using React (Vite) + TypeScript. The user has delegated language and scope decisions to me ("I trust your sense"), so the following is my recommended configuration.

---

## 1. Expected Target and Concept

### Target

**Knowledge workers** (software engineers, designers, writers, researchers, graduate students) who need **deep focus** while working at home/remotely. Often drowning in notifications and tabs, losing the gateway to immersion.

### Concept

**"A tool for immersion that glows quietly"** — Quiet Ember.

- Competing not on functionality, but on **"the texture of time."**
- Shortest path: just launch and press Space to begin the ritual of immersion.
- The timer is not a "tool to rush you," but a "tool to regulate your breathing." Colors and sounds are restrained, yet they support focus subconsciously.

### Rationale for this direction

Existing Pomodoro apps (Pomofocus, TomatoTimer, etc.) are either feature-bloated or decoration-heavy (red tomatoes, bloated task management). **In a deep work context, UI is better when it "disappears"** — users can return to work more easily if the timer doesn't insist on itself.

### UI Language

**Japanese-first, English for key elements only** (e.g., `FOCUS` / `BREAK` session chips). Rationale:

- The user is a native Japanese speaker. Optimizing for domestic UX results in a "thoughtful" experience.
- The i18n layer is an unnecessary cost for v1. I will structure it so `i18next` can be added later if needed (keeping wording organized at module boundaries).

---

## 2. Technology Selection and Design Philosophy

### Stack

| Layer | Selection | Rationale |
| --- | --- | --- |
| Build | **Vite 7** | Fast HMR, TS native, small bundle |
| Framework | **React 19 + TypeScript (strict)** | Specified + Type safety |
| Styling | **Tailwind CSS v4** (CSS-first `@theme`) | `node_modules` already present. v4 allows declaring color palettes as CSS variables via `@theme`, high affinity with custom designs. Fastest trial-and-error speed via utility, 0 KB runtime |
| State Management | **Zustand + persist middleware** | No Provider needed, selector-based re-rendering, auto-sync with localStorage via `persist`. Lighter than Context+useReducer, not as excessive as Redux |
| Animation | **Framer Motion** + native CSS transform | State transitions (focus↔break) via Framer's `AnimatePresence`, high-frequency breathing rings via CSS transform to guarantee 60fps |
| Timer Engine | `requestAnimationFrame` + `performance.now()` | `setInterval` precision collapses in background tabs. RAF + wall clock reference for **drift-free** timing |
| Audio | **Web Audio API (Synthesis)** | Bells, white noise, and rain sounds are all synthesized. No audio files bundled → lightweight bundle + copyright-free |
| Icons | **lucide-react** | Elegant thin lines, tree-shakeable |
| Testing | **Vitest + RTL** | Minimal coverage focused on state machine logic (cycles, time calculation) |
| PWA | **vite-plugin-pwa** | Installable, offline-capable. Essential for exceeding the threshold of "app-likeness" |

### Custom Color Palette — "Nocturne × Ember"

Why default to dark mode: Deep work often happens in the evening/night in low-light environments. Dark mode reduces cognitive load.

| Role | Name | Hex | Note |
| --- | --- | --- | --- |
| Base Background | **Nocturne** | `#0B0B14` | Near-black with a touch of blue, not pure black. Reduces eye strain |
| Surface | **Slate Plum** | `#141525` | Cards, modal backgrounds |
| Surface (Raised) | **Raised Plum** | `#1E1F33` | Buttons, chips |
| Border | **Soft Cinder** | `#2A2B42` | Low-contrast separators |
| **Focus Accent** | **Ember** | `#FF6B35` | Warm orange. Avoids red=stress, suggests positive focus (similar to Philips Hue "concentrate" line) |
| **Short Break Accent** | **Sage** | `#7FB99F` | Pale green to evoke the parasympathetic nervous system |
| **Long Break Accent** | **Lavender** | `#9B8DD4` | Restorative and dreamy |
| Primary Text | **Mist** | `#F2EFE8` | Ivory, not pure white `#FFF` → Harmonizes with Ember, avoids glare |
| Secondary Text | **Dust** | `#8B8AA3` | Descriptions and meta-info |
| Deep Shadow | **Shadow Plum** | `#05050A` | Ring shadows, modal overlays |

By **using three different accent colors**, I provide emotional signatures for session types, allowing instant state identification through color (forming muscle memory).

### Visual Characteristics of UI

1. **Single-screen, centered giant ring timer**. Decorations recede to the periphery.
2. **Aurora Backdrop**: 2–3 low-saturation `radial-gradient` layers in the background, shifting 1.2s ease-in-out based on session color. Depth that avoids flatness.
3. **Grain Overlay**: SVG noise overlaid at 3% opacity. Removes "AI-like flatness" and adds texture.
4. **Vignette**: Subtle darkening toward the screen edges via `radial-gradient`, drawing the gaze toward the center.
5. **Typography**: `Inter Tight` variable font. Timer digits use `font-variant-numeric: tabular-nums` + `font-feature-settings: "tnum"` to prevent jittering.
6. **Border Radius**: Large motifs are `20–28px`, smaller elements `12–14px`. Rounded enough to calm, but not excessive.

---

## 3. Function and Presentation Plan

### Core Features

1. **Timer Engine**: 25m Focus / 5m Short Break / 15m Long Break (customizable), long break after 4 cycles.
2. **Breathing Ring**: Progress via SVG `stroke-dasharray`, with a very subtle scale vibration (approx. 2% amplitude, 8s period) for focus. Regulates breathing subconsciously. Gentler during breaks.
3. **Task Anchor**: Voluntary input field for "Current Task." Displayed faintly behind the ring during focus to re-anchor immediately if attention drifts.
4. **Keyboard First**:
   - `Space`: Start/Pause
   - `R`: Reset
   - `S`: Skip to next session
   - `F`: Full-screen focus mode (UI fades after 3s inactivity)
   - `1`/`2`/`3`: Switch session type
   - `?`: Shortcut list
5. **Ambient Sound Layer**: Brown noise / Rain (white noise → LPF → random transients) / Silent, synthesized via Web Audio. Volume slider, disabled by default.
6. **Ritual of Completion**:
   - Bell: Soft 3-tone chime (OscillatorNode + GainNode envelope, rich ADSR)
   - Bloom: 40 light particles radiating from the ring edge, disappearing in 0.8s (disabled for `prefers-reduced-motion: reduce`)
   - Toast: Daily achievements and encouragement
7. **Session Ledger (Heatmap)**: Monthly heatmap similar to GitHub contributions. Completed Pomodoros accumulate as density. **Visualizing habituation** is the ultimate motivational device.
8. **Daily Goal**: Goal count displayed as a thin circle progress indicator on the side.
9. **Auto-continue**: Toggle for "Automatically start next session upon completion."
10. **Tab Title Sync**: `25:00 · Focusing` → Tab state visible at a glance.
11. **Wake Lock**: Prevents screen sleep during focus (Screen Wake Lock API).
12. **Browser Notifications**: Triggered upon session end. Permission dialog requested **only upon the first start** (not on page load = avoid pestering).
13. **Settings Dialog**: Session lengths, daily goals, audio, theme, data reset.
14. **PWA**: Manifest + Icons + Offline launch.
15. **Respect for Reduced-motion**: Automatically disables breathing vibration and particles for `prefers-reduced-motion: reduce`.

### Animation Details (Effects to Enhance Focus)

- **Session Transition Sweep**: 1.2s ease-in-out color transition for focus → break. Synchronization of ring color, aurora backdrop, and Ember → Sage/Lavender. Physically feel the "passage of time."
- **Digit Tweening**: When minutes change, old digits fade out `y: -8px`, new digits enter `y: 8px → 0` (Framer `AnimatePresence`, 150ms). **Seconds do not tween** (conserves battery).
- **Play/Pause Icon Morph**: Framer SVG path morph between triangle ↔ bar.
- **Button Press**: `scale: 0.97` + 1px inner shadow. Physical sensation of pressing.
- **Full-screen Focus Mode**: Header/footer fades to `opacity: 0` after 3s inactivity, restored by mouse movement.

### Drift Countermeasures (Unassuming but critically effective UX)

Implementations based on `setInterval(tick, 1000)` cause **1s to stretch to 3s when the tab is in the background**, leading to drifts in 25-minute focus sessions. My implementation uses:

```
const startedAt = performance.now();
const tick = () => {
  const elapsed = performance.now() - startedAt;
  // Calculate remaining time each time. References absolute clock instead of cumulative intervals.
  rafId = requestAnimationFrame(tick);
};
```

→ Accuracy within ±50ms even after switching tabs.

---

## 4. File Structure (Target Paths)

```
pomodoro-timer/
├── index.html
├── package.json                        # New (scripts: dev/build/preview/test/lint)
├── tsconfig.json / tsconfig.node.json  # strict
├── vite.config.ts                      # React + PWA plugin
├── tailwind.config not needed (v4 uses CSS @theme)
├── public/
│   ├── icon-192.png / icon-512.png     # PWA icons
│   └── favicon.svg
├── src/
│   ├── main.tsx
│   ├── App.tsx
│   ├── styles/
│   │   └── globals.css                 # @import "tailwindcss"; @theme { --color-ember: #FF6B35; ... }
│   ├── components/
│   │   ├── Timer/
│   │   │   ├── TimerRing.tsx           # SVG progress ring + breathing
│   │   │   ├── TimerDigits.tsx         # Animated digits
│   │   │   ├── TimerControls.tsx       # play/pause/reset/skip
│   │   │   └── TaskAnchor.tsx          # "Current task"
│   │   ├── Session/
│   │   │   ├── SessionTabs.tsx         # focus/short/long
│   │   │   └── SessionBadge.tsx        # state chip
│   │   ├── Ledger/
│   │   │   └── HistoryHeatmap.tsx
│   ├── store/
│   │   ├── timerStore.ts               # Zustand: kind/phase/startedAt
│   │   ├── settingsStore.ts            # Zustand persist: time/goals
│   │   └── historyStore.ts             # Zustand persist: completion log
│   ├── hooks/
│   │   ├── useTimer.ts                 # RAF drift-free tick
│   │   ├── useKeyboardShortcuts.ts
│   │   └── useWakeLock.ts
│   ├── audio/
│   │   ├── bell.ts                     # Completion chime
│   │   └── ambient.ts                  # Brown noise / Rain synth
│   └── ...
└── tests/
    ├── sessionPattern.test.ts
    └── formatTime.test.ts
```

---

## 6. Verification

1. `npm install && npm run dev` → Open http://localhost:5173
2. Verify `25:00 · FOCUS` is displayed with Ember ring.
3. Press `Space` → start, breathing animation begins, title syncs to `25:00 · Focusing`.
4. Change focus time to **0.1 min** (6 sec) via settings → verify completion.
5. Upon completion: Bell + particle bloom + toast, heatmap updated, auto-transition to Short Break.
6. Verify time remains accurate after backgrounding tab for 30s (drift check).
7. Press `F` for full-screen mode, verify chrome fade-out after 3s.
8. Verify ambient "Rain" works and volume slider is effective.
9. Emulate `prefers-reduced-motion: reduce` in DevTools → verify breathing/particles are disabled.
10. Verify Lighthouse PWA score 90+.
11. Run `npm test` → verify unit tests for `sessionPattern` and `formatTime` pass.

---

## 7. Recommended Implementation Order

1. **Scaffolding**: `package.json`, `tsconfig`, `vite.config.ts`, `globals.css`
2. **State**: `timerStore`, `settingsStore`, `historyStore`, `sessionPattern`, `formatTime`
3. **Hooks**: `useTimer`, `useKeyboardShortcuts`
4. **Base UI**: `App`, `TimerRing`, `TimerDigits`, `TimerControls`, `SessionTabs`
5. **Effects**: `AuroraBackdrop`, `GrainOverlay`, `CompletionBloom`
6. **Extensions**: `TaskAnchor`, `SettingsDialog`, `HistoryHeatmap`
7. **APIs**: `useWakeLock`, notifications, audio
8. **PWA & QA**

Sonnet 4.6 — Minimalist "CSS-First"

Sonnet's personality appeared most strongly in its styling methodology. It uses CSS Modules + CSS Custom Properties, achieving color transitions for all components in 800ms simply by toggling body.mode-work / body.mode-shortBreak / body.mode-longBreak classes. It declares that it will not use Framer Motion, opting for pure CSS animations to reduce bundle size and maintain full control.

On the other hand, it has a distinct tendency to limit functionality. There are no keyboard shortcuts other than Space, and no ambient sounds, Wake Lock, or heatmaps. The timer implementation is also a relatively simple construction updated at 1-second intervals. Its habit of leaving design intent in HTML comments is another peculiar trait.

However, Sonnet was the only one of the 4 models that did not generate a .gitignore. This reveals a minimalist side: it creates clean CSS designs but tends to skip peripheral administrative tasks.

Codex — Prose-based "Proposal"

Codex (GPT-5.4)'s plan appeared in a completely different format.

## Summary
## Implementation Changes
## Public APIs / Types
## Test Plan
## Assumptions

This is a template unique to Codex's planning mode, with almost flat hierarchy, no tables or diagrams, and no code snippets. Everything is composed of prose, and coverage of the requested study items was relatively thin.

Instead, a feature of this plan is that every decision is accompanied by "The reason for ~ is...". It feels like a diff-first template conscious of patching existing code, and it applies the same format even for zero-to-one projects like this.

Cursor — Specification based on YAML + Mermaid

Cursor's plan had yet another distinct character. It starts with YAML frontmatter.

---
name: Pomodoro Web App
overview: ...
todos:
  - id: scaffold-vite
    ...
isProject: false
---

This todos: list is treated by Cursor as a machine-readable task queue. In other words, the plan is a direct execution blueprint. Whereas Claude Code's plan is a "human-readable design document," Cursor's plan is heavily weighted toward a "DSL for the execution engine." A Mermaid architecture diagram was also included in the text, a feature not seen in other tools.

Comparing the 3 Planning Modes

Axis Claude Code Codex Cursor
Chapters Deep (6-7 sections) Shallow (5, flat) Medium (3 sections + YAML)
Table usage × (All prose)
Code snippets × × (Mermaid only)
Machine-readable No No YAML todos / Mermaid
Rationale Accompanies each chapter Required for every decision Key points only
Expected Reader Human (Implementer) Human (Implementer) Human + Engine

Claude Code is a "design doc for humans," Codex is a "memo for design policy," and Cursor is a "specification for the execution engine." At least in this comparison, the plans differed significantly in form even for the same prompt. In terms of the experience of reading them as design documents, Claude Code was the most stable.

Sidebar: Models that asked "questions" despite being told to do everything

Immediately after starting, Codex and Opus asked follow-up questions. These included 5-6 points regarding the ideal outcome, use cases, notification scope, UI language, and scope elements. While Cursor and Sonnet started silently, the difference in philosophy regarding whether to try and clarify unknowns even when told "I entrust everything to you" was interesting.

Model Personalities Seen in Implementation Results

Finally, reading through the implementations reveals that each of the 4 models had distinct personalities.

Opus 4.7 — The Perfectionist who packs everything in

Opus has the highest volume of information and features. It included keyboard shortcuts, environmental sounds (brown noise/rain synthesis), Wake Lock, PWA support, heatmaps, and tab title synchronization—features I hadn't even specified. Dependency libraries were heavy (Zustand / Framer Motion / lucide-react / vite-plugin-pwa), and the timer implementation was the only one based on requestAnimationFrame + performance.now().

Color naming was also poetic: Nocturne / Slate Plum / Soft Cinder / Ember / Sage / Lavender—using evocative proper names for dark/purple shades, contrasting with the functional names used by other models. It often "raised the UX bar without being asked," such as adding hover:bg-slate-800 voluntarily and implementing input validation. However, the fact that it had 10 vulnerabilities (5 moderate, 4 high, 1 critical) when I ran npm install is a point of concern; it might be better to run dependency updates or a review before pushing this to production.

GPT-5.4 — The Accessibility Specialist focused on the "Why"

GPT's personality was focused on invisible robustness. The timer implementation combines setInterval(250ms) with deadline-based remaining time calculation, making it the most meticulous in precision design among the four. It thoroughly incorporated aria-live / role="tab" / aria-label, building accessibility support from the start.

It was the only one to use a light paper-themed color palette (#F6F1E8 canvas + #D95D39 warm brown), explicitly stating the rationale of reducing glare. It was also the only model to have a "Design Concept" card implemented inside the screen. It was also the only model with a ## Test Plan from the planning stage, which it actually implemented as a set of test files. Not only talking about "why," but building mechanisms to verify what it says was GPT's strength.

Composer 2 — The Honest MVP with GitHub Colors

Composer's personality was condensed into simplicity with minimal dependencies and GitHub Primer color schemes. It used only React and React-DOM as external libraries. It defined color tokens with Tailwind v4's @theme and completed everything with plain CSS. The colors were quite close to GitHub's dark theme. It also had a clear demarcation between MVP and out-of-scope items, making it easy to use for customer mocks where you want to avoid "over-delivering."

Summary: Select by Plan, Build by Model

What this verification revealed is a two-layered structure:

  • Tool design philosophy determines the plan format (Reading material / Prose proposal / YAML specification).
  • Model characteristics appear in the plan details and implementation (feature density, color vocabulary, peripheral awareness, and commitment to drift prevention).

This is an era of asking "with which AI is it comfortable to work" rather than "which AI is superior." The sense of selecting an AI as a 'master craftsman partner' is stronger than ever. Planning with the tool's forte and implementing by anticipating the model's temperament seems to be the next stage of AI coding.


株式会社ギックス

Discussion