Building an Icon Library Tool: From Lucide React to Search Filtering#

Managing icons in frontend projects is always a hassle. Designers send a bunch of SVGs, developers manually import, name, and wrap them. Recently discovered Lucide React, a clean icon library with simple API and high-quality icons. Built an online icon library tool and documented the implementation approach.

Lucide React’s Design Philosophy#

Lucide is a community-maintained fork of Feather Icons with consistent style and clean lines. The key advantage is Tree-shaking support:

// ✅ Only import used icons, bundle grows on-demand
import { Home, Search, User } from 'lucide-react'

// ❌ Traditional icon library imports entire package
import * as Icons from '@iconify/react'

Each Lucide icon is an independent React component, implemented with SVG under the hood:

// lucide-react internal implementation
const Home = createLucideIcon('Home', [
  ['path', { d: 'm3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z' }],
  ['polyline', { points: '9 22 9 12 15 12 15 22' }]
])

createLucideIcon accepts an icon name and SVG path data, returning a React component. Path data is an array of SVG elements supporting path, circle, rect, etc.

Core Features of the Icon Library Tool#

1. Search Filtering Algorithm#

When users type keywords, filter the icon list in real-time. Key is supporting multiple matching methods:

const filteredIcons = useMemo(() => {
  if (!search) return commonIcons

  const term = search.toLowerCase()
  return commonIcons.filter(icon =>
    icon.name.toLowerCase().includes(term) ||
    icon.keywords.toLowerCase().includes(term)
  )
}, [search])

Using useMemo to cache filtered results, avoiding recalculation on every render. Search logic:

  • Icon name matching: Home matches home, homework
  • Keyword matching: keywords: 'home, house, 首页' supports multilingual search

Keyword design is crucial. We preset common keywords for each icon:

const commonIcons = [
  { name: 'Home', keywords: 'home, house, 首页' },
  { name: 'Search', keywords: 'search, find, 搜索' },
  { name: 'User', keywords: 'user, person, 用户' },
  // ...
]

2. Icon Size and Stroke Control#

Lucide React supports two key props: size and strokeWidth:

<Home size={24} strokeWidth={2} />

size controls icon dimensions, strokeWidth controls line thickness. Tool implementation:

const [size, setSize] = useState(24)
const [strokeWidth, setStrokeWidth] = useState(2)

// Slider control
<input
  type="range"
  min={16}
  max={48}
  value={size}
  onChange={(e) => setSize(parseInt(e.target.value))}
/>

strokeWidth range is set to 1-3 with 0.5 steps. Thinner strokes blur on Retina screens, thicker strokes lose detail.

3. One-Click Copy Functionality#

Click an icon to copy import code and component code:

const handleCopy = async (iconName: string) => {
  const importCode = `import { ${iconName} } from 'lucide-react'`
  const svgCode = `<${iconName} size={${size}} strokeWidth={${strokeWidth}} />`

  await navigator.clipboard.writeText(`${importCode}\n${svgCode}`)

  // Copy success feedback
  setCopied(iconName)
  setTimeout(() => setCopied(null), 2000)
}

navigator.clipboard.writeText() is a modern browser API for copying text to clipboard. After successful copy, the icon changes to a checkmark, reverting after 2 seconds.

Performance Optimization Details#

1. useMemo Caching Filter Results#

With 50+ icons, recalculating filtering on every input has performance overhead:

const filteredIcons = useMemo(() => {
  // ...filtering logic
}, [search])  // Only recalculate when search changes

2. Dynamic Rendering Optimization#

Icon grid uses CSS Grid layout, browsers automatically optimize repaints:

<div className="grid grid-cols-6 sm:grid-cols-8 md:grid-cols-10 lg:grid-cols-12 gap-3">
  {filteredIcons.map(icon => (
    <button key={icon.name} onClick={() => handleCopy(icon.name)}>
      {/* Icon content */}
    </button>
  ))}
</div>

Responsive column design:

  • Small screen: 6 columns
  • Medium screen: 8 columns
  • Large screen: 10 columns
  • Extra large screen: 12 columns

3. Search Debouncing (Optional Optimization)#

With hundreds of icons, add debouncing:

const [debouncedSearch, setDebouncedSearch] = useState('')

useEffect(() => {
  const timer = setTimeout(() => {
    setDebouncedSearch(search)
  }, 300)  // 300ms debounce

  return () => clearTimeout(timer)
}, [search])

const filteredIcons = useMemo(() => {
  if (!debouncedSearch) return commonIcons
  // ...filtering logic
}, [debouncedSearch])

Edge Cases#

1. Icon Name Conflicts#

If your project already has a Home component, import conflicts:

// ❌ Conflict
import { Home } from 'lucide-react'
import Home from './components/Home'

// ✅ Rename
import { Home as HomeIcon } from 'lucide-react'

Consider adding alias options in generated code.

2. Icon Not Found#

Show a prompt when search has no results:

{filteredIcons.length === 0 && (
  <div className="text-center py-12 text-text-secondary">
    No matching icons found
  </div>
)}

3. Icon Loading Failure#

Lucide React supports on-demand icon loading, throwing errors for non-existent icons. Wrap with try-catch:

import * as LucideIcons from 'lucide-react'

const iconName = 'NonExistentIcon'
const IconComponent = LucideIcons[iconName]

if (!IconComponent) {
  console.warn(`Icon ${iconName} does not exist`)
  return <FallbackIcon />
}

Real-World Use Cases#

1. Rapid Prototyping#

During prototype development, copy code directly from the icon library to quickly build interfaces:

import { Home, Search, User, Settings } from 'lucide-react'

function Navigation() {
  return (
    <nav>
      <Home /> <Search /> <User /> <Settings />
    </nav>
  )
}

2. Unified Icon Management#

In team development, use Lucide icon library uniformly to avoid inconsistent styles from designer-provided SVGs.

3. Design System Integration#

Lucide’s clean, consistent icon style is perfect as a design system’s base icon set.

Final Result#

Based on the above approach, built an online tool: Icon Library

Key features:

  • 50+ common icons
  • Real-time search filtering
  • Adjustable size and stroke
  • One-click copy import code

Lucide React itself is already excellent. The tool just simplifies icon discovery and copying. Hope this helps.


Related tools: Button Generator | Color Extractor