0
# Custom Icon Creation
1
2
System for creating custom icon components from icon data, supporting Lucide Lab icons, custom SVG definitions, and creating new Lucide-style icon components.
3
4
## Capabilities
5
6
### Icon Component
7
8
The base `Icon` component renders SVG icons from icon node data, supporting custom icons and Lucide Lab integration.
9
10
```typescript { .api }
11
import type { SVGProps, ForwardRefExoticComponent, RefAttributes } from 'react';
12
13
type ElementAttributes = RefAttributes<SVGSVGElement> & Partial<SVGProps<SVGSVGElement>>;
14
15
/**
16
* Base icon component that renders SVG from IconNode data
17
* @param props - Icon props including iconNode and standard LucideProps
18
* @returns JSX.Element - Rendered SVG icon
19
*/
20
function Icon(props: IconComponentProps): JSX.Element;
21
22
interface IconComponentProps extends LucideProps {
23
/** Icon data structure defining SVG elements */
24
iconNode: IconNode;
25
/** Optional children to add to the SVG */
26
children?: React.ReactNode;
27
}
28
29
interface LucideProps extends ElementAttributes {
30
size?: string | number;
31
absoluteStrokeWidth?: boolean;
32
}
33
34
type IconNode = [elementName: SVGElementType, attrs: Record<string, string>][];
35
36
type SVGElementType =
37
| 'circle'
38
| 'ellipse'
39
| 'g'
40
| 'line'
41
| 'path'
42
| 'polygon'
43
| 'polyline'
44
| 'rect';
45
```
46
47
**Usage Examples:**
48
49
```typescript
50
import { Icon } from "lucide-react";
51
52
// Custom icon data
53
const customIconNode: IconNode = [
54
['path', { d: 'M12 2L2 7v10c0 5.55 3.84 10 9 10s9-4.45 9-10V7l-8-5z', key: 'custom1' }],
55
['path', { d: 'M12 8v8', key: 'custom2' }],
56
['path', { d: 'M8 12h8', key: 'custom3' }]
57
];
58
59
// Render custom icon
60
<Icon iconNode={customIconNode} size={32} color="blue" />
61
62
// With Lucide Lab icon
63
import { coconut } from '@lucide/lab';
64
<Icon iconNode={coconut} />
65
66
// With additional children
67
<Icon iconNode={customIconNode}>
68
<circle cx="12" cy="12" r="2" fill="red" />
69
</Icon>
70
```
71
72
### createLucideIcon Function
73
74
Factory function to create reusable icon components from icon data.
75
76
```typescript { .api }
77
/**
78
* Creates a reusable Lucide-style icon component from icon data
79
* @param iconName - Name for the icon (used for CSS classes and display name)
80
* @param iconNode - Icon data structure defining SVG elements
81
* @returns LucideIcon - Reusable React component with forwardRef
82
*/
83
function createLucideIcon(iconName: string, iconNode: IconNode): LucideIcon;
84
85
type LucideIcon = ForwardRefExoticComponent<
86
Omit<LucideProps, 'ref'> & RefAttributes<SVGSVGElement>
87
>;
88
```
89
90
**Usage Examples:**
91
92
```typescript
93
import { createLucideIcon } from "lucide-react";
94
95
// Define custom icon data
96
const heartIconNode: IconNode = [
97
['path', {
98
d: 'M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z',
99
key: 'heart1'
100
}]
101
];
102
103
// Create reusable component
104
const Heart = createLucideIcon('heart', heartIconNode);
105
106
// Use like any other Lucide icon
107
<Heart />
108
<Heart size={24} color="red" />
109
<Heart className="favorite-icon" />
110
```
111
112
### Icon Node Structure
113
114
The `IconNode` type defines how icon data is structured for rendering.
115
116
```typescript { .api }
117
/**
118
* Icon node structure representing SVG elements
119
* Each element is a tuple of [elementName, attributes]
120
*/
121
type IconNode = [elementName: SVGElementType, attrs: Record<string, string>][];
122
123
/**
124
* Supported SVG element types for icon definitions
125
*/
126
type SVGElementType =
127
| 'circle' // <circle cx="12" cy="12" r="5" />
128
| 'ellipse' // <ellipse cx="12" cy="12" rx="5" ry="3" />
129
| 'g' // <g transform="translate(2,2)">
130
| 'line' // <line x1="0" y1="0" x2="24" y2="24" />
131
| 'path' // <path d="M12 2L2 7v10..." />
132
| 'polygon' // <polygon points="12,2 22,7 22,17 12,22 2,17 2,7" />
133
| 'polyline' // <polyline points="12,2 22,7 22,17" />
134
| 'rect'; // <rect x="2" y="2" width="20" height="20" />
135
136
/**
137
* Element attributes are key-value pairs
138
* Common attributes: d, x, y, cx, cy, r, width, height, points, key
139
*/
140
type ElementAttributes = Record<string, string>;
141
```
142
143
**Usage Examples:**
144
145
```typescript
146
// Simple path icon
147
const simpleIcon: IconNode = [
148
['path', { d: 'M12 2v20', key: 'line1' }],
149
['path', { d: 'M2 12h20', key: 'line2' }]
150
];
151
152
// Complex icon with multiple elements
153
const complexIcon: IconNode = [
154
['rect', { x: '2', y: '2', width: '20', height: '20', rx: '5', key: 'bg' }],
155
['circle', { cx: '12', cy: '12', r: '3', key: 'center' }],
156
['path', { d: 'M12 1v6m0 10v6', key: 'vertical' }],
157
['path', { d: 'M1 12h6m10 0h6', key: 'horizontal' }]
158
];
159
160
// Group element for transformations
161
const groupIcon: IconNode = [
162
['g', { transform: 'translate(2,2) scale(0.8)', key: 'group' }],
163
['path', { d: 'M0 0h20v20H0z', key: 'square' }]
164
];
165
```
166
167
### Creating Icons from SVG
168
169
Convert existing SVG code to IconNode format for use with Lucide React.
170
171
```typescript { .api }
172
/**
173
* Converting SVG to IconNode:
174
* 1. Extract SVG elements (path, circle, etc.)
175
* 2. Convert to [elementName, attributes] tuples
176
* 3. Add unique 'key' attribute to each element
177
* 4. Use with Icon component or createLucideIcon
178
*/
179
```
180
181
**Usage Examples:**
182
183
```typescript
184
// Original SVG
185
/*
186
<svg viewBox="0 0 24 24">
187
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
188
</svg>
189
*/
190
191
// Converted to IconNode
192
const starIcon: IconNode = [
193
['path', {
194
d: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z',
195
key: 'star'
196
}]
197
];
198
199
// Create component
200
const Star = createLucideIcon('star', starIcon);
201
202
// Or use directly
203
<Icon iconNode={starIcon} />
204
```
205
206
### Icon Styling and Classes
207
208
Created icons automatically receive Lucide-style CSS classes and support all standard props.
209
210
```typescript { .api }
211
/**
212
* Created icons automatically receive CSS classes:
213
* - 'lucide' - Base class for all Lucide icons
214
* - 'lucide-{icon-name}' - Specific class for the icon
215
* - Additional classes from className prop
216
*/
217
```
218
219
**Usage Examples:**
220
221
```typescript
222
// Icon created with createLucideIcon gets automatic classes
223
const CustomIcon = createLucideIcon('my-custom-icon', iconNode);
224
225
// Results in classes: 'lucide lucide-my-custom-icon'
226
<CustomIcon />
227
228
// Additional classes
229
<CustomIcon className="my-extra-class" />
230
// Results in: 'lucide lucide-my-custom-icon my-extra-class'
231
232
// Direct Icon component also gets base class
233
<Icon iconNode={iconNode} className="custom-direct" />
234
// Results in: 'lucide custom-direct'
235
```
236
237
### Lucide Lab Integration
238
239
Use icons from Lucide Lab (experimental icons) with the Icon component.
240
241
```typescript { .api }
242
/**
243
* Lucide Lab provides experimental icons not in the main library
244
* Install: npm install @lucide/lab
245
* Icons are provided as IconNode data ready for use
246
*/
247
```
248
249
**Usage Examples:**
250
251
```typescript
252
import { Icon } from "lucide-react";
253
import { coconut, avocado, mango } from "@lucide/lab";
254
255
// Use lab icons directly
256
<Icon iconNode={coconut} />
257
<Icon iconNode={avocado} size={32} color="green" />
258
259
// Create reusable components from lab icons
260
const Coconut = createLucideIcon('coconut', coconut);
261
const Avocado = createLucideIcon('avocado', avocado);
262
263
// Use like standard Lucide icons
264
<Coconut />
265
<Avocado size={24} />
266
```
267
268
### Default Attributes
269
270
Custom icons inherit the same default SVG attributes as built-in icons.
271
272
```typescript { .api }
273
/**
274
* Default attributes applied to all custom icons:
275
* - xmlns: "http://www.w3.org/2000/svg"
276
* - width: 24, height: 24
277
* - viewBox: "0 0 24 24"
278
* - fill: "none"
279
* - stroke: "currentColor"
280
* - strokeWidth: 2
281
* - strokeLinecap: "round"
282
* - strokeLinejoin: "round"
283
*/
284
```
285
286
### Accessibility
287
288
Custom icons support the same accessibility features as built-in icons.
289
290
```typescript { .api }
291
/**
292
* Accessibility features:
293
* - Automatic aria-hidden="true" for decorative icons
294
* - Support for aria-label and role attributes
295
* - Proper focus management with ref support
296
*/
297
```
298
299
**Usage Examples:**
300
301
```typescript
302
// Decorative icon (automatic aria-hidden)
303
<Icon iconNode={customIcon} />
304
305
// Semantic icon with label
306
<Icon
307
iconNode={customIcon}
308
role="img"
309
aria-label="Custom action"
310
/>
311
312
// Interactive icon
313
<button>
314
<Icon iconNode={customIcon} aria-hidden="true" />
315
<span className="sr-only">Perform action</span>
316
</button>
317
```