---
title: My actual Claude Code workflow as a designer
description: "The real daily loop I use to design and ship products with Claude Code. Not a tool list. Four steps, one taste file, and where the human still stays in the work."
date: 2026-07-20
tags: [ai, design, workflow, claude-code]
url: "https://mahdif.com/blog/my-actual-claude-code-workflow-as-a-designer/"
---

# My actual Claude Code workflow as a designer

The real daily loop I use to design and ship products with Claude Code. Not a tool list. Four steps, one taste file, and where the human still stays in the work.

I am a product designer. I have been one for 17 years. And most mornings now I don't open Figma. I open a terminal.

That sentence would have sounded like a gimmick to me two years ago. Today it's just how I work. In the past few months I rebuilt my portfolio site from Astro to Next.js, built a full job search app with its own feed and pipeline, and turned a folder of markdown files into a system that runs half my life. I designed all of it. AI wrote most of the code. Every piece shipped.

This post is the actual workflow. Not the influencer version. The loop I run daily, including the parts that are unglamorous.

<figure style="margin:2.75rem 0;">
<div style="border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--card);">
<svg viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg" style="display:block;width:100%;height:auto" role="img" aria-label="The design to ship loop: write intent, load context and taste, review in the browser, commit, then repeat every phase.">
<defs><linearGradient id="loopgrad" x1="0" y1="0" x2="1200" y2="0" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#6366F1"/><stop offset="0.5" stop-color="#A855F7"/><stop offset="1" stop-color="#EC4899"/></linearGradient></defs>
<style>.lp-bg{fill:var(--card)}.lp-dot{fill:var(--card)}.lp-num{fill:var(--muted-foreground);font-family:var(--font-mono);font-size:16px;letter-spacing:2px}.lp-lbl{fill:var(--foreground);font-family:var(--font-heading);font-size:27px;font-weight:600}.lp-sub{fill:var(--muted-foreground);font-family:var(--font-sans);font-size:16px}.lp-eye{fill:var(--muted-foreground);font-family:var(--font-mono);font-size:19px;letter-spacing:4px}.lp-cap{fill:var(--muted-foreground);font-family:var(--font-mono);font-size:16px;letter-spacing:3px}</style>
<rect class="lp-bg" width="1200" height="630"/>
<text class="lp-eye" x="140" y="98">THE DESIGN-TO-SHIP LOOP</text>
<line x1="150" y1="330" x2="1050" y2="330" stroke="url(#loopgrad)" stroke-width="2.5"/>
<g fill="none" stroke="url(#loopgrad)" stroke-width="2.5" stroke-linecap="round"><path d="M326,322 l9,8 l-9,8"/><path d="M593,322 l9,8 l-9,8"/><path d="M860,322 l9,8 l-9,8"/></g>
<g text-anchor="middle">
<text class="lp-num" x="200" y="188">01</text><text class="lp-lbl" x="200" y="222">Write intent</text><text class="lp-sub" x="200" y="250">not specs</text>
<text class="lp-num" x="467" y="188">02</text><text class="lp-lbl" x="467" y="222">Load context</text><text class="lp-sub" x="467" y="250">taste in a file</text>
<text class="lp-num" x="733" y="188">03</text><text class="lp-lbl" x="733" y="222">Review</text><text class="lp-sub" x="733" y="250">in the browser</text>
<text class="lp-num" x="1000" y="188">04</text><text class="lp-lbl" x="1000" y="222">Commit</text><text class="lp-sub" x="1000" y="250">ship the PR</text>
</g>
<g><circle class="lp-dot" cx="200" cy="330" r="10" stroke="url(#loopgrad)" stroke-width="2.5"/><circle class="lp-dot" cx="467" cy="330" r="10" stroke="url(#loopgrad)" stroke-width="2.5"/><circle class="lp-dot" cx="733" cy="330" r="10" stroke="url(#loopgrad)" stroke-width="2.5"/><circle class="lp-dot" cx="1000" cy="330" r="10" stroke="url(#loopgrad)" stroke-width="2.5"/></g>
<path d="M1000,352 C1000,545 200,545 200,362" fill="none" stroke="url(#loopgrad)" stroke-width="2" stroke-dasharray="2 7" stroke-linecap="round"/>
<path d="M200,362 l-6,13 l13,-1 z" fill="#EC4899"/>
<text class="lp-cap" x="600" y="527" text-anchor="middle">REPEAT EVERY PHASE</text>
</svg>
</div>
<figcaption style="margin-top:0.85rem;text-align:center;font-size:0.85rem;color:var(--muted-foreground);">The loop, start to finish. Every phase runs it again.</figcaption>
</figure>

## Step 1: I write intent, not specs

Every build starts with a few plain sentences. What I want, who it's for, and what done looks like. Not how to build it.

Here's a real one from my job search dashboard: "I want a side panel that opens when I click a role. It should lead with what I need to do next. Everything else collapses."

That's it. No wireframe. No spec doc. The spec was always a translation layer between my head and someone else's hands. When the same person holds both, the translation disappears.

I still sketch when the problem is genuinely visual or novel. But that's the exception now, not the rule.

## Step 2: The context does the heavy lifting

This is the part most people skip, and it's the part that matters most.

Claude Code reads files before it writes code. So I keep files worth reading. Every project has a conventions doc: the stack, the design rules, how things are named, what not to touch. And I keep a written taste file. Mine says things like: light by default, no drop shadows, separation comes from hairlines and tone, collapse detail until it's asked for, strong typography, cut anything that doesn't earn its place.

That file is the difference between getting generic AI output and getting something that looks like I made it. AI has taste defaults. They're not mine. So I wrote mine down, and now every session starts from my defaults instead.

<figure style="margin:2.75rem 0;">
<div style="border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--card);">
<svg viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg" style="display:block;width:100%;height:auto" role="img" aria-label="A file named taste.md listing five design principles: light by default; hairlines and tone, never shadows; collapse detail until it is asked for; strong type, clear hierarchy; cut what does not earn its place.">
<defs><linearGradient id="tastegrad" x1="0" y1="0" x2="0" y2="630" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#6366F1"/><stop offset="0.5" stop-color="#A855F7"/><stop offset="1" stop-color="#EC4899"/></linearGradient></defs>
<style>.ts-bg{fill:var(--card)}.ts-panel{fill:var(--background);stroke:var(--border);stroke-width:1}.ts-line{stroke:var(--border);stroke-width:1}.ts-file{fill:var(--foreground);font-family:var(--font-mono);font-size:21px}.ts-meta{fill:var(--muted-foreground);font-family:var(--font-mono);font-size:14px}.ts-h{fill:var(--foreground);font-family:var(--font-heading);font-size:33px;font-weight:600}.ts-sub{fill:var(--muted-foreground);font-family:var(--font-sans);font-size:19px}.ts-item{fill:var(--foreground);font-family:var(--font-sans);font-size:22px}</style>
<rect class="ts-bg" width="1200" height="630"/>
<rect class="ts-panel" x="150" y="104" width="900" height="422" rx="16"/>
<text class="ts-file" x="196" y="158">taste.md</text>
<text class="ts-meta" x="1004" y="157" text-anchor="end">loaded at the start of every session</text>
<line class="ts-line" x1="150" y1="182" x2="1050" y2="182"/>
<text class="ts-h" x="196" y="250">The file every</text>
<text class="ts-h" x="196" y="291">project starts from.</text>
<text class="ts-sub" x="196" y="351">AI has taste defaults.</text>
<text class="ts-sub" x="196" y="379">These are mine.</text>
<line class="ts-line" x1="606" y1="222" x2="606" y2="470"/>
<g>
<rect x="650" y="233" width="11" height="11" rx="2.5" fill="url(#tastegrad)"/><text class="ts-item" x="680" y="244">Light by default</text>
<rect x="650" y="285" width="11" height="11" rx="2.5" fill="url(#tastegrad)"/><text class="ts-item" x="680" y="296">Hairlines and tone, never shadows</text>
<rect x="650" y="337" width="11" height="11" rx="2.5" fill="url(#tastegrad)"/><text class="ts-item" x="680" y="348">Collapse detail until it's asked for</text>
<rect x="650" y="389" width="11" height="11" rx="2.5" fill="url(#tastegrad)"/><text class="ts-item" x="680" y="400">Strong type, clear hierarchy</text>
<rect x="650" y="441" width="11" height="11" rx="2.5" fill="url(#tastegrad)"/><text class="ts-item" x="680" y="452">Cut what doesn't earn its place</text>
</g>
</svg>
</div>
<figcaption style="margin-top:0.85rem;text-align:center;font-size:0.85rem;color:var(--muted-foreground);">A real page from how I work. The agent reads it before it writes a line.</figcaption>
</figure>

Designers have always been good at articulating principles. It turns out that skill compounds now. A principle you can write clearly is a principle an agent can apply while you sleep.

## Step 3: Build in phases, checkpoint each one

I don't ask for the whole thing. I ask for a phase, review it, save progress, then move on. When something goes wrong, and it does, I lose an hour instead of a day.

The review isn't a code review first. It's a design review. I open the thing in a browser and use it. Does it feel right? Is the hierarchy honest? What can I remove? Same questions I've asked for 17 years. The mockup just happens to be real now.

Then I push back in plain language. "The table is too dense." "This animation is trying too hard." "Why are there three greys here?" The agent revises like the strongest production partner I've ever had: no ego, infinite patience, ships in minutes.

## Step 4: Everything ends in a commit

Real repo, real commits, real deploys. This is non-negotiable for me, and it's the same conviction I built my last product on: AI wins when it ships a PR, not a suggestion. Output you can't ship is a demo. Output in version control is progress.

It also changed what my design artifacts are. My source of truth isn't a Figma file anymore. It's the codebase. When design lives where the product lives, it can't drift out of date.

## Where the human stays

Here's the honest part. The model is genuinely good at building. It is not good at knowing what's worth building, when something feels off, or what to delete. That's still the job.

My time didn't shrink. It moved up a level. Less pushing pixels, more deciding, reviewing, and cutting. I kill features I built the same week I built them, because building got cheap enough that sunk cost finally died. The fastest teams treat everything as disposable. Now one person can.

And the model is sometimes wrong. I design for that in my products, and I work that way with my tools too. Small phases, verifiable checkpoints, everything reviewable. Trust the loop, not the output.

## If you're a designer wanting to start

Start with your own problem, not a client's. Build a tool you'll actually use. The feedback loop of using what you made teaches faster than any course.

Write your taste down. Seriously. One page of design principles you actually believe. It will improve every AI interaction you have.

And lower the stakes. Your first build doesn't need users. Mine was my own website. The tenth one might matter. The first one just needs to ship.

Designers keep asking whether AI will take the craft out of the work. After months of working this way, my answer is the opposite. I've never spent more of my week on judgment, taste, and deciding what deserves to exist. The production moved to the machine. The design moved back to me.
