Geistcn Icons & Logos

Icons and logos of the Geist design system

What's Geistcn Assets?

The @vercel/geistcn-assets package includes all icons and logos for internal and customer-facing apps. It can be used independently of the geistcn (or geist) package.

  1. packages/geistcn-assets:

Package installation

To install @vercel/geistcn-assets in your project in front, run:

# from root
pnpm --filter <your-app-name> add @vercel/geistcn-assets --workspace
# For example, if adding to geist-docs:
pnpm --filter geist-docs add @vercel/geistcn-assets --workspace

To install @geistcn-assets outside of front as a private npm package, run:

pnpm i @vercel/geistcn-assets

Usage

When consuming @vercel/geistcn-assets, you’ll need to choose from two main strategies:

  • Named Imports, for the simplest and most performant setup.
  • Dynamic Lookup (RSC-only), for cases where assets need to be loaded dynamically (e.g., by a CMS)

The examples below outline both approaches so you can choose the strategy that best fits your workflow.

Named Imports (Recommended)

Import Geistcn assets as named components for a simple and performant experience.

// Logos (rendered as next/image)
import { LogoVercel } from '@vercel/geistcn-assets/logos';
// Default Icons (rendered as inline SVG)
import { IconUser } from '@vercel/geistcn-assets/icons';
// Logo Icons (rendered as next/image)
import { IconLogoVercel } from '@vercel/geistcn-assets/icons';
// Or import directly from named paths (maximum tree-shaking)
import { LogoVercel } from '@vercel/geistcn-assets/logos/logo-vercel';
import { IconWarning } from '@vercel/geistcn-assets/icons/icon-warning';
import { IconLogoVercel } from '@vercel/geistcn-assets/icons/icon-logo-vercel';

This is the preferred way to consume logos and icons - All components are tree-shakable and compatible with Server and Client Components. You get consistent behavior and minimal bundle size.



Dynamic Name-Based Lookups (Server Components Only)

For CMS-driven or dynamic asset selection, use the server component wrappers:

import { Logo, Icon, IconLogo } from '@vercel/geistcn-assets/server';
import type {
LogoName,
IconName,
IconLogoName,
} from '@vercel/geistcn-assets/types';
export default async function Page() {
const logoName: LogoName = await cms.getField('logo'); // "vercel"
const iconName: IconName = await cms.getField('icon'); // "warning"
const logoIconName: IconLogoName = await cms.getField('logoIcon'); // "logo-github"
return (
<>
<Logo name={logoName} height={100} />
<Icon name={iconName} size={24} />
<IconLogo name={logoIconName} size={24} />
</>
);
}

Important Notes:

  • Server Components Only - Cannot be used in Client Components (dynamic imports)
  • Bundle Impact - Each component includes all assets in its category for server-side lookup
  • Atomic Imports - For smaller server bundles, use: @vercel/geistcn-assets/server/logo, /server/icon, or /server/icon-logo
  • Best Practice - For static/known assets, prefer named imports for optimal performance

Find more technical details in the README of the package.

Add new icons or logos

0. Prerequisites

To add new icons or logos, the following prerequisites have to be met:

  • Edit permission for our Figma workspace, request access in #design slack channel.
  • Figma personal access token, find detailed steps to create one here.
  • Add your token as env variable FIGMA_TOKEN to your .env.local in `packages/geistcn-assets. See command below:
# from root
echo 'FIGMA_TOKEN="YOUR_PERSONAL_TOKEN"' > packages/geistcn-assets/.env.local
# or from packages/geistcn-assets
echo 'FIGMA_TOKEN="YOUR_PERSONAL_TOKEN"' > .env.local

1. Add assets to Figma

Add assets in one of the following workspaces. E.g. if your logo starts with "B", put it in the alphabetically correct folder:



Guidance for adding icons

If you add an icon, the ideal format, if possible, is to provision the icon via one path (e.g. union select). This eliminates unnecessary SVG elements not neeed for the React component and avoids incorrect renders (see example in video below).

See video below for more guidance:


Example for workflow icon

(Raw) code for workflow icon before one path transformation:

<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_12542_4117)">
<mask
id="mask0_12542_4117"
style="mask-type:luminance"
maskUnits="userSpaceOnUse"
x="0"
y="0"
width="16"
height="16"
>
<path
d="M16 0H0V16H16V0Z"
fill="white"
style="fill:white;fill-opacity:1;"
/>
</mask>
<g mask="url(#mask0_12542_4117)">
<path
d="M3.55933 11.3813L5.75 6.99988M7 13.5H11.4999M9.06883 4.45959L11.5456 9.00052"
stroke="#666666"
style="stroke:#666666;stroke:color(display-p3 0.4000 0.4000 0.4000);stroke-opacity:1;"
stroke-width="1.5"
/>
<path
d="M9 1H7C6.44772 1 6 1.44772 6 2V4C6 4.55228 6.44772 5 7 5H8H9C9.55228 5 10 4.55228 10 4V3V2C10 1.44772 9.55228 1 9 1Z"
stroke="#666666"
style="stroke:#666666;stroke:color(display-p3 0.4000 0.4000 0.4000);stroke-opacity:1;"
stroke-width="1.5"
/>
<path
d="M4 11H2C1.44772 11 1 11.4477 1 12V14C1 14.5523 1.44772 15 2 15H3H4C4.55228 15 5 14.5523 5 14V13V12C5 11.4477 4.55228 11 4 11Z"
stroke="#666666"
style="stroke:#666666;stroke:color(display-p3 0.4000 0.4000 0.4000);stroke-opacity:1;"
stroke-width="1.5"
/>
<path
d="M14 11H12C11.4477 11 11 11.4477 11 12V14C11 14.5523 11.4477 15 12 15H13H14C14.5523 15 15 14.5523 15 14V13V12C15 11.4477 14.5523 11 14 11Z"
stroke="#666666"
style="stroke:#666666;stroke:color(display-p3 0.4000 0.4000 0.4000);stroke-opacity:1;"
stroke-width="1.5"
/>
</g>
</g>
<defs>
<clipPath id="clip0_12542_4117">
<rect
width="16"
height="16"
fill="white"
style="fill:white;fill-opacity:1;"
/>
</clipPath>
</defs>
</svg>

(Raw) Code for workflow icon after one path transformation:

<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5.75 7L6.4209 7.33594L4.85254 10.4717C5.38789 10.771 5.75 11.3431 5.75 12V14C5.75 14.9665 4.96648 15.75 4 15.75H2C1.03352 15.75 0.25 14.9665 0.25 14V12C0.25 11.0335 1.03352 10.25 2 10.25H3.28711L5.0791 6.66504L5.75 7ZM14 10.25C14.9665 10.25 15.75 11.0335 15.75 12V14C15.75 14.9665 14.9665 15.75 14 15.75H12C11.1185 15.75 10.3909 15.098 10.2695 14.25H7V12.75H10.25V12C10.25 11.0335 11.0335 10.25 12 10.25H14ZM2 11.75C1.86192 11.75 1.75 11.8619 1.75 12V14C1.75 14.1381 1.86192 14.25 2 14.25H4C4.13808 14.25 4.25 14.1381 4.25 14V12C4.25 11.8619 4.13808 11.75 4 11.75H2ZM12 11.75C11.8619 11.75 11.75 11.8619 11.75 12V14C11.75 14.1381 11.8619 14.25 12 14.25H14C14.1381 14.25 14.25 14.1381 14.25 14V12C14.25 11.8619 14.1381 11.75 14 11.75H12ZM9 0.25C9.96649 0.25 10.75 1.03351 10.75 2V4C10.75 4.44642 10.5808 4.85197 10.3057 5.16113L12.2041 8.6416L10.8877 9.36035L8.91895 5.75H7C6.03351 5.75 5.25 4.96649 5.25 4V2C5.25 1.03351 6.03351 0.25 7 0.25H9ZM7 1.75C6.86193 1.75 6.75 1.86193 6.75 2V4C6.75 4.13807 6.86193 4.25 7 4.25H9C9.13807 4.25 9.25 4.13807 9.25 4V2C9.25 1.86193 9.13807 1.75 9 1.75H7Z"
fill="#666666"
style="fill:#666666;fill:color(display-p3 0.4000 0.4000 0.4000);fill-opacity:1;"
/>
</svg>

Guidance for adding logos

If you add a logo, the following requirements have to be met:

  • Naming convention:

    • [Company]: if logo (symbol) only, e.g. Vercel
    • [Company] Logotype: if logo with wordmark, e.g. Vercel Logotype
  • Variants:

    • Light version
    • Dark version

See video below for more guidance.

2. Fetch and generate new assets from Figma

Once the assets are put into the right format in Figma, run the following commands in the package.

For icons:

# from root
pnpm --filter geistcn-assets icons:generate

For logos:

# from root
pnpm --filter geistcn-assets logos:generate

This process also includes automated checks to ensure assets follow the required format. The CLI will display errors and provide guidance if needed.

3. Publish your changes as a new PR

Once assets have been created, you can simply create a PR. The new assets will be available in the internal package immediately.

For the npm release to happen, run pnpm changeset to create a changeset PR to trigger a release:

# from root
pnpm changeset

This command will ask you whether you want to create a major bump, minor bump, or patch release. Always select a patch release (press enter until this option is shown).

Provide the summary and the changeset PR is ready to be created.