Icons
Icons make actions and navigation across Supabase easier.
Principles
- Paired: Icons should accompany text, as they aren’t often obvious enough on their own.
- Clear: Icons should be legible at small sizes and unembellished. Let the text do the heavy lifting.
- Consistent: Use the same icons for similar actions throughout Supabase. This makes the app easier to use.
Tints
Use classes just like you would for text to tint icons. For example:
<BucketAdd className="text-foreground-muted" />
Just like text, don’t tint icons with text-destructive
for destructive actions. There should be a confirmation dialog right after which can handle the destructive styling.
UI icons
We rely on Lucide for any standard UI icon needs.
Custom icons
Create and use custom icons when Lucide doesn’t have the icon you need. Tap on an icon below to copy the JSX, SVG, or import path.
Usage
import { ReplaceCode, InsertCode, BucketAdd } from 'icons'
function app() {
return (
<>
<ReplaceCode className="text-light" strokeWidth={1} size={16} />
<InsertCode className="text-light" strokeWidth={1} size={16} />
<BucketAdd size={24} className="text-foreground-muted" />
</>
)
}
Default props: All icons have strokeWidth={2}
and size={24}
by default. Override these props as needed for your use case.
Adding new custom icons
To add a new custom icon to the Supabase icon library:
-
Create SVG file: Add your SVG file to
packages/icons/src/raw-icons/
with a kebab-case name (e.g.,my-new-icon.svg
). Make sure it has follows these exact requirements:- Exported at 24x24px with
viewBox="0 0 24 24"
- Uses
stroke="currentColor"
for strokes (no hardcoded colors) - Uses
fill="none"
for fills (no hardcoded colors) - Icon content is optically centered and around 18x18px within the 24x24 frame
- Any unnecessary elements like
<clipPath>
,<defs>
, and<g>
wrappers have been removed - SVG structure is as simple as possible with just
<path>
elements
- Exported at 24x24px with
Just leave attributes like stroke-width
as they are. The conversion to camel-case (for React compatibility) is handled by the below build process.
-
Build the component: Run
npm run build:icons
from inside thepackages/icons
directory -
Use the icon: Import and use like any other icon:
import { MyNewIcon } from 'icons' ;<MyNewIcon size={16} strokeWidth={1} />
SVG design guidelines
Icons should:
- Always be exported 24x24px
- Have an icon inside that frame that’s around 18x18px(ish)
- Use clean, simple paths without unnecessary wrapper elements
Bad example ❌
Notice the hardcoded colors, unnecessary backgrounds, and complex structure:
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" fill="#1E1E1E" /> <!-- ❌ Hardcoded color -->
<path d="M..." fill="#404040" /> <!-- ❌ Hardcoded color -->
<path d="M..." stroke="#EDEDED" stroke-linecap="round" /> <!-- ❌ Hardcoded color -->
</svg>
Good example ✅
Clean structure with currentColor
and proper attributes:
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M6 7C6 4.2 8.2 2 11 2H13C15.8 2 18 4.2 18 7" />
<path d="M4.5 11H19.5" />
<path d="M6 11L6.8 20C6.9 21.1 7.9 22 9 22H12" />
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M6 7C6 4.2 8.2 2 11 2H13C15.8 2 18 4.2 18 7" />
<path d="M4.5 11H19.5" />
<path d="M6 11L6.8 20C6.9 21.1 7.9 22 9 22H12" />
</svg>
Troubleshooting
If your SVG specifies stroke-width
attributes, they will override the component's strokeWidth
prop. Remove stroke attributes from individual paths to let the component control them.