MD3
Expressive
MATERIAL DESIGN 3 EXPRESSIVE

Using with AI Studio

Configure Google AI Studio with durable system instructions and current best practices for building React and Next.js applications with Bug On MD3 Expressive.

Google AI Studio is a fast environment for prototyping with Gemini. In AI Studio, select the newest stable Gemini model available in the model picker rather than baking a model version into this documentation or into prompts. This keeps experiments on the current supported model while avoiding stale references.

Model-selection Policy

  • Default recommendation: Prefer the newest stable Gemini model for new work.
  • Pinning endpoints: Use a model's exact, stable endpoint only when production reproducibility, evaluation baselines, pricing control, or capability compatibility requires pinning.
  • Preview models: Avoid preview and experimental models for production unless their required capability is unavailable in a stable model.

📋 System Instructions for AI Studio

In Google AI Studio, choose the newest stable Gemini model shown in the model picker, then paste the following into System Instructions:

text
You are an expert frontend engineer building React applications with the @bug-on/m3-expressive component library, Material Design 3 Expressive, Tailwind CSS v4, and Motion for React.

MANDATORY RULES

1. Reference documentation first
Before writing or changing code, consult the library documentation below. Treat it as the source of truth for public APIs, supported imports, prop signatures, accessibility requirements, installation, and migration notes.
- Full reference: https://raw.githubusercontent.com/nguyentruongton/bug-on-m3-expressive/main/llms-full.txt
- Quick overview: https://raw.githubusercontent.com/nguyentruongton/bug-on-m3-expressive/main/llms.txt
- Package-hosted reference: https://unpkg.com/@bug-on/m3-expressive/llms-full.txt

If the documentation is unavailable, do not invent component names, import paths, or prop signatures. State the limitation and use only APIs already established in the project.

2. Use documented subpath imports
Do not import components from @bug-on/m3-expressive at the package root in production code. Use the documented subpath for each component:
- Buttons and FABs: @bug-on/m3-expressive/buttons
- Form controls and pickers: @bug-on/m3-expressive/forms, @bug-on/m3-expressive/pickers
- Navigation and bars: @bug-on/m3-expressive/navigation
- Overlays and dialogs: @bug-on/m3-expressive/overlays
- Layout and cards: @bug-on/m3-expressive/layout
- Feedback and progress: @bug-on/m3-expressive/feedback
- Core and providers: @bug-on/m3-expressive/core

3. Tailwind CSS v4 only
This library targets Tailwind CSS v4. Use the CSS-first v4 workflow; do not create a tailwind.config.js unless the existing project explicitly requires one. The root stylesheet must include:
@import "tailwindcss";
@import "@bug-on/m3-expressive/index.css";

4. Animation
Use Motion for React from the motion package, importing from motion/react. Do not add the legacy framer-motion package to new projects unless the repository already depends on it and migration is out of scope.

5. Known API requirements
- TextField onChange receives a raw string: (value: string) => void. It does not receive a React ChangeEvent.
- Select onChange receives: (value: string, option?: SelectOption) => void.
- ProgressIndicator requires an aria-label.
- For an indeterminate ProgressIndicator, omit value; do not use max.
- Prefer semantic MD3 utilities such as bg-m3-primary and text-m3-on-surface. Do not hard-code hex colours when a semantic token exists.

6. Code quality and accessibility
- Preserve TypeScript safety and existing project conventions.
- Use semantic HTML, accessible names, keyboard support, and correct ARIA only when necessary.
- Respect React Server Components and client boundaries in Next.js. Add "use client" only to components that need browser APIs, state, effects, or event handlers.
- Return complete, minimal changes. Explain any required manual setup step.

⚡ React with Vite

For a client-rendered React application, Vite is the recommended setup in this guide. The instructions below use Tailwind CSS v4's Vite plugin workflow.

1. Install dependencies

bash
# pnpm
pnpm add @bug-on/m3-expressive motion
pnpm add -D tailwindcss @tailwindcss/vite

# npm
npm install @bug-on/m3-expressive motion
npm install -D tailwindcss @tailwindcss/vite

2. Configure Vite

ts
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
});

3. Configure the stylesheet

css
/* src/index.css */
@import "tailwindcss";
@import "@bug-on/m3-expressive/index.css";

/* Optional typography */
@import "@bug-on/m3-expressive/typography.css";

4. Add the theme provider

tsx
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import { MD3ThemeProvider } from "@bug-on/m3-expressive/core";
import { Button } from "@bug-on/m3-expressive/buttons";
import "./index.css";

function App() {
  return (
    <MD3ThemeProvider>
      <main className="min-h-screen bg-m3-surface p-6 text-m3-on-surface">
        <h1 className="text-2xl font-semibold">React + MD3 Expressive</h1>
        <Button onClick={() => console.log("Pressed")}>Get started</Button>
      </main>
    </MD3ThemeProvider>
  );
}

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);

🚀 Next.js App Router

Next.js App Router uses React Server Components by default. Keep pages and components server-rendered; use "use client" only where interactivity, state, or browser-only APIs are required.

1. Install dependencies

bash
pnpm add @bug-on/m3-expressive motion
# or: npm install @bug-on/m3-expressive motion

2. Configure global stylesheet

Import global CSS once from the root layout:

css
/* app/globals.css */
@import "tailwindcss";
@import "@bug-on/m3-expressive/index.css";
@import "@bug-on/m3-expressive/typography.css";

3. Add client provider wrapper

Put interactive components and providers that depend on client-side React APIs behind a client boundary:

tsx
// app/providers.tsx
"use client";

import { MD3ThemeProvider } from "@bug-on/m3-expressive/core";

export function Providers({ children }: { children: React.ReactNode }) {
  return <MD3ThemeProvider>{children}</MD3ThemeProvider>;
}

4. Set up root layout

<Icon> configures Material Symbols automatically; render Providers inside app/layout.tsx:

tsx
// app/layout.tsx
import { Providers } from "./providers";
import "./globals.css";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

🔄 Keeping this Guide Current

  • Model selection: In AI Studio, choose the newest stable Gemini model shown by the product rather than copying an endpoint version from this page.
  • API integrations: Read the Gemini models guide before choosing an endpoint. *-latest aliases move over time and can point to stable, preview, or experimental releases.
  • Production pinning: Pin a stable model endpoint for production flows that need reproducible behaviour. Review the Gemini API changelog and deprecation notices before upgrades.
  • Library specification: Re-check the library's llms.txt and llms-full.txt whenever updating @bug-on/m3-expressive, Tailwind, React, or Motion.