Elements

Elements · Primitives

Model logos

Inline SVG marks for OpenAI, Anthropic, and Google model providers.

fig. 01

Installation

npx shadcn@latest add "@assistant-ui/logos"
First time? Set up a runtime

Runtime components read their state from an assistant-ui runtime. Add one to an existing project:

npx assistant-ui@latest init

Then wrap your app in a runtime provider:

import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";

export default function App() {
  const runtime = useChatRuntime({
    transport: new AssistantChatTransport({ api: "/api/chat" }),
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      {/* your components */}
    </AssistantRuntimeProvider>
  );
}

The installation guide covers new projects, templates, and API routes.

ClaudeLogo, OpenAILogo, and GeminiLogo are inline SVG marks for the three model providers, sized and colored like any other icon. With a runtime you typically hand one to a model list as its icon; standalone you drop it wherever you'd show a provider mark.

Getting started

ModelSelector's own ModelOption type carries an optional icon: ReactNode, rendered next to the model's name in both the trigger and the list. assistant-ui doesn't know which mark belongs to which provider, that mapping is yours to set when you build the option list.

Attach a logo to each model option

components/assistant-ui/elements/model-catalog.ts
import { ClaudeLogo, OpenAILogo, GeminiLogo } from "@/components/assistant-ui/elements/logos";
import type { ModelOption } from "@/components/assistant-ui/elements/model-selector";

export const models: ModelOption[] = [
  { id: "claude-sonnet-5", name: "Sonnet 5", icon: <ClaudeLogo className="size-4" /> },
  { id: "gpt-5.6-luna", name: "GPT-5.6", icon: <OpenAILogo className="size-4" /> },
  { id: "gemini-3-pro", name: "Gemini 3 Pro", icon: <GeminiLogo className="size-4" /> },
];

Pass models to ModelSelectorRoot, or the runtime-connected ModelSelector kit component, the way Model selector documents; the icon shows up for free once it's on the option.

Examples

Recoloring

OpenAILogo fills with currentColor, so it follows a text color class like any other icon:

<OpenAILogo className="size-5 text-foreground/60" />

ClaudeLogo and GeminiLogo carry their own fixed brand color, a flat orange fill and a left-to-right gradient, so a text color class has no effect on either.

Every prop svg takes, still works

LogoProps is exactly ComponentProps<"svg">, so width, height, aria-hidden, and any other native svg attribute pass straight through, each overriding this file's own defaults (aria-hidden="true", and for OpenAI and Gemini, fill).

<ClaudeLogo width={20} height={20} aria-hidden={false} role="img" />

API reference

ModelOption

FieldTypeDescription
iconReactNodeRendered next to the model's name by ModelSelector's trigger and list. Any of these three logos fits; nothing computes this mapping for you.

There's no dedicated selector: this is a field you set on the array you already pass to ModelSelectorRoot. See Model selector for the rest of that shape.