Lucide began as a community fork of Feather Icons. Feather was widely loved for its restraint, then went quiet, and a group of contributors kept it moving rather than let a good set rot. The result is a library that inherited Feather's drawing rules almost exactly but has kept growing, and now covers roughly 1,700 icons under the permissive ISC licence.
That inheritance matters more than the icon count. Lucide is not a set of icons that happen to look similar. It is a set drawn to a written specification, which is why an icon added last month still sits correctly next to one drawn in 2020.
The short version
Lucide icons are drawn on a 24 by 24 grid with a 2px stroke, round caps and round joins, and roughly 1px of padding inside the box. They are stroke-based, not filled, so currentColor and stroke-width do most of the customisation for you. Names are lowercase kebab-case. The licence is ISC, which means commercial use is fine and attribution is not required.
The drawing rules, and why they matter
Every Lucide icon is built inside a 24 by 24 viewBox. The artwork sits within roughly a 22 by 22 live area, leaving about a pixel of breathing room on each edge so icons do not collide with adjacent text or button borders. Strokes are 2 pixels, caps and joins are rounded, and corner radii follow a small set of allowed values rather than being drawn by eye.
The practical benefit shows up when you scale. Because every icon has the same optical weight at 24px, you can drop any Lucide icon into any slot in your interface and it will not look bolder or lighter than its neighbours. Mixed-library interfaces almost always fail this test, and it is the single most common reason an interface feels slightly unfinished without anyone being able to say why.
It also means the set is predictable to override. If you know every icon is a 2px stroke on a 24 grid, one CSS rule restyles all of them.
Stroke width is the main dial
Because Lucide is stroke-based, stroke-width is the fastest way to change how the whole set feels, and it is the setting people most often forget exists.
| Stroke | Reads as | Good for |
|---|---|---|
| 1.25 to 1.5 | Light, editorial | Large icons, 32px and up, marketing pages, empty states |
| 1.75 to 2 | Default, neutral | Standard UI at 20 to 24px. This is what Lucide ships |
| 2.25 to 2.5 | Firm, dense | Small icons at 14 to 16px, where a 2px stroke starts to disappear |
The rule that saves you: as icons get bigger, reduce the stroke; as they get smaller, increase it. A 2px stroke on a 48px icon looks thin and spindly. The same 2px on a 14px icon fills the shape in until the icon becomes a blob. Browsers scale the stroke proportionally with the icon, which is exactly the wrong behaviour visually. Setting stroke deliberately per size is covered in more depth in the icon sizes guide.
How Lucide names icons
Names are lowercase, hyphen separated, and describe the object rather than the action: arrow-right, circle-check, message-square, trash-2. Two conventions are worth learning because they make searching much faster.
- Modifiers come after the noun. You want
circle-check, notcheck-circle. Search the shape first, then the container. - Numbered suffixes are alternates, not sizes.
trash-2is a second design of a bin, not a larger bin. Pick whichever fits your set and use it consistently.
Lucide also ships an alias file, which is why searching for "bin" or "delete" in a good search interface still finds trash. If you are searching the raw GitHub repo you lose that, which is one reason searching through a tool that carries the tag data is faster.
Installing Lucide in a project
If you are building an app and will use more than a handful of icons, install the package for your framework. Tree shaking means you only ship the icons you import, so the bundle cost is per icon, not per library.
| Stack | Package |
|---|---|
| React / Next.js | lucide-react |
| Vue 3 | lucide-vue-next |
| Svelte | lucide-svelte |
| Angular | lucide-angular |
| Plain HTML / vanilla JS | lucide |
| Raw SVG files, no bundler | lucide-static |
In React the components accept size, color, strokeWidth and absoluteStrokeWidth as props. That last one is worth knowing: it keeps the rendered stroke at a fixed pixel width regardless of the icon size, which solves the scaling problem described above without you doing the maths.
Getting one icon without npm
Installing a whole package for three icons on a marketing page is a bad trade. If you need a small number of icons, take the SVG directly.
- Search for the icon in the ICON OOP tool.
- Set the colour and stroke you want before exporting, so the file arrives finished.
- Copy the SVG markup to paste inline, or download the
.svgfile. You can also export a transparent PNG if the destination does not accept SVG.
Inline SVG is usually the right choice for a handful of icons: no extra network request, and the icon inherits colour from CSS. Once you are past roughly 15 to 20 icons on one page, consider an SVG sprite instead.
Colouring Lucide correctly
Lucide icons ship with stroke="currentColor" and fill="none". That combination is deliberate and it is the thing to preserve.
<svg width="24" height="24" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M5 12h14M12 5l7 7-7 7"/>
</svg>
Because the stroke is currentColor, the icon picks up the CSS color of whatever it sits inside. Hover states, dark mode and disabled states all work with zero icon-specific CSS. The mistake to avoid is setting fill to your brand colour, which does nothing visible on a stroke icon and then confuses the next person who reads the code. Full detail in how to change icon colour.
Lucide vs Feather vs Tabler
| Lucide | Feather | Tabler | |
|---|---|---|---|
| Roughly | 1,700 icons | 287 icons | 5,000+ icons |
| Licence | ISC | MIT | MIT |
| Actively added to | Yes | Largely dormant | Yes, quickly |
| Filled variants | Limited | No | Yes, full filled set |
| Feels like | Restrained, clean | Minimal, dated in places | Broad, slightly softer |
Choose Lucide when you want a tight, consistent set and are happy to occasionally not find a niche icon. Choose Tabler when coverage matters more than restraint, or when you need matched filled and outline pairs for selected and unselected states. Feather is only worth choosing if you already have it and it works. See the full icon set comparison.
Five things that trip people up
- The icon renders as a solid black shape. Something set
fillto a colour. Lucide needsfill="none". - Nothing renders at all. Usually a missing
viewBox, or width and height set to 0 by a CSS reset. Set an explicit size in CSS. - Strokes look uneven at small sizes. That is pixel snapping, not a broken file. Use even sizes, 16, 20, 24, rather than 15 or 23.
- Icons look bolder than the text next to them. Reduce stroke to about 1.5 when the icon is larger than the text it sits with.
- Different icons in one interface look mismatched. Almost always a second library sneaking in through a component package. Audit your imports.
Licence in plain English
Lucide is ISC licensed, a short permissive licence functionally very close to MIT. You can use the icons in commercial products, modify them, and ship them inside a paid app. You must keep the copyright and permission notice with the source, which in practice means leaving the licence file in place if you redistribute the icon files themselves. You do not need visible on-page attribution.
What is not covered: any brand logo is a trademark regardless of the icon licence. Lucide is a UI icon set and contains no brand marks, so this only applies once you mix in logo sets. The icon licensing guide works through this in detail.