M3 Expressive: a Material Design 3 skill for AI coding agents

Give Claude Code, Codex, Cursor, Copilot, and Gemini CLI the real Material Design 3 spec. Exact design tokens, per-component dp geometry, motion spring values, shape morphing rules, emphasized typography, color roles, and 2,587 reference images, packaged as an Agent Skill your assistant loads on its own the moment you ask for Material UI.

Agent Skill Material Design 3 Platforms License

claude plugin marketplace add abhixv/google-m3-expressive-design-skill
claude plugin install m3-expressive@m3-expressive

Not on Claude? Jump to Codex, Cursor, GitHub Copilot, Gemini CLI, or Windsurf, Cline, opencode, Zed, and anything else.


Why this exists

Ask any model for a Material 3 Expressive spec and it will answer instantly, in the right vocabulary, with numbers that look exactly like real tokens. Some of them are. The rest are invented, and an invented dp value is indistinguishable from a real one on the page, so it ships.

This skill closes that gap two ways. It puts the actual values in reach, and it holds the model to a source contract: every number, token name, and component name must be looked up, and anything M3 doesn't publish gets labelled as a design decision instead of quietly passed off as spec.

You ask Unassisted With this skill
"Expressive fast spatial spring?" a confident spring that isn't in any token file damping 0.6, stiffness 800
"Radius for a child inside a 48dp card with 16dp padding?" "48dp, keep it consistent" 32dp, since inner = outer − padding
"Gap between the two action buttons?" a number, stated as spec "My design decision (not in M3): 12dp"
"Fade the color with a bouncy spring?" sure color and opacity take effects springs: damping 1.0, no overshoot
"Ship this expressive treatment on web" sure availability is uneven, so it checks platforms.md first

The last two matter as much as the first three. Most Material mistakes aren't missing knowledge, they're plausible defaults applied to the wrong component, and those are what the do/don't rules in each reference catch.

What you get

Path Contents
SKILL.md Entry point: source contract, quick-reference decision table, the 7 expressive tactics, router, common-mistakes table
references/tokens.md The numeric bedrock: 30 type styles, the 10-step corner scale, spring damping/stiffness for both schemes, web curve conversions, elevation, contrast levels
references/component-tokens.md 916 per-component values across 104 component groups: container heights and widths, icon sizes, internal spacing, shape and elevation assignments
references/components/*.md 7 files, 40+ components. The sibling-choice rule ("use this instead of that when..."), anatomy, every size variant, placement, states, color and type role mapping, do/don'ts
references/motion.md, shape.md, typography.md, color.md, color-schemes.md, transitions.md The style systems in depth: motion schemes, 35 shapes and morphing, baseline vs emphasized type, role pairing, dynamic color, transition patterns
references/layout.md, interaction.md, foundations.md, platforms.md Breakpoints and canonical layouts. States, gestures, accessibility. Elevation, spacing, icons. Per-platform API availability
references/expressive-tactics.md The 7 tactics in depth, the research behind them, what actually shipped
visuals/ + references/visuals.md 2,587 images: anatomy diagrams, measurement specs, state grids, do/don't pairs, full-screen canonical layouts, with a greppable caption index
scripts/ Two refresh scripts, for when Material ships an update

Size: text + scripts = 800 KB. Images = 495 MB and entirely optional, since every number lives in the markdown. See slim install.

Install

Claude Code

As a plugin. One command, and claude plugin marketplace update keeps it current:

claude plugin marketplace add abhixv/google-m3-expressive-design-skill
claude plugin install m3-expressive@m3-expressive
claude plugin list                                  # what's installed
claude plugin marketplace update m3-expressive      # pull updates
claude plugin uninstall m3-expressive

As a personal skill. Available in every project. Claude Code picks up any directory under ~/.claude/skills/ that contains a SKILL.md:

git clone https://github.com/abhixv/google-m3-expressive-design-skill.git ~/m3-skill
ln -s ~/m3-skill/skills/m3-expressive ~/.claude/skills/m3-expressive
git clone https://github.com/abhixv/google-m3-expressive-design-skill.git "$env:USERPROFILE\m3-skill"
New-Item -ItemType Directory -Force "$env:USERPROFILE\.claude\skills" | Out-Null
Copy-Item -Recurse -Force `
  "$env:USERPROFILE\m3-skill\skills\m3-expressive" "$env:USERPROFILE\.claude\skills\"

As a project skill. Commit it, and everyone who clones your repo gets it, scoped to that project:

mkdir -p .claude/skills
cp -r /path/to/m3-skill/skills/m3-expressive .claude/skills/
git add .claude/skills/m3-expressive && git commit -m "Add m3-expressive skill"
your-project/
└── .claude/
    └── skills/
        └── m3-expressive/
            ├── SKILL.md
            ├── references/
            ├── scripts/
            └── visuals/        # consider .gitignore-ing, see slim install

Claude apps (web, desktop, mobile)

Zip the text-only build and upload it under Settings > Capabilities > Skills. The images are far past any upload limit, so leave them out. The skill is fully functional without them:

cd /path/to/m3-skill/skills
zip -r m3-expressive.zip m3-expressive -x "m3-expressive/visuals/*"

Codex CLI

Codex reads AGENTS.md, either the repo's at the project root or a global one at ~/.codex/AGENTS.md. Clone the skill once, then point Codex at it:

git clone https://github.com/abhixv/google-m3-expressive-design-skill.git ~/m3-skill

Append the pointer block to ~/.codex/AGENTS.md (global) or your project's AGENTS.md (per-repo). If your Codex version supports skill directories natively, drop it in there instead. Same folder, no changes:

mkdir -p ~/.codex/skills
ln -s ~/m3-skill/skills/m3-expressive ~/.codex/skills/m3-expressive

Cursor

Cursor loads project rules from .cursor/rules/*.mdc. Vendor the skill into the repo, then add a rule that routes to it:

mkdir -p .cursor/rules .agent-skills
cp -r /path/to/m3-skill/skills/m3-expressive .agent-skills/

.cursor/rules/m3-expressive.mdc:

---
description: Material Design 3 / M3 Expressive spec, tokens, component dp, motion springs
globs: ["**/*.kt", "**/*.dart", "**/*.tsx", "**/*.css"]
alwaysApply: false
---

Read `.agent-skills/m3-expressive/SKILL.md` before writing any Material Design UI, then follow
its "Where to look" table into the specific reference file. Never state a dp value, token name,
or spring parameter from memory. Look it up. Label anything not in M3 as a design decision.

GitHub Copilot

Copilot reads .github/copilot-instructions.md. Vendor the skill into the repo and add the pointer block to that file:

mkdir -p .agent-skills .github
cp -r /path/to/m3-skill/skills/m3-expressive .agent-skills/

Gemini CLI

Gemini CLI reads GEMINI.md, at the project root or ~/.gemini/GEMINI.md globally. Same move: clone the skill, add the pointer block.

Any other agent, the universal method

Windsurf (.windsurf/rules/), Cline (.clinerules/), opencode and Zed (AGENTS.md), Aider (CONVENTIONS.md), or anything with a system-prompt file: the mechanism is always the same two steps.

  1. Put the folder somewhere the agent can read. Either .agent-skills/m3-expressive/ in the repo, or ~/m3-skill/skills/m3-expressive globally.
  2. Add the pointer block to whatever instruction file that agent loads.

Some runtimes are converging on a shared ~/.agents/skills/ location. If yours does, one symlink covers all of them at once:

mkdir -p ~/.agents/skills
ln -s ~/m3-skill/skills/m3-expressive ~/.agents/skills/m3-expressive

The pointer block

Paste this into AGENTS.md, GEMINI.md, .github/copilot-instructions.md, CLAUDE.md, or your agent's equivalent. Fix the path to match where you put the folder:

## Material Design 3 / M3 Expressive

The M3 spec lives at `.agent-skills/m3-expressive/`.

Before writing or reviewing any Material Design UI (components, dp values, corner radii,
motion springs, type styles, color roles, adaptive layouts), read
`.agent-skills/m3-expressive/SKILL.md` and follow its "Where to look" table into the
specific reference file.

Never state a number, token name, or component name from memory. Look it up:
- exact values (type scale, radii, springs, elevation) -> `references/tokens.md`
- per-component dp geometry -> `references/component-tokens.md`
- component behavior, variants, do/don'ts -> `references/components/*.md`
- platform API availability -> `references/platforms.md`

If a value genuinely isn't in M3, say so and label it "my design decision (not in M3)"
rather than presenting it as spec.

That block is the whole trick. It transplants the source contract into agents that don't auto-discover skills, which is why this works the same everywhere.

Slim install (text-only)

The 495 MB of images is the only heavy part. Install without them, and pull them down later if you ever want them:

rsync -a --exclude visuals/ /path/to/m3-skill/skills/m3-expressive/ ~/.claude/skills/m3-expressive/

# regenerate whenever you want them (~5 min, 2,587 files)
cd ~/.claude/skills/m3-expressive && node scripts/refresh-m3.js images visuals

Cloning this repo gets you the images already, so it works offline with no extra step. If you're vendoring the skill into your own repo and want it light, exclude them. They rebuild from INDEX.tsv plus the refresh script:

skills/m3-expressive/visuals/*
!skills/m3-expressive/visuals/INDEX.tsv

Verify it loaded

Restart your agent, since skills are discovered at startup, then ask something only the skill can answer:

What are the expressive fast spatial spring values, and what corner radius should a child inside a 48dp-radius card with 16dp padding use?

Correct: damping 0.6 / stiffness 800, and 32dp (inner = outer − padding). Anything else and the skill isn't being read. Check that the folder contains SKILL.md at its top level, and that your pointer path is right.

Using it

Claude Code loads it automatically whenever a request touches Material Design. The skill's description triggers on M3, M3 Expressive, Material You, Material components, motion springs, shape morphing, emphasized typography, color roles, adaptive layout, and Jetpack Compose / MDC-Android / Flutter / web Material UI. You can also invoke it by name:

/m3-expressive

It's built for three kinds of work:

  • Designing. "Design a now-playing screen with M3 Expressive." You get a spec with real token values, and every unpublished value labelled as a decision rather than smuggled in as spec.
  • Implementing. "Build this as a Compose component." references/platforms.md gets checked first: availability is uneven, and M3 Expressive APIs are experimental until Compose 1.5.0.
  • Reviewing. "Check this screen against M3." The common-mistakes table and the per-component do/don't rules exist for exactly this pass.

Keeping it current

cd ~/.claude/skills/m3-expressive

node scripts/refresh-m3.js pages /tmp/m3-pages    # guideline prose to markdown
node scripts/refresh-m3.js images visuals         # reference images + caption index
node scripts/refresh-component-tokens.js          # per-component dp, rewrites the reference in place

refresh-component-tokens.js is byte-reproducible and writes over its reference directly. The other two write to a directory you name, so diff before folding changes in, since the references carry hand-written organization on top of the raw output. Requires Node.js; nothing else here does.

On accuracy. Design guidance, placement rules, and do/don'ts come from the Material guidelines. The md.comp.* geometry in component-tokens.md, plus the type scale, spring, shape, and elevation values, comes from the generated androidx.compose.material3.tokens sources, and each group carries the generator version it was taken from. The two are kept distinct on purpose, so the skill can attribute correctly. Known gaps are recorded as ## Gaps sections rather than filled with plausible values. Captured July 2026.

FAQ

What an agent skill is

A folder with a SKILL.md at its root, carrying YAML frontmatter with a name and a description. The agent reads only the description until something in your request matches it, then loads the body and, from there, whichever reference files it needs. It's why 800 KB of specification costs almost no context until the moment it's relevant.

Does it work with models other than Claude?

Yes. SKILL.md and the references are plain markdown with no Claude-specific syntax. Claude Code discovers the folder automatically; every other agent needs the pointer block, which takes about thirty seconds.

Do I need the 495 MB of images?

No. Every number, rule, and token lives in the markdown. The images are for reading measurement diagrams and canonical screens, useful when a spec is ambiguous and optional otherwise. See slim install.

Is M3 Expressive a new version of Material?

No. It's an evolution of Material 3, not "M4", and M3 isn't deprecated. It adds components, updated tokens, and design tactics. SKILL.md opens with this because getting it wrong colors every downstream decision.

Does it cover Compose, Flutter, and web equally?

It covers the design system for all of them, and is explicit that platform availability is uneven. references/platforms.md maps what's actually shipped where. Compose M3 Expressive APIs are experimental until Compose 1.5.0; MDC-Android and Material Web are in maintenance mode.

Will it override my own design system?

No. It supplies M3 values when you ask for M3. When you're working against your own tokens, it's the component behavior, sibling-choice rules, and do/don'ts that carry over.

Contributing

Corrections to values, gaps worth filling, and install recipes for agents not covered here are all welcome. Open an issue or a PR. If you're correcting a number, cite where the real one lives so it can be verified.

License

MIT for this repository's original work: the refresh scripts, the skill structure, and the authored organization of the references. See LICENSE.

Everything else keeps its own license, and NOTICE.md records which is which:

  • Material Design guidelines (the design guidance in references/) are © Google LLC, used under CC BY 4.0 with attribution
  • AndroidX token values (component-tokens.md) are Apache License 2.0, © The Android Open Source Project; values extracted and reformatted, none altered
  • Reference images (visuals/) are © Google LLC, included unmodified for reference, and optional. Exclude them if you'd rather not redistribute them.

Material Design, Material You, Android, and Jetpack Compose are trademarks of Google LLC. This project is not affiliated with, sponsored by, or endorsed by Google.