mcpField
L
lucide-icons

lucide-icons

github.com/thinkoodleDesign & UI7177 installsUpdated 8w ago
Repository

About lucide-icons

A skill for Rails UI developers using Lucide icons through the `lucide-rails` helper. It covers inline SVG rendering, sizing, styling, icon selection, and accessibility practices.

Key features

  1. 01Render inline SVGs with `lucide_icon`
  2. 02Set icon size and stroke width
  3. 03Inherit text color and adapt to dark mode
  4. 04Pass through HTML attributes
  5. 05Reference common icon names
  6. 06Apply accessibility labeling rules

Use cases

  1. 01Add icons to buttons and navigation
  2. 02Label icon-only interactive controls accessibly
  3. 03Keep icon sizing and color consistent
  4. 04Find Lucide icons for interface concepts

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/thinkoodle/rails-skills --skill lucide-icons

After installing, type/lucide-iconsin Claude Code to confirm it loaded.

Bundled filesreference.md

Details

From the project README

Lucide Icons in Rails

Render Lucide icons as inline SVGs via the lucide-rails gem. Icons use currentColor so they inherit text color automatically.

When To Use This Skill

  • Adding icons to a Rails view (buttons, nav, badges, empty states)
  • Choosing the right Lucide icon name for a UI element
  • Making icons accessible (decorative vs interactive)
  • Styling or sizing SVG icons with CSS

Philosophy

  1. Icons are decoration until they aren't — Decorative icons need no label. Interactive icons (buttons, links) MUST have accessible text.
  2. Size intentionally — Always pass size:. The default 24px is too large for most inline contexts.
  3. Let CSS handle color — Icons inherit currentColor. Style the parent, not the SVG.
  4. Use the helper, never raw SVGs — lucide_icon keeps icons consistent, cacheable, and updatable.
  5. kebab-case names only — It's "chevron-right", never "chevronRight" or "ChevronRight".

Installation

# Gemfile
gem "lucide-rails"
bundle install

No JavaScript, no import maps, no asset pipeline config. The gem provides a Ruby helper that renders inline SVGs.

Basic Usage

<%= lucide_icon "home", size: 18 %>

Renders:

<svg width="18" height="18" viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="2"
     stroke-linecap="round" stroke-linejoin="round">
  <path d="..."></path>
</svg>
Helper Parameters
ParameterDefaultDescription
size24Width and height in pixels
classnilCSS classes
stroke_width2Stroke width (1–3 typical range)
<%= lucide_icon "home", size: 16, class: "text-muted" %>
<%= lucide_icon "home", size: 24, stroke_width: 1.5 %>

Any additional HTML attributes are passed through to the <svg> element:

<%= lucide_icon "copy", size: 14, data: { action: "click->clipboard#copy" } %>
<%= lucide_icon "x", size: 18, aria: { label: "Close" } %>

Size Guidelines

Pick size based on context. Be consistent within each context.

ContextSizeWhen
Badges, inline labels12pxTight spaces, small text
Dismiss/close, inline actions14pxBody text companion
Buttons with text16pxMost common for actions
Navigation sidebar18pxNav links, menu items
Card/list item icons20pxContent type indicators
Empty states, hero32–48pxLarge decorative icons

Styling with CSS

Color Inheritance

Icons stroke with currentColor — they inherit the parent's color:

.nav-link { color: var(--color-muted); }
.nav-link:hover { color: var(--color-default); }
/* Icon color changes automatically on hover */
Direct Icon Styling

When you need icon-specific colors, use a utility class on the parent or icon wrapper:

.text-success { color: var(--color-positive); }
.text-danger  { color: var(--color-negative); }
.text-warning { color: var(--color-warning); }
.text-muted   { color: var(--color-muted); }
<span class="text-success"><%= lucide_icon "check", size: 14 %></span>
<span class="text-danger"><%= lucide_icon "alert-circle", size: 14 %></span>
Stroke Width

Thinner strokes look more refined at larger sizes. Thicker strokes read better small.

<%= lucide_icon "settings", size: 48, stroke_width: 1.5 %>  <%# Large, elegant %>
<%= lucide_icon "check", size: 12, stroke_width: 2.5 %>     <%# Small, readable %>
Dark Mode

Since icons use currentColor, they adapt to dark mode when your text colors do. No extra work needed if your color system uses CSS custom properties.

Common Patterns

Icon + Text Button
<button class="btn btn-primary">
  <%= lucide_icon "plus", size: 16 %>
  Create Project
</button>
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
Icon-Only Button
<button class="btn-icon" aria-label="Close">
  <%= lucide_icon "x", size: 18 %>
</button>
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
}

Icon-only buttons MUST have aria-label.

Navigation Link
<%= link_to dashboard_path, class: "nav-link" do %>
  <%= lucide_icon "layout-dashboard", size: 18 %>
  Dashboard
<% end %>
Badge with Icon
<span class="badge">
  <%= lucide_icon "lock", size: 12 %>
  Restricted
</span>
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
Empty State
<div class="empty-state">
  <%= lucide_icon "folder-plus", size: 48, stroke_width: 1.5 %>
  <h3>No projects yet</h3>
  <p>Create your first project to get started.</p>
</div>
.empty-state {
  text-align: center;
  padding: 3rem 1rem;
}
.empty-state svg {
  color: var(--color-muted);
  margin-bottom: 1rem;
}
Icon in Link (Turbo)
<%= link_to edit_post_path(@post), class: "action-link", data: { turbo_frame: "post_form" } do %>
  <%= lucide_icon "edit", size: 14 %>
  Edit
<% end %>
Stimulus Integration
<button data-controller="clipboard" data-action="click->clipboard#copy"
        data-clipboard-text-value="<%= @invite_url %>">
  <%= lucide_icon "copy", size: 14 %>
  Copy Link
</button>

Accessibility

Rule: Decorative vs. Meaningful

Decorative — icon accompanies visible text. No extra markup needed:

<button>
  <%= lucide_icon "plus", size: 16 %> Add Item
</button>

Meaningful — icon is the only content. MUST add accessible text:

<%# Option 1: aria-label on the interactive element %>
<button aria-label="Close" class="btn-icon">
  <%= lucide_icon "x", size: 18 %>
</button>

<%# Option 2: sr-only span %>
<button class="btn-icon">
  <%= lucide_icon "x", size: 18 %>
  <span class="sr-only">Close</span>
</button>
Screen Reader Only Class
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
SVGs Are aria-hidden by Default

The lucide_icon helper renders SVGs that screen readers skip. This is correct — the accessible name belongs on the interactive parent element, not the icon.

Common Icons by Use Case

Navigation
Icon NameUse
homeHome/Dashboard
layout-dashboardDashboard/Overview
settingsSettings
usersTeam/People
file-textDocuments/Pages
log-outSign out
log-inSign in
menuHamburger menu
searchSearch
Actions
Icon NameUse
plusCreate/Add
editEdit/Modify
trashDelete
copyCopy to clipboard
xClose/Dismiss
checkConfirm/Save
eyeView/Preview
eye-offHide
downloadDownload
uploadUpload
external-linkOpen in new tab
Arrows & Chevrons
Icon NameUse
arrow-leftBack
arrow-rightForward
chevron-downExpand/Dropdown
chevron-rightNext/Drill-in
chevron-upCollapse
arrow-up-rightExternal/Outbound
Status & Feedback
Icon NameUse
check-circleSuccess
alert-circleError
alert-triangleWarning
infoInformation
help-circleHelp
loaderLoading (animate with CSS)
lockRestricted/Private
unlockPublic/Open
Communication
Icon NameUse
mailEmail
bellNotifications
message-circleChat/Comments
megaphoneAnnouncements
sendSend message
Files & Content
Icon NameUse
fileGeneric file
file-textDocument
folderFolder/Category
folder-plusNew folder
imageImage/Photo
videoVideo
linkLink/URL
Social & Misc
Icon NameUse
githubGitHub
twitterTwitter/X
globeWebsite/World
calendarDate/Schedule
clockTime/History
starFavorite
heartLike
filterFilter
sort-ascSort ascending
sort-descSort descending

Anti-Patterns

  1. Wrong icon name casing — "chevronRight" → use "chevron-right" (kebab-case always)
  2. Missing size — Don't rely on default 24px. Be explicit: size: 16
  3. Raw <svg> or <img> tags — Always use lucide_icon helper
  4. Styling SVG directly — Style the parent element's color, not the SVG's stroke
  5. Icon-only button without aria-label — Screen readers can't describe it
  6. Inconsistent sizes — Pick a size per context and stick to it
  7. Too many different icons — Reuse the same icon for the same concept across your app
  8. Using icons without visible text when meaning is ambiguous — A pencil icon might mean "edit" or "write." Add text or a tooltip.

Finding Icons

Browse the full library at lucide.dev/icons.

Search tips:

  • Search by concept: "arrow", "file", "user", "check"
  • Icons are named descriptively: circle-check not checkmark-in-circle
  • Related icons share prefixes: file, file-text, file-plus, file-x
  • If an icon doesn't exist in lucide-rails, the helper will raise an error at render time

Reference

For detailed patterns, edge cases, and advanced usage, see reference.md.

Comments

Markdown supported