appllama-app-design-skill
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAppllama App Design Skill
Appllama 应用设计技能
You are building screens that will sit on a phone next to the best-designed apps
in the world. The user will compare your output to those apps within seconds of
launching it. This skill defines the bar and the method for clearing it.
你正在构建的界面,将会和全球设计最出色的应用一同出现在用户手机上。用户在启动应用后的几秒内,就会将你的成果与这些顶尖应用进行对比。本技能定义了达到顶尖水准的标准与方法。
The Prime Directive: study before you draw
核心准则:先研究再设计
Never design a screen from imagination when you can study how top apps solved
the same screen. Real, shipping, revenue-ranked apps encode thousands of hours
of design iteration and A/B testing. Your first move on any screen is research:
- If the Appllama MCP is connected, pull real screens for the category and
screen type you are building (see the skill for the exact research playbooks). Study 20–30 screens before writing a line of UI code.
appllama-usage - Extract the pattern, not the pixels: layout skeleton, information hierarchy, control choices, spacing rhythm, where the primary CTA sits, what gets an illustration vs. plain text, how progress is communicated. Note: every Appllama image and video carries a small Appllama watermark in the top-left corner. It is provenance, not design — ignore it when reading a screen (it may sit over the status bar or a back button) and never reproduce it in anything you build.
- Then design your screen: same proven skeleton, your product's voice. Copying a competitor's screen 1:1 is both lazy and legally risky; shipping a screen that ignores every convention users already know is worse.
当你可以研究顶尖应用如何解决同类界面问题时,绝不要凭空设计界面。真实上线、营收排名靠前的应用,凝聚了数千小时的设计迭代与A/B测试。处理任何界面的第一步都是调研:
- 如果已连接Appllama MCP,提取你要构建的类别和界面类型对应的真实界面(参考技能中的具体调研指南)。在编写任何UI代码前,先研究20–30个界面。
appllama-usage - 提取模式而非像素:布局框架、信息层级、控件选择、间距节奏、主CTA的位置、哪些内容用插画哪些用纯文本、进度如何传达。 注意:所有Appllama的图片和视频左上角都带有小型水印,这是来源标识而非设计元素——解读界面时请忽略它(它可能覆盖状态栏或返回按钮),且绝不要在你构建的内容中重现它。
- 然后设计你的界面:采用经过验证的框架,融入产品自身的风格。1:1复制竞品界面既偷懒又有法律风险;而完全无视用户已熟知的所有惯例来开发界面则更糟糕。
Platform baseline
平台基准
Default stack assumptions (override only if the project already differs):
- Expo + Expo Router, React Native, TypeScript.
- for motion,
react-native-reanimatedfor gestures,react-native-gesture-handler(or FlashList v2) for any list that can grow.@shopify/flash-list - for images (and SF Symbols via
expo-imageon iOS),source="sf:name"/expo-video(never the deprecatedexpo-audio).expo-av - for insets. Never hard-code notch numbers.
react-native-safe-area-context - over
process.env.EXPO_OSfor compile-time platform checks.Platform.OS
默认技术栈假设(仅当项目已有不同配置时才覆盖):
- Expo + Expo Router、React Native、TypeScript。
- 使用实现动效,
react-native-reanimated处理手势,react-native-gesture-handler(或FlashList v2)实现任何可滚动增长的列表。@shopify/flash-list - 使用处理图片(iOS上通过
expo-image调用SF Symbols),source="sf:name"/expo-video(绝不要使用已废弃的expo-audio)。expo-av - 使用处理内边距。绝不要硬编码凹槽数值。
react-native-safe-area-context - 编译时平台检查使用而非
process.env.EXPO_OS。Platform.OS
Native fidelity laws
原生保真度规则
These are the details that separate "web page in a wrapper" from "native app".
Violating any of them is a finding, not a style preference.
- Semantic colors, both themes, day one. Use system/semantic color tokens
(e.g. from
Coloron iOS:expo-router,Color.ios.label; Material dynamic colors on Android). Every screen must render correctly in light AND dark before it is "done". Never pass semantic color objects into Reanimated animated styles — resolve to strings first.Color.ios.secondarySystemBackground - Native controls over rebuilt ones. Switch, Slider, SegmentedControl, context menus, date pickers: use the native control or a faithful wrapper. A rebuilt toggle that animates 50 ms differently than iOS's reads as fake instantly.
- SF Symbols / Material Symbols for iconography. On iOS prefer SF Symbols
(with
expo-imagesources, orsf:); they inherit weight, optical size, and Dynamic Type behavior. Do not mix three icon families on one screen.expo-symbols - Typography is hierarchy. Use the platform type ramp (Large Title / Title
/ Headline / Body / Footnote on iOS). One display size per screen. Tabular
numerals () for anything that counts, times, or prices.
fontVariant: ['tabular-nums']on data users may want to copy.Text selectable - Continuous corners. on every rounded rectangle. Squircles are the single cheapest "feels iOS" win that exists.
borderCurve: 'continuous' - Shadows via CSS , not legacy
boxShadow/shadow*props. Shadows are for elevation logic, not decoration — one elevation system per app.elevation - Spacing rhythm. Pick a base unit (4 or 8) and never leave it. Prefer
flexbox over margin stacking. ScrollView padding goes in
gap, never on the ScrollView itself.contentContainerStyle - Safe areas and the Dynamic Island are part of the design. Screens must be verified with content scrolled under the island / status bar (does the blur/fade treatment hold?), with the home indicator (does the bottom CTA clear it?), and in landscape if supported.
- Navigation titles belong to the navigator. Use the stack's native title (and large-title collapse behavior on iOS) rather than a hand-rolled header whenever possible.
- Haptics are punctuation. Light impact on selection/confirm on iOS, success/warning notifications for outcomes. Never on scroll, never in loops. Guard with platform checks.
- Format numbers like a product, not a database: 1.4M, 38k, $4.99. Trim trailing zeros. Localize dates.
- Root scroll behavior: screens that can ever overflow wrap content in a
ScrollView (first component in the route) with
. Use
contentInsetAdjustmentBehavior="automatic", neveruseWindowDimensions.Dimensions.get()
这些细节是区分「套壳网页」与「原生应用」的关键。违反任何一条都属于问题,而非风格偏好。
- 从第一天起就支持语义化色彩与双主题。使用系统/语义化颜色令牌(例如iOS上的
expo-router:Color、Color.ios.label;Android上的Material动态颜色)。每个界面在「完成」前,必须确保在亮色和深色模式下都能正确渲染。绝不要将语义化颜色对象传入Reanimated的动画样式——需先解析为字符串。Color.ios.secondarySystemBackground - 优先使用原生控件而非重造控件。开关、滑块、分段控件、上下文菜单、日期选择器:使用原生控件或忠实的封装组件。一个动效与iOS原生开关相差50毫秒的重造开关,会立刻被用户识别为仿制品。
- 图标使用SF Symbols / Material Symbols。iOS上优先使用SF Symbols(通过的
expo-image源,或sf:);它们会继承字重、光学尺寸和动态字体行为。同一界面不要混合使用三种不同的图标库。expo-symbols - 排版即层级。使用平台的字体层级(iOS上的大标题/标题/副标题/正文/脚注)。每个界面仅使用一种显示字号。计数、时间或价格使用等宽数字()。用户可能需要复制的数据,设置
fontVariant: ['tabular-nums']。Text selectable - 连续圆角。所有圆角矩形都设置。圆角矩形是让应用「感觉像iOS应用」的最简单方法。
borderCurve: 'continuous' - 通过CSS 实现阴影,而非旧版的
boxShadow/shadow*属性。阴影用于体现层级逻辑,而非装饰——每个应用仅使用一套层级系统。elevation - 间距节奏。选择一个基础单位(4或8)并严格遵循。优先使用flexbox的而非外边距堆叠。ScrollView的内边距设置在
gap中,绝不要直接设置在ScrollView本身。contentContainerStyle - 安全区域与灵动岛是设计的一部分。必须验证界面在内容滚动到灵动岛/状态栏下方时的表现(模糊/渐变效果是否正常?)、在有主屏幕指示器时的表现(底部CTA是否避开它?),以及支持横屏时的表现。
- 导航标题属于导航器。尽可能使用栈的原生标题(以及iOS上的大标题折叠行为),而非手动实现的头部。
- 触觉反馈是标点符号。iOS上选择/确认时使用轻量震动,结果通知使用成功/警告震动。绝不要在滚动时或循环中使用。需通过平台检查进行适配。
- 像产品一样格式化数字,而非像数据库:1.4M、38k、$4.99。去除末尾的零。日期本地化。
- 根滚动行为:任何可能溢出的界面,都将内容包裹在ScrollView中(路由中的第一个组件),并设置。使用
contentInsetAdjustmentBehavior="automatic",绝不要使用useWindowDimensions。Dimensions.get()
Anti-slop laws
反粗制滥造规则
AI-built apps share a look, and users file it under "template" within seconds.
Each of these is a default ban — there is always an override when the brand
explicitly asks for the thing AND you can articulate why it fits this product.
- No AI-default styling. Purple/indigo gradient CTAs with a glow, glassmorphism on every card, mesh-gradient heroes, confetti for minor events, sparkles in headings — that is the model's house style, not design. Your palette, materials, and layout come from the reference screens you studied, never from the priors you'd reach for unprompted.
- One accent, locked. Pick one accent color and it is THE accent on every screen — no blue CTA on one screen and teal on the next, no new hue appearing in screen seven. Neutrals carry the app; the accent is spent where the money is (primary action, active state, progress).
- One grey family. Warm greys or cool greys — never both in one app.
- Shape lock. One corner-radius scale, stated as a rule ("actions are pills, cards 16, inputs 8") and never violated. Mixed radii without a stated rule read as assembled-from-parts.
- No emoji as iconography. Icons are SF Symbols / Material Symbols (fidelity law 3). Emoji appear only when the product's voice is genuinely chat-native or playful — sparingly, in content, never in chrome.
- One label per intent. "Get started", "Start now", and "Begin" are the same intent — pick one phrasing and use it everywhere it appears.
- Emphasis stays in the family. Emphasize a word with weight or italic of the same typeface; injecting a serif word into a sans headline (or vice versa) for visual interest is amateur.
- Ship full state cycles, not the happy path. Static-successful-state- only is the default failure mode: skeletons must match the final layout's shape, empty states are composed (and say how to fill them), errors are inline and specific.
- The slop pre-flight is mechanical. Before any flow reaches the simulator pass, count: distinct accent hues (must be 1), distinct corner radii (all from the stated scale), emoji in UI chrome (0), gradients without a brand reason (0), duplicate labels for one intent (0). A failed count is a fix, not a judgment call.
AI构建的应用有相似的外观,用户几秒内就能识别出「模板感」。以下所有内容均为默认禁用项——只有当品牌明确要求,且你能说明其适配产品的原因时,才可例外。
- 禁止AI默认样式。带发光效果的紫色/靛蓝色渐变CTA、每个卡片都用毛玻璃效果、网格渐变hero、小事件就撒彩屑、标题加闪光——这些是模型的固有风格,而非设计。你的调色板、材质和布局应来自你研究的参考界面,而非你下意识选择的默认样式。
- 锁定一种强调色。选择一种强调色,并在所有界面中统一使用——不要一个界面用蓝色CTA,另一个用蓝绿色,也不要在第七个界面突然出现新色调。中性色构成应用主体;强调色仅用于关键位置(主操作、激活状态、进度)。
- 仅使用一种灰色系。暖灰色或冷灰色——同一应用中绝不要同时使用两种。
- 形状锁定。定义一套圆角半径规则(例如「操作按钮为胶囊形,卡片圆角16,输入框圆角8」)并严格遵守。无规则混合不同圆角半径会让界面看起来像拼凑而成。
- 禁止用表情符号作为图标。图标使用SF Symbols / Material Symbols(保真度规则3)。表情符号仅在产品风格为原生聊天或活泼风格时使用——且仅用于内容中,绝不要用于界面框架。
- 同一意图使用统一标签。「开始使用」「立即启动」「开始」表达的是同一意图——选择一种表述并在所有相同场景中使用。
- 强调方式保持统一。使用同一款字体的加粗或斜体来强调文字;为了视觉趣味在无衬线标题中插入衬线文字(反之亦然)是业余做法。
- 交付完整状态周期,而非仅快乐路径。仅展示静态成功状态是默认的失败模式:骨架屏必须与最终布局形状一致,空状态需精心设计(并说明如何填充内容),错误提示需内联且具体。
- 反粗制滥造预检是机械性检查。任何流程进入模拟器测试前,统计:不同的强调色数量(必须为1)、不同的圆角半径(全部符合既定规则)、界面框架中的表情符号数量(0)、无品牌理由的渐变数量(0)、同一意图的重复标签数量(0)。统计不合格必须修复,而非主观判断。
Motion laws
动效规则
Motion is the highest-leverage polish surface and the easiest to overdo.
- Every animation needs a reason: continuity (element moves between states), causality (response to a gesture), or orientation (where did this come from). Decoration-only motion gets cut.
- Reanimated worklets on the UI thread for anything tracking a gesture. Gesture → animation must never hop the JS thread.
- Springs over durations for anything the user "touches"; gentle timing curves (250–350 ms, ease-out) for anything the system initiates.
- Entering/exiting animations (,
FadeIn, layout transitions) on list items, modals, and conditional content — subtle, 150–250 ms.SlideInDown - Respect Reduce Motion. Query the accessibility setting and collapse spatial animations to cross-fades.
- The bar to hit: 60 fps on a mid-tier device, zero dropped frames during the hero transition of your flow. Measure, don't vibe — see references/performance.md.
动效是提升质感的最高杠杆点,但也最容易过度使用。
- 每个动画都要有理由:连续性(元素在状态间移动)、因果性(响应用户手势)或导向性(说明来源)。仅用于装饰的动效应删除。
- 跟踪手势的动效使用Reanimated工作线程。手势→动画绝不要跨JS线程。
- 用户「触摸」的元素使用弹簧动效而非固定时长;系统触发的动效使用平缓的时间曲线(250–350毫秒,缓出)。
- 列表项、模态框和条件内容使用进入/退出动画(、
FadeIn、布局过渡)——效果要微妙,时长150–250毫秒。SlideInDown - 尊重减少动效设置。查询无障碍设置,将空间动画转换为淡入淡出。
- 达标要求:中端设备上保持60fps,流程核心过渡无掉帧。需测量而非凭感觉——参考references/performance.md。
State architecture
状态架构
Screens that feel great are screens whose state is boring:
- Server state in TanStack Query (or the project's equivalent): caching,
retries, optimistic updates. Never +
useEffect.fetch - Client state in a small atomic store (Zustand/Jotai). Broad "app state" contexts cause the re-render cascades that make UIs feel heavy.
- Ephemeral UI state (open/closed, focus, scroll) stays local to the component.
- Optimistic by default: taps reflect instantly, reconcile in the background, roll back loudly on failure.
- Uncontrolled s for high-frequency typing surfaces; controlled inputs are a top-3 cause of typing jank.
TextInput - Persist tiny client state in MMKV, not AsyncStorage, when latency shows.
质感出色的界面,其状态管理往往简洁明了:
- 服务端状态使用TanStack Query(或项目的等效工具):缓存、重试、乐观更新。绝不要使用+
useEffect。fetch - 客户端状态使用小型原子状态库(Zustand/Jotai)。宽泛的「应用状态」上下文会导致重渲染连锁反应,让UI显得沉重。
- 临时UI状态(展开/收起、焦点、滚动)保留在组件本地。
- 默认启用乐观更新:点击操作立即反馈,后台进行数据协调,失败时清晰回滚。
- 高频输入场景使用非受控;受控输入是导致输入卡顿的三大原因之一。
TextInput - 当存在延迟问题时,将小型客户端状态持久化到MMKV,而非AsyncStorage。
Perceived performance
感知性能
- Skeletons only for content whose shape you know; otherwise progressive reveal. Never a full-screen spinner for a partial update.
- FlashList for every list; give stable keys.
- Preload the next screen's data on press-in, not on navigation-complete.
- Images: right-size sources, with
expo-imagein lists, thumbhash/blurhash placeholders.recyclingKey - Cold-start TTI and bundle discipline live in references/performance.md — apply the measure → optimize → re-measure loop, never blind memoization.
- 仅对已知形状的内容使用骨架屏;否则使用渐进式加载。局部更新时绝不要使用全屏加载 spinner。
- 所有列表都使用FlashList;提供稳定的key。
- 在用户按下按钮时预加载下一个界面的数据,而非导航完成后。
- 图片:使用合适尺寸的源,列表中使用带的
recyclingKey,使用thumbhash/blurhash占位符。expo-image - 冷启动TTI和包体积优化参考references/performance.md——遵循测量→优化→重新测量的流程,绝不要盲目使用memoization。
Image & illustration assets
图片与插画资源
When a screen calls for illustration, empty-state art, hero imagery, or icons
beyond the symbol set:
- Generate assets with the best image model available to you (e.g. an imagegen tool or the Higgsfield MCP/CLI if connected) at the highest quality settings, then downscale to @1x/@2x/@3x. Never upscale.
- One visual language per app: pick a style (gradient-mesh, flat-duotone, 3D-clay, hand-drawn, mascot style) and generate ALL assets in that same style, same palette, same lighting. A mixed-style asset set reads as template slop.
- Prompt for transparent or solid-flat backgrounds matched to your surface color; composite artifacts (white halos, wrong-color mattes) are an automatic redo.
- Full asset pipeline and prompt patterns: references/image-assets.md.
当界面需要插画、空状态图、hero图或符号库之外的图标时:
- 使用你能获取到的最佳图像生成模型(例如图像生成工具,或已连接的Higgsfield MCP/CLI),以最高质量设置生成资源,然后缩小到@1x/@2x/@3x。绝不要放大。
- 同一应用使用统一视觉风格:选择一种风格(渐变网格、扁平双色调、3D黏土风、手绘风、吉祥物风格),所有资源都使用相同风格、相同调色板、相同光照。混合风格的资源集会显得像模板粗制品。
- 生成时要求透明或与背景色匹配的纯色背景;合成瑕疵(白色光晕、错误颜色的遮罩)需重新生成。
- 完整资源流程和提示模板参考:references/image-assets.md。
The simulator loop (non-negotiable)
模拟器循环(不可协商)
A screen does not exist until you have seen it running. The loop:
- Implement → launch in the iOS Simulator (or Android emulator).
- Screenshot and actually look: alignment, optical centering, spacing rhythm, truncation with long content, dark mode, Dynamic Type at XL.
- Run the full-motion pass below — screenshots prove layout; they prove nothing about motion.
- Fix, relaunch, re-verify. Repeat until you cannot find a defect — then run the checklist in references/simulator-loop.md once more.
Do not declare a screen finished from code review alone. Do not stop at "looks
fine" — stop at "cannot find a flaw at 100% zoom".
只有当你看到界面运行起来后,它才算真正存在。流程如下:
- 实现→在iOS模拟器(或Android模拟器)中启动。
- 截图并仔细查看:对齐方式、视觉居中、间距节奏、长内容截断、深色模式、XL级动态字体。
- 运行下面的全动效检查——截图只能验证布局,无法验证动效。
- 修复、重启、重新验证。重复直到找不到缺陷——然后再运行一次references/simulator-loop.md中的检查清单。
不要仅通过代码评审就宣布界面完成。不要停留在「看起来还行」——要做到「100%缩放时找不到任何缺陷」。
The full-motion pass (mandatory, per flow)
全动效检查(强制要求,每个流程都需执行)
Every flow is evaluated as moving pictures in the simulator, never as
stills. Screen-record the entire flow end to end
(), exercising ALL of it:
xcrun simctl io booted recordVideo flow.mov- every screen transition, push/pop, tab switch
- every modal and sheet: present, drag, dismiss — and cancel mid-drag
- the keyboard, both directions: appear (does the layout glide, is the focused input visible?) and dismiss (does anything jump-cut?)
- every user interaction: press states, gesture follow-through, interrupted gestures, rapid taps, scroll flings at the extremes
Watch the recording twice: once at full speed for feel, once scrubbing
frame by frame. You are hunting:
- dropped or stuttered frames — the bar is a sustained 60 fps through every transition, measured, not vibed
- one-frame flashes: white/unstyled first paint, wrong-theme frames mid- transition, color pops where a surface briefly renders the wrong token
- layout jumps, double-render pops, springs that clip or overshoot into content, elements that reflow after appearing
The whole recording must play like one native piece — smooth end to end,
zero UX glitches. One glitchy frame means the flow is not done.
每个流程都要在模拟器中以动态画面评估,而非静态截图。录制整个流程的屏幕视频(),测试所有场景:
xcrun simctl io booted recordVideo flow.mov- 所有界面过渡、推入/弹出、标签切换
- 所有模态框和底部弹窗:展示、拖动、关闭——以及中途取消拖动
- 键盘:弹出(布局是否平滑滑动,聚焦的输入框是否可见?)和收起(是否有跳变?)
- 所有用户交互:按压状态、手势跟随、中断的手势、快速点击、滚动到极限时的甩动
观看两次录制视频:第一次以正常速度感受整体体验,第二次逐帧查看。你需要排查:
- 掉帧或卡顿——标准是所有过渡持续保持60fps,需测量而非凭感觉
- 单帧闪烁:首次绘制时的空白/未样式化帧、过渡中途的错误主题帧、表面短暂渲染错误颜色令牌导致的颜色跳变
- 布局跳变、双重渲染闪烁、弹簧动效裁剪或过度覆盖内容、元素出现后重新排版
整个录制视频必须像一个原生整体——全程流畅,无UX瑕疵。哪怕有一帧瑕疵,流程都不算完成。
Definition of done, per screen
界面完成标准
- Studied 10+ real reference screens for this screen type (via Appllama MCP when available) and can name the pattern you adopted
- Light + dark mode verified in the simulator
- Safe areas / Dynamic Island / home indicator verified
- Long-content, empty, loading, and error states designed — not defaulted
- Motion: the full flow screen-recorded and scrubbed — entrances, presses, transitions, modals, keyboard — native feel, zero glitch or wrong-color frames; Reduce Motion respected; 60 fps measured on the target device profile
- Dynamic Type XL doesn't break layout; text is selectable where useful
- All tap targets ≥ 44pt; contrast passes in both themes
- Assets: single style family, crisp at @3x, no compositing halos
- List surfaces virtualized; no controlled-input jank; no re-render storms (profiled, not guessed)
- 研究了10+个同类界面的真实参考案例(可用Appllama MCP获取),并能说明你采用的模式
- 在模拟器中验证了亮色+深色模式
- 验证了安全区域/灵动岛/主屏幕指示器适配
- 设计了长内容、空状态、加载状态和错误状态——未使用默认样式
- 动效:录制并逐帧检查了完整流程——进入、按压、过渡、模态框、键盘——具有原生质感,无瑕疵或错误颜色帧;尊重减少动效设置;目标设备配置上测量达到60fps
- XL级动态字体未破坏布局;有用的文本可选择
- 所有点击目标≥44pt;双主题下对比度达标
- 资源:统一风格,@3x下清晰,无合成光晕
- 列表使用虚拟化;无受控输入卡顿;无重渲染风暴(已分析验证,而非猜测)
References
参考资料
| File | Load when |
|---|---|
| references/native-controls.md | Choosing/wiring iOS+Android native controls, menus, pickers, sheets |
| references/motion.md | Any Reanimated work: gestures, transitions, springs, layout animations |
| references/performance.md | Jank, slow TTI, big bundles, memory leaks, profiling method |
| references/image-assets.md | Generating illustrations/icons/hero art with image models |
| references/simulator-loop.md | Final verification checklist + device matrix |
| 文件 | 加载场景 |
|---|---|
| references/native-controls.md | 选择/配置iOS+Android原生控件、菜单、选择器、底部弹窗 |
| references/motion.md | 任何Reanimated相关工作:手势、过渡、弹簧动效、布局动画 |
| references/performance.md | 卡顿、TTI缓慢、包体积过大、内存泄漏、分析方法 |
| references/image-assets.md | 使用图像模型生成插画/图标/hero图 |
| references/simulator-loop.md | 最终验证清单+设备矩阵 |