Skip to main content
RapidDev - Software Development Agency
retool-tutorial

How to Use Custom Icons in Retool

Retool includes 3,400+ icons from the Ant Design and Bold icon sets, selectable via an icon picker in any Button, Icon, Stat, or Menu component. Reference icons programmatically with IconKey strings (e.g., 'bold/arrow-right'). For custom SVGs not in the library, embed them via the Image component using a data:image/svg+xml URL, or use an HTML component to load an external icon library like Heroicons or Font Awesome.

What you'll learn

  • How to browse and apply Retool's 3,400+ built-in icons using the icon picker
  • How to reference icons programmatically using IconKey strings like 'bold/arrow-right'
  • How to make icons dynamic using {{ }} expressions bound to query or state data
  • How to use custom SVG icons via the Image component with inline SVG data URLs
  • How to embed fully custom icon sets using the HTML component
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate8 min read15-20 minRetool Cloud and Self-hostedLast updated March 2026RapidDev Engineering Team
TL;DR

Retool includes 3,400+ icons from the Ant Design and Bold icon sets, selectable via an icon picker in any Button, Icon, Stat, or Menu component. Reference icons programmatically with IconKey strings (e.g., 'bold/arrow-right'). For custom SVGs not in the library, embed them via the Image component using a data:image/svg+xml URL, or use an HTML component to load an external icon library like Heroicons or Font Awesome.

Quick facts about this guide
FactValue
ToolRetool
DifficultyIntermediate
Time required15-20 min
CompatibilityRetool Cloud and Self-hosted
Last updatedMarch 2026

Icons in Retool: Built-in, Dynamic, and Custom

Retool ships with over 3,400 icons from the Ant Design and Bold icon libraries. Any component that supports an icon property (Button, Icon, Stat, List, Menu, Navigation) has a built-in icon picker in the Inspector — click the icon field, search by name, and select. Retool renders these icons as SVGs with optimal performance.

For dynamic icon selection (showing different icons based on data — e.g., green checkmark for active, red X for inactive), you reference icons by their IconKey string in a `{{ }}` expression. The IconKey format is 'library/icon-name', such as 'bold/check-circle' or 'ant-design/warning-outlined'.

For custom icons not in Retool's library — your own brand icons, specific UI icons from other libraries — you have two approaches: embed SVGs directly in the Image component using data URLs, or use an HTML component to load an entire icon library via CDN.

Prerequisites

  • A Retool app with at least one Button, Icon, or Stat component
  • Editor or Admin access to the Retool app
  • Custom SVG files if you plan to use custom icons (optional)
  • Basic understanding of Retool's Inspector panel

Step-by-step guide

1

Browse and apply a built-in icon

Select any component that supports icons (Button, Icon, Stat, List, etc.). In the Inspector panel, find the Icon or Icon key field. Click it to open Retool's icon picker. In the search box, type an icon name (e.g., 'arrow', 'check', 'warning', 'user'). The picker shows results from both the Bold and Ant Design icon sets. Click any icon to apply it. The icon appears on the component immediately. For Button components, the icon can be placed Left or Right of the button label — configure this in the Inspector's Icon Position field.

Expected result: The selected icon appears on the component in the editor canvas.

2

Reference icons with IconKey strings

Each icon in Retool's library has an IconKey string in the format 'library/icon-name'. When you hover an icon in the picker, the tooltip shows its key. Common examples: - 'bold/check-circle' — green checkmark circle - 'bold/close-circle' — red X circle - 'bold/warning' — warning triangle - 'ant-design/rocket-outlined' — rocket icon - 'ant-design/database-outlined' — database icon Type or paste the IconKey string directly into the Inspector's Icon key field instead of using the picker. This enables dynamic icon selection via `{{ }}` expressions.

typescript
1// Example: IconKey field value for an Icon component
2// In Inspector → Icon key field:
3'bold/check-circle'
4
5// To dynamically select icon based on status:
6{{ table1.selectedRow.status === 'active' ? 'bold/check-circle' : 'bold/close-circle' }}
7
8// To show warning icon if value exceeds threshold:
9{{ numberInput1.value > 100 ? 'bold/warning' : 'bold/check' }}

Expected result: The Icon component displays the specified icon, or changes icon dynamically based on the `{{ }}` expression.

3

Build a dynamic icon column in a Table

Tables support icon columns via custom columns. Select the Table component → Inspector → Columns → + Add column. Set the Column type to Icon. In the Icon key field, enter a `{{ }}` expression referencing `{{ currentRow.fieldName }}`. For example, if your data has a status field with values 'active', 'inactive', 'pending', map them to icons:

typescript
1// Table custom column → Icon type → Icon key field value:
2{{
3 currentRow.status === 'active' ? 'bold/check-circle' :
4 currentRow.status === 'pending' ? 'bold/clock-circle' :
5 'bold/close-circle'
6}}
7
8// To also set icon color dynamically (in the Color field):
9{{
10 currentRow.status === 'active' ? '#10B981' :
11 currentRow.status === 'pending' ? '#F59E0B' :
12 '#EF4444'
13}}

Expected result: Each table row shows a different icon in the status column based on the row's status field value.

4

Add a custom SVG icon via the Image component

For icons not in Retool's built-in library (brand logos, custom UI icons, specialized symbols), use the Image component with an inline SVG data URL. First, get your SVG code — either from a design tool export or a site like heroicons.com. Then create an Image component and set its Image source to a data URL: Format: `data:image/svg+xml;base64,[base64-encoded-svg]` Or use URL-encoded SVG directly:

typescript
1// Option 1: URL-encoded SVG (no base64 needed for simple SVGs)
2// In Image component → Source field:
3data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237C3AED' stroke-width='2'%3E%3Cpath d='M12 2L2 7l10 5 10-5-10-5z'/%3E%3Cpath d='M2 17l10 5 10-5'/%3E%3Cpath d='M2 12l10 5 10-5'/%3E%3C/svg%3E
4
5// Option 2: Base64-encoded SVG via JS Query
6// JS Query to convert SVG string to base64 data URL:
7const svgString = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
8 <path fill="#7C3AED" d="M12 2L2 7l10 5 10-5-10-5z"/>
9</svg>`;
10const encoded = btoa(unescape(encodeURIComponent(svgString)));
11return `data:image/svg+xml;base64,${encoded}`;

Expected result: The Image component displays your custom SVG at the size you configured.

5

Load a full custom icon library via HTML component

For apps requiring many custom icons (e.g., loading Heroicons, Phosphor, or Font Awesome), use an HTML component to load the icon library via CDN and render icons using their native syntax. Add an HTML component with custom HTML/CSS/JS. For Heroicons (SVG-based, no JS library needed):

typescript
1<!-- HTML component content for Font Awesome icons -->
2<!DOCTYPE html>
3<html>
4<head>
5 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
6 <style>
7 body { margin: 0; display: flex; align-items: center; gap: 8px; }
8 .fa-icon { font-size: {{ self.model.size || 24 }}px; color: {{ self.model.color || '#374151' }}; }
9 </style>
10</head>
11<body>
12 <i class="fa-solid {{ self.model.iconClass }}" aria-label="{{ self.model.label }}"></i>
13</body>
14</html>

Expected result: The HTML component renders the Font Awesome or Heroicons icon, controlled by the model data from the Inspector.

6

Use Preloaded CSS to load an icon font globally

To make an icon font available across all apps without adding HTML components everywhere, add the CDN @import to Settings → Preloaded CSS/JS. The icon font loads once for the entire Retool organization. Then reference icons in any Text component using HTML content mode or in CSS Class Name styled text.

typescript
1/* Add to Settings → Preloaded CSS */
2@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css');
3
4/* Now use Font Awesome icons in Text components with HTML mode enabled */
5/* Text component content (with HTML mode on):
6<i class="fa-solid fa-rocket" style="color: #7C3AED; font-size: 20px;"></i>
7*/

Expected result: Font Awesome icons are available in all apps via <i class="fa-solid ..."> HTML in Text components with HTML mode enabled.

Complete working example

JS Query: generateSvgDataUrl
1// JS Query to convert a custom SVG to a data URL for the Image component
2// Usage: set Image component Source to {{ generateSvgDataUrl.data }}
3
4const svgString = `
5<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
6 stroke="#7C3AED" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
7 <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
8</svg>
9`;
10
11// URL-encode the SVG for use as a data URL
12const encodedSvg = encodeURIComponent(svgString.trim());
13const dataUrl = `data:image/svg+xml,${encodedSvg}`;
14
15return dataUrl;
16
17// To use dynamic colors based on component state:
18// const color = statusVar.value === 'active' ? '#10B981' : '#EF4444';
19// const svgString = `<svg ... stroke="${color}" ...>...</svg>`;

Common mistakes

Why it's a problem: Typing an IconKey string incorrectly (wrong format or typo) and seeing a blank icon

How to avoid: Always copy IconKey strings from the icon picker tooltip rather than typing them. The correct format is exactly 'library/icon-name' — e.g., 'bold/check-circle', not 'bold-check-circle' or 'checkCircle'.

Why it's a problem: Using an Image component for simple icons that exist in Retool's built-in library

How to avoid: Check Retool's icon picker first — 3,400+ icons are already available as optimized SVGs. Only use Image or HTML components for icons genuinely missing from the built-in set.

Why it's a problem: Embedding large unoptimized SVG data URLs in Image components, causing performance issues

How to avoid: Optimize SVGs before embedding: remove metadata, simplify paths, and reduce decimal precision. Use tools like SVGO. Alternatively, host SVGs in Retool Storage or an S3 bucket and use a URL instead.

Best practices

  • Hover icons in Retool's built-in picker to see their IconKey string before writing dynamic expressions
  • Use the 'bold/' prefix icons for filled styles and 'ant-design/*-outlined' for line/outline styles
  • For dynamic icons in tables, use the custom column Icon type rather than embedding Image components in each row
  • Prefer Retool's built-in icon library over external CDN fonts — built-in icons are SVGs with no network requests
  • For custom SVGs, optimize them first (remove unnecessary attributes, reduce path complexity) before embedding as data URLs
  • Load icon CDN fonts in Preloaded CSS (org-wide) rather than per-app to avoid redundant network requests
  • Use aria-label on icon-only buttons for accessibility — Retool's Icon component has a Tooltip field you can use as a label

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I'm building a Retool dashboard and need to show status icons in a table column. Each row has a 'status' field with values 'active', 'inactive', or 'pending'. I want to show a green check circle for active, a red X circle for inactive, and a yellow clock for pending. Explain how to add an Icon-type custom column in a Retool Table, and write the IconKey expression using {{ currentRow.status }} with the correct Retool icon key strings.

Retool Prompt

Add a custom column to the table1 Table component with type Icon. Use this expression in the Icon key field: active → 'bold/check-circle', pending → 'bold/clock-circle', inactive → 'bold/close-circle'. Also set the Color field dynamically: green for active, yellow for pending, red for inactive.

Frequently asked questions

How do I find the IconKey string for a Retool built-in icon?

Open the icon picker in any component's Inspector (click the icon field), search for the icon you want, and hover over it. The tooltip shows the full IconKey string in 'library/icon-name' format. Click to apply it, or copy the string for use in a {{ }} dynamic expression.

Can I use Heroicons or Lucide icons in Retool?

Yes, but they require an HTML component or Preloaded CSS/JS approach. For Heroicons, use an HTML component and embed SVG code directly in the HTML. For Lucide (JavaScript-based), add the CDN script in Preloaded JS and use an HTML component to initialize and render icons. Retool's built-in icons cover most use cases, so check those first.

Can the same icon change color dynamically based on data in Retool?

Yes. In components like Table custom columns and Stat components, Retool provides separate Color or Icon color fields in addition to the Icon key field. Both support {{ }} expressions, so you can write {{ currentRow.value > 0 ? '#10B981' : '#EF4444' }} to switch between green and red. For standalone Icon components, use the Color property in the Inspector.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Learning is great. Shipping is faster with help.

Our engineers have built 600+ apps on Retool and the tools around it. If your project needs to be live sooner than your learning curve allows — book a free consultation.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.