Design handoff (bàn giao thiết kế) là một trong những khâu tốn thời gian nhất trong quy trình phát triển frontend — designer làm xong frame trên Figma, developer phải tự đọc, tự đo spacing, tự suy ra token màu, rồi gõ lại thành code, sai lệch vài pixel là chuyện thường. Kết hợp Figma MCP server và GitHub MCP server cho phép AI agent đọc trực tiếp cấu trúc design (không phải đọc ảnh chụp màn hình), lấy đúng design token, sinh code component khớp với design system hiện có, rồi tự mở PR. Bài này đi qua toàn bộ chuỗi: từ frame Figma đến component đã được review và sẵn sàng deploy.
Tổng Quan Workflow: Từ Frame Figma Đến Component Production-Ready Qua AI
Khác với cặp GitHub + Jira (chủ yếu là dữ liệu text: ticket, PR, comment), cặp Figma + GitHub có một khác biệt lớn: dữ liệu từ Figma là structured design data — cây node (frame, group, text, vector), thuộc tính layout (auto-layout, constraints), và design token (color, typography, spacing) — không phải ảnh. Agent hiểu Figma tốt hơn nhiều so với hiểu ảnh chụp UI, vì nó nhận được JSON có cấu trúc rõ ràng, không phải phải "đoán" dựa trên pixel.
Figma MCP server GitHub MCP server
────────────────── ──────────────────
Frame "CheckoutButton" ──read──► agent đọc design context:
- layout: auto-layout horizontal component structure,
- fill: token "color/primary/600" token mapping, spacing
- padding: 12px 24px
- text: "Thanh toán ngay"
- variant: default/hover/disabled
agent map token Figma
sang token trong codebase
(Tailwind config / CSS vars)
agent sinh component code
◄─write── src/components/CheckoutButton.tsx
agent mở PR
◄─write── PR #789 kèm ảnh preview
Comment PR "cần review design" ◄──── agent (hoặc reviewer) mở lại
Figma frame để so sánh
Yếu tố quyết định chất lượng output ở workflow này không nằm ở GitHub MCP (phần "viết code, mở PR" khá chuẩn ở mọi workflow), mà nằm ở độ chính xác khi agent đọc và map dữ liệu Figma. Nếu design system của bạn không có token đặt tên nhất quán (ví dụ designer đặt màu là "Blue 600" còn code dùng biến --color-primary-600), agent phải tự suy luận ánh xạ — và đây là nơi dễ sai nhất, cần bạn kiểm soát bằng một bước map rõ ràng trước khi sinh code.
Mẹo: Trước khi chạy workflow này lần đầu, dành 15 phút liệt kê rõ bảng ánh xạ token Figma ↔ token code (trong CLAUDE.md hoặc file style-guide riêng) — ví dụ "Figma 'color/primary/600' = CSS var
--color-primary-600= Tailwind classbg-primary-600". Không có bảng này, agent sẽ tự bịa tên biến mới mỗi lần chạy, phá vỡ tính nhất quán của design system.
Bước 1: Trích Xuất Design Context Và Design Token Từ Figma Bằng MCP
Figma MCP server (chạy qua Figma Desktop app ở dev-mode, expose local server tại 127.0.0.1:3845) cho agent hai loại dữ liệu chính: design context của một node cụ thể (cấu trúc layout, thuộc tính, text content) và design token/variable (màu, spacing, typography được định nghĩa ở cấp design system, không phải hard-code trên từng node).
Chọn frame trong Figma (hoặc dán link frame trực tiếp vào prompt — Figma MCP server tự parse node-id từ URL), rồi yêu cầu:
Lấy design context của frame có link:
https://www.figma.com/design/abc123/Checkout?node-id=42-108
Liệt kê rõ:
- Cấu trúc layout (auto-layout direction, gap, padding)
- Toàn bộ text content và font style áp dụng
- Toàn bộ màu/token được dùng (fill, stroke), ưu tiên trả về
tên variable/token nếu node được bind vào token, không chỉ
trả về giá trị hex thô
- Các variant nếu đây là component có state (default/hover/disabled)
Kết quả trả về (rút gọn) trông giống:
{
"name": "CheckoutButton",
"type": "COMPONENT_SET",
"layout": { "mode": "HORIZONTAL", "gap": 8, "padding": [12, 24, 12, 24] },
"variants": ["default", "hover", "disabled"],
"children": [
{
"type": "TEXT",
"characters": "Thanh toán ngay",
"style": { "fontFamily": "Inter", "fontWeight": 600, "fontSize": 16 }
}
],
"fills": [{ "boundVariable": "color/primary/600" }],
"cornerRadius": 8
}
Điểm mấu chốt: "boundVariable": "color/primary/600" — đây là token đã được designer bind, khác hẳn với việc chỉ trả về "fills": [{"color": "#2563EB"}] (giá trị hex thô, không có ngữ cảnh token). Nếu design chưa dùng variable/token nhất quán (nhiều team ở giai đoạn đầu design system còn hard-code màu), agent sẽ chỉ nhận được hex — trong trường hợp đó, bạn cần thêm bước map thủ công hex → token gần nhất trong prompt, hoặc yêu cầu designer chuẩn hoá token trước khi chạy workflow tự động này.
Với component có nhiều variant (default/hover/disabled), luôn yêu cầu agent lấy context của toàn bộ component set, không chỉ 1 variant — thiếu variant nào, code sinh ra thiếu state đó, và lỗi này chỉ lộ ra khi QA/design review, không lộ ra lúc build.
Mẹo: Khi frame Figma dùng token nhất quán (bound variable), luôn yêu cầu agent ưu tiên trả về tên token thay vì giá trị hex — thêm câu "ưu tiên tên token/variable, không chỉ giá trị thô" vào prompt như ví dụ trên. Thiếu câu này, agent thường trả hex vì đó là dữ liệu "hiển nhiên" hơn, và bạn sẽ mất mối liên kết với design system khi sinh code ở bước sau.
Bước 2: Sinh Code Component Và Push Lên Branch GitHub
Với design context đã lấy được, bước tiếp là để agent viết code component khớp với stack thực tế của project (React + Tailwind, Vue + CSS Modules...) — quan trọng nhất là map token Figma sang token code đã có, không tạo token mới trùng lặp:
Dựa trên design context của component CheckoutButton vừa lấy,
sinh React component tại src/components/CheckoutButton.tsx, dùng
Tailwind CSS theo convention hiện có trong project (xem
tailwind.config.js để lấy đúng tên class màu tương ứng token
"color/primary/600").
Yêu cầu:
- Support đủ 3 state: default, hover, disabled (dùng prop `disabled`)
- Text nội dung nhận qua prop `children`, không hard-code
"Thanh toán ngay"
- Viết kèm 1 file Storybook story minh họa cả 3 state
- Không tạo class Tailwind mới nếu class tương đương đã tồn tại
trong config — kiểm tra tailwind.config.js trước khi sinh code
Component sinh ra (rút gọn):
// src/components/CheckoutButton.tsx
import { ButtonHTMLAttributes } from 'react';
interface CheckoutButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
}
export function CheckoutButton({ children, disabled, ...rest }: CheckoutButtonProps) {
return (
<button
className={`inline-flex items-center gap-2 rounded-lg px-6 py-3
font-semibold text-white transition-colors
${disabled
? 'bg-primary-300 cursor-not-allowed'
: 'bg-primary-600 hover:bg-primary-700'}`}
disabled={disabled}
{...rest}
>
{children}
</button>
);
}
Sau khi có code, commit và push qua GitHub MCP server — bước này giống hoàn toàn quy trình ở workflow GitHub + Jira đã học trước đó:
Tạo branch feature/checkout-button-component từ main trong repo
acme/checkout-web. Commit code với message:
"feat(ui): add CheckoutButton component từ Figma design".
Push branch lên remote.
Một chi tiết dễ bỏ sót nhưng ảnh hưởng lớn tới chất lượng review: yêu cầu agent đọc code component tương tự đã có trong codebase trước khi sinh code mới (ví dụ đọc PrimaryButton.tsx nếu đã tồn tại), để giữ nhất quán về convention prop naming, cấu trúc file, cách export — tránh tình trạng mỗi component sinh ra bởi agent lại theo một "style" hơi khác component cũ do người viết tay.
Mẹo: Luôn yêu cầu agent đọc ít nhất 1 component tương tự đã có trong codebase (cùng category: button, input, card...) trước khi sinh component mới. Bước này tốn thêm vài giây, nhưng đổi lại code sinh ra khớp convention hiện có ngay từ lần đầu, giảm hẳn số comment review kiểu "đổi tên prop cho khớp convention".
Bước 3: Mở PR Và Yêu Cầu Design Review Từ Các Bên Liên Quan Trên Figma
Với UI component, review chỉ ở phía code (GitHub PR review) là không đủ — designer cần xác nhận component render đúng ý đồ thiết kế, đặc biệt phần spacing, màu ở state hover/disabled thường sai lệch nhẹ khi convert từ design sang code thật. PR nên có preview và link ngược về đúng frame Figma gốc:
Mở PR từ feature/checkout-button-component vào main.
Title: "feat: CheckoutButton component (từ Figma CheckoutButton frame)"
Description gồm:
- Link tới frame Figma gốc: https://www.figma.com/design/abc123/Checkout?node-id=42-108
- Danh sách state đã implement: default, hover, disabled
- Ghi chú rõ: "Cần design review trước khi merge" và tag reviewer @figma-team
- Đính kèm ảnh chụp Storybook (nếu CI có bước export ảnh)
Nếu team dùng Figma Dev Mode với tích hợp GitHub, PR sẽ tự động hiện link "compare with design" — nhưng nếu không có tích hợp sẵn, agent nên tự thêm rõ liên kết trong description như trên, đừng để reviewer phải tự đi tìm frame gốc trong Figma.
Khi designer review và để lại comment (ví dụ "padding hover state nên là 14px không phải 12px"), quy trình khép vòng bằng cách agent đọc lại comment PR, đối chiếu ngược với Figma frame (có thể designer đã update trực tiếp trên Figma), rồi tự sửa code:
Đọc toàn bộ comment chưa resolve trên PR #789.
Với mỗi comment liên quan đến spacing/màu, kiểm tra lại giá trị
hiện tại trên frame Figma gốc (link đã có trong PR description)
để xác nhận giá trị đúng, rồi sửa code khớp theo.
Sau khi sửa xong từng comment, reply lại comment đó xác nhận
đã sửa, kèm commit SHA liên quan.
Đây chính là điểm workflow multi-MCP tỏa sáng: agent không chỉ đọc feedback dạng text (comment PR) mà còn tự tra lại nguồn sự thật (Figma frame) để xác nhận trước khi sửa, thay vì chỉ đoán ý người review dựa trên câu chữ.
Mẹo: Khi resolve comment design review, luôn yêu cầu agent trỏ lại Figma frame làm nguồn sự thật (source of truth) trước khi sửa code, không chỉ dựa vào câu chữ trong comment. Comment con người viết ra thường thiếu số liệu chính xác ("hơi rộng quá") — Figma frame mới có giá trị pixel chính xác agent cần.
Vài Lưu Ý Thêm
- Chuẩn hoá bảng ánh xạ token Figma ↔ token code trước khi tự động hoá — thiếu bước này, mỗi lần chạy agent sẽ tạo token/class mới không nhất quán.
- Ưu tiên lấy tên token/bound variable từ Figma, không chỉ giá trị hex thô, để giữ liên kết với design system.
- Luôn lấy design context của toàn bộ component set (mọi variant/state), không chỉ variant default.
- Cho agent đọc component tương tự đã có trong codebase trước khi sinh code mới, để giữ convention nhất quán.
- Khi resolve feedback design review, luôn đối chiếu lại Figma frame gốc, không chỉ dựa vào câu chữ comment.
Mẹo: Với những component dùng lại nhiều lần (button, input, card...), đầu tư làm đúng 1 lần bảng ánh xạ token và 1 component mẫu chất lượng cao để agent dùng làm "few-shot example" khi đọc trước lúc sinh component mới — chi phí ban đầu này trả lại nhiều lần khi workflow được lặp lại cho hàng chục component sau đó.