* Rename music icons
* Make music icons more rounded
* Add more tags to music icons
* Add self-sttribution
* Update metadata
* Adding usecase
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* test(svelte): add Vite and SvelteKit integration fixtures
Scaffold a plain Svelte + Vite app (create-vite svelte-ts) and a SvelteKit
app (sv create --template minimal) that consume the built @lucide/svelte
package. Each fixture runs a production build, svelte-check and a Vitest
Browser Mode test, wired up via test:integrations:svelte and CI.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0198HmSjcE6LwPPScwLdMtjt
* test(svelte): label Pen as canonical and Edit2 as alias in fixtures
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0198HmSjcE6LwPPScwLdMtjt
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat(icons): added `circle-fading-play` icon
Adds a play button in a fading circle, completing the circle-fading-*
family (circle-fading-plus, circle-fading-arrow-up). Useful for short
clips, highlights, stories/reels and video previews.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(icons): add use-cases and tags to `circle-fading-play`
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(icons): credit contributors of base icons for `circle-fading-play`
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Update circle-fading-play.json
---------
Co-authored-by: tatianatsiguleva <324940161+tatianatsiguleva@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Karsa <contact@karsa.org>
* fix(docs): rename notification category title to notifications
* feat(icons): add cross and x tags to circle-x
* Update icons/circle-x.json
---------
Co-authored-by: Karsa <contact@karsa.org>
* add icons/shield-house.svg
* add icons/shield-house.json
* fix(icons): changed 'shield-house' icon
* Apply suggestion from @github-actions[bot]
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Refine use cases and update 'house' to 'property'
Updated use cases to use consistent phrasing and replaced 'house' with 'property' for clarity.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Fix missing newline in shield-house.svg
Add missing newline at the end of the SVG file.
* Fix missing newline at end of shield-house.json
Add newline at the end of shield-house.json
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* test(lucide-react): add tests for DynamicIcon fallback and ref forwarding
* style(lucide-react): format DynamicIcon test with Prettier
---------
Co-authored-by: grzdev <grzdev@users.noreply.github.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Load the Use Cases section of .github/instructions/metadata.instructions.md
into the --describe prompt so generated use-cases match the repository
style, and make useCase an array of phrases per usage group.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q2D9GYbnSV56MAVVhHPRhH
Retry 408 responses (and other transient errors) with backoff, only waiting
for the rate-limit reset on 403/429. Requests that still fail are skipped
with a warning instead of aborting the run, and the OpenAI client retries
too. Each icon is now described as soon as its searches finish and
--output is rewritten after every icon, so an interrupted run keeps its
results.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q2D9GYbnSV56MAVVhHPRhH
* ci: split lint-code into ESLint, Prettier and JSON Schema jobs with PR annotations
- ESLint: annotations via setup-node's built-in eslint-stylish problem matcher.
- Prettier: new scripts/lintFormat.mts formats unformatted files in memory, diffs
them and emits line-level `::error` annotations with the expected code.
- JSON Schema: replace ajv-cli with a local ESLint rule (Ajv draft 2020-12) that
validates icons/categories JSON against their `$schema` and reports at the
offending property. eslint-plugin-json-schema-validator was not used because it
runs Ajv in draft-07 mode and ignores `dependentRequired`.
All annotations use workflow commands, so they work on fork PRs with a read-only token.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8
* Improve root value check and property error handling
Enhance error reporting for JSON schema validation.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* style(lint): format jsonSchemaPlugin with Prettier
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8
* test commit
* fix(lint): annotate syntax errors from Prettier and ESLint in PRs
- ESLint/JSON Schema jobs use a small GitHub formatter that prints `::error`
workflow commands. setup-node's eslint-stylish matcher skipped parsing errors
because they have no rule id.
- lintFormat.mts annotates Prettier syntax errors (exit code 2) at their line and
column instead of only printing stderr, and still checks the other files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8
* ci(lint): spell check icon and category metadata with cspell annotations
- New "Spelling" job runs scripts/lintSpelling.mts, which turns cspell findings
into `::error` annotations (with cspell's suggested fix when it has one).
- cspell accepts both US and British English, ignores contributor usernames and
deprecated `alias.typo` aliases.
- Add existing search tags and domain terms to .cspell/custom-words.txt so the
current metadata passes.
- Add `lint:spelling` to `pnpm lint` and lint-staged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8
* fix(lint): pin JSON schemas per file set and drop typo tags
- json-schema/no-invalid now takes the schema from config (icon.schema.json for
icons, category.schema.json for categories) and reports a `$schema` that
points elsewhere, so metadata can't opt out of validation.
- Remove the misspelled `frigerator` and `sterisk` tags and their allowlist entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8
* fix(icons): split joined-word tags into separate words
Tags like `groupchat` and `timemachine` become `group chat` and `time machine`
so they read naturally and pass the spell check without allowlisting. Where the
spaced tag already existed (`smart home`) the joined one is dropped.
cspell now skips all alias names, since they are icon names that can't change
(e.g. the deprecated `palmtree` alias).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVxEtqNswEDq1N23taZYh8
* Revert
* Try another error
* Revert error
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Add --context and --describe to the icon usage script. --context extracts
how each matched icon is used (parent elements, labels, handlers, links,
snippet) and summarizes it per icon. --describe groups those usages into
use-case descriptions with an OpenAI model. Also adds --max-contexts and
--icons-file, accepts export names like Trash2, and allows a single icon.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q2D9GYbnSV56MAVVhHPRhH
* feat(icon): add kazakh tenge
Signed-off-by: Hakan Kayra Doğan <hkayrad@gmail.com>
* fix: add one more use case to kazakh-tenge.json
Signed-off-by: Hakan Kayra Doğan <hkayrad@gmail.com>
* Fix formatting of Kazakh Tenge use-cases
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: kazakh-tenge icon format
Signed-off-by: Hakan Kayra Doğan <hkayrad@gmail.com>
* fix: updated the icon to use same size as other typographic icons
Signed-off-by: Hakan Kayra Doğan <hkayrad@gmail.com>
* fix: inconsistent indentation in kazakh-tenge.json
Signed-off-by: Hakan Kayra Doğan <hkayrad@gmail.com>
* Apply suggestion from @github-actions[bot]
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Format svg
* Remove 'tenge' from kazakh-tenge.json
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Signed-off-by: Hakan Kayra Doğan <hkayrad@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Eric <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Added icons/armenian-dram.svg
* Added icons/armenian-dram.json
* Update icons/armenian-dram.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: add use-cases to armenian-dram metadata
* fix(icons/armenian-dram): adjust cap height to match Unicode standard
- Move top horizontal stroke from y=12 to y=6 to align with standard Unicode cap-height
- Adjust second stroke from y=16 to y=10 for consistent spacing
- Adjust vertical stroke endpoint to match new cap height
- Maintains the icon's visual design while following Lucide's Unicode glyph conventions
* fix(icons): restore original Armenian dram icon before making the review-driven cap-height adjustment
* fix(icons): adjust Armenian dram cap height to match Unicode-style proportions
* restore original Armenian dram icon from base commit
* fix(icons): adjust armenian-dram cap height to match Lucide typographic conventions
Align the dram symbol's top and bottom to match the 16px cap height used by other uppercase-letter and currency icons (H, B, I, euro, etc.). The symbol maintains its original design; only the vertical positioning is adjusted.
Resolves the review feedback on PR #4456.
* Apply suggestion from @karsa-mistmere
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
* Updates needed to support Solid 2
* Switch to the next tag
* feat(packages): add `@lucide/solid` package for Solid 2
Solid 2's API is a breaking change from Solid 1 and is still an RC, so
`lucide-solid` stays on Solid 1 (`solid-js: ^1.4.7`) untouched and Solid 2
support ships as a new `packages/solid` package named `@lucide/solid` —
the same scheme already used by `@lucide/svelte` and `@lucide/angular`.
The package is a copy of `lucide-solid` on the `@lucide/shared` build
architecture, ported to Solid 2:
- `splitProps` -> `omit`, `solid-js/web` -> `@solidjs/web`,
`JSXElement` -> `Element`, `Context.Provider` -> `<Context value>`
- `jsxImportSource` is `@solidjs/web` in tsconfig, the esbuild step and
`ts.createProgram`; rollup externals drop the removed `solid-js/store`
- `vite-plugin-solid` -> `@solidjs/vite-plugin`
- tests keep upstream's coverage with two Solid 2 adaptations: boolean
attribute literals must be strings (`aria-hidden="false"`), and writes
are batched so the reactivity tests need a `flush()` before asserting
Rendered output is unchanged — the snapshots are byte-identical to
`lucide-solid`'s.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(solid): fix React leftovers in the Solid guide
The Solid guide was derived from the React guide and three things were
not carried across:
- `advanced/typescript.md` still told readers the types are for "a
TypeScript React project"
- its `LucideIcon` example kept React's destructured-props signature.
The `: ButtonProps` annotation had also been dropped in the copy, so
`ButtonProps` was declared but unused and the parameters were
implicitly `any`. Destructuring props breaks reactivity in Solid —
verified: with `({ icon: Icon, label })` a changing `label` never
reaches the DOM, while `props.label` updates correctly.
- `advanced/aliased-names.md` had an orphaned `###` heading; its parent
`## Choosing import name style` was dropped during the conversion
because it documents React-only subpath exports.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs: type the shared Sandpack wrapper with `SandpackProps`
The base Sandpack wrapper declared its props as
`FunctionalComponent<LucideProps>` with `LucideProps` imported from
`@lucide/vue`, which has nothing to do with a Sandpack embed. None of
the props the markdown plugin actually passes (`template`, `files`,
`options`, `customSetup`, `theme`) were declared, so they only reached
the inner `<Sandpack />` via Vue's fallthrough attributes.
Declare `SandpackProps` from `sandpack-vue3` instead and forward them
explicitly. This also removes the `@lucide/vue` import that made every
framework guide — including the Solid one, which uses this wrapper
directly — appear to reference the Vue package.
Verified with a full `vitepress build`: each framework guide's chunk
still carries its own template (react/vue/vite-svelte/vanilla/
vite-solid) and all five props reach the component.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs(solid): document the Solid 2 flavour in the getting started guide
The Solid guide teaches `lucide-solid` throughout (64 references), so
the one-line note about `@lucide/solid` left Solid 2 readers on a page
whose every install command and live example is Solid 1 — and the
packages list points `@lucide/solid` at this same page.
Replace that note with a "Using Solid 2?" callout holding its own
tabbed install group, the import-specifier swap, and a table of the
Solid 2 changes that affect code written around Lucide (`@solidjs/web`,
`jsxImportSource`, `splitProps` -> `omit`, `<Ctx value>`), linking out
to Solid's own migration guide for the rest.
The claim that both packages expose the same components and props is
checked, not assumed: `dist/types/lucide-solid.d.ts` is identical
between the two packages, and the only differences anywhere in the
public type surface are Solid's own renames (the `JSX` namespace source
and `JSXElement` -> `Element`).
Keeps one guide section for both packages, matching how upstream
handles the two Svelte packages.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(solid): port lucide-solid to Solid 2
- Icon/context/types use Solid 2 APIs: omit() instead of splitProps(),
Dynamic and JSX types from @solidjs/web.
- solid-js / @solidjs/web 2.0 (rc) as peer and dev dependencies,
babel-preset-solid 2; rollup and tsconfig updated to match.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add integration test
* Update rollup file
* Fix tests
* Revert lucide-solid changes
* update lockfile
* Fix docs
* Format code
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Eric <eric.fennis@gmail.com>
* fix(github/actions): move to daily release flow with gated releases on other changes
* Update .github/workflows/ci.yml
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* Apply suggestion from @karsa-mistmere
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* test(lucide-solid): add Vite and SolidStart integration fixtures
Mirror the `lucide-react` integration suite for `lucide-solid`. Both
fixtures are scaffolded by `pnpm create solid` and consume the built
package through its public entry points only:
- `integrations/lucide-solid/vite` (vanilla/basic template)
- `integrations/lucide-solid/solid-start` (solid-start-v2/basic template)
Each runs a production build, `tsc --noEmit`, and a Vitest Browser Mode
test in Chromium under a `check` script, wired into the new root
`test:integrations:solid` script and an `integration` job on the
`lucide-solid` workflow.
The showcase exercises the bare export, per-icon props, `LucideProvider`,
an alias against its canonical icon, and the `lucide-solid/icons/circle`
deep import. `lucide-solid` has no `DynamicIcon`, so the deep import
takes the place of the React fixtures' dynamic-icon block. The SolidStart
spec additionally navigates between two routes.
Both fixtures resolve the package through its `solid` export condition
and compile the raw JSX in `dist/source`; the SolidStart build bundles it
into the SSR server chunk.
Each fixture carries a second TypeScript project,
`tsconfig.declarations.json`, that compiles the showcase with
`skipLibCheck: false` so the declarations shipped in `dist/types` are
actually read. That catches a `.d.ts` pointing at a file the build never
emitted, which the app typecheck silently degrades to `any`.
`@solidjs/start@2` requires Vite 8 while the repository pins Vite 7, so
the SolidStart fixture is released from that pin by a parent-scoped
`'@lucide/integration-solid-solid-start>vite'` override. Only that
importer resolves to Vite 8; every other package stays on 7.3.6.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAmVJZqdypLNwEFhCmfsPN
* fix(solid): align SolidStart fixture with Vite 7
* Upgrade vite dependency from 7.3.6 to 8.3.2
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Update README.md to clarify Vite overrides
Removed duplicate note about bug #4846 and added a section on Vite overrides.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* test(react-native): add failing regression test for #3877 (rest props leaking onto child shapes)
* fix(react-native): stop forwarding arbitrary rest props to child shape elements
Fixes#3877. customAttrs (merged onto every child Path/Circle/etc.)
was spreading ...rest in addition to stroke/strokeWidth, which
duplicates event handlers like onPress onto every child shape, not
just the parent Svg. This breaks touch handling in react-native-svg,
since child shapes' own responder handling competes with the parent's.
fill is now pulled explicitly from the already-resolved svgAttributes
(same pattern already used for stroke/strokeWidth) instead of relying
on the blanket ...rest spread, since it's the one presentational
attribute that genuinely needs to reach every child and was otherwise
only reaching them incidentally via that spread.
Mirrors the same fix pattern already applied to this file for the
identical bug class: PR #3892 (className leaking onto children) and
commit 5d9cc158 / #4881 (testID not reaching the right element).
* fix(react-native): close strokeLinecap/strokeLinejoin regression from prior fix-wave (#3877)
Final review on this branch found that the prior fix (stopping
customAttrs from spreading ...rest onto child shapes) introduced a
real regression: childDefaultAttributes hardcodes
strokeLinecap/strokeLinejoin to 'round', and since customAttrs no
longer carried ...rest, a caller's override of either prop never
reached the child merge — the hardcoded default silently won every
time.
Extend customAttrs to also pull strokeLinecap/strokeLinejoin from the
already-resolved svgAttributes, the same pattern already used for
fill/stroke/strokeWidth. Verified childDefaultAttributes has exactly
these 5 keys (defaultAttributes.ts) and that svgAttributes correctly
resolves caller overrides for both (traced through
buildLucideIconForReact in @lucide/shared), so this closes the gap
completely.
Added a regression test that is RED against the unfixed code
(asserts strokeLinecap='butt'/strokeLinejoin='miter' survive to
every child) and GREEN after the fix.
Also, per the same review:
- Strengthened the existing "should not forward arbitrary rest props"
test to assert the parent Svg DOES receive onPress (same reference),
proving where the prop went, not just where it didn't.
- Added afterEach(() => vi.restoreAllMocks()) as defense-in-depth
against future test reordering (vitest.config.mts already sets
mockReset: true, so nothing was previously broken by this).
Skipped the local quality-gate hook for this commit: its repo-root
tsc check fails identically (same ~700 pre-existing errors, e.g.
missing generated icon/alias files and missing --jsx flags in
packages outside lucide-react-native) against the clean base commit
with zero changes applied (verified via git stash + npx tsc --noEmit
-p . before restoring this diff) - a pre-existing, repo-structural
gate false positive, not something this diff caused. The actual
in-scope test suite (tests/Icon.spec.tsx, tests/lucide-react-native.spec.tsx,
tests/context.spec.tsx) runs clean: 20/20 passing, no warnings.
Signed-off-by: Mohsin Manzoor Bhat <mohsinmanzoor1913@gmail.com>
---------
Signed-off-by: Mohsin Manzoor Bhat <mohsinmanzoor1913@gmail.com>
* fix(docs): persist icon customizer settings
Persist icon color, size, stroke width, and absolute stroke width between page navigations and reloads.
Keep a shared icon style state across the homepage and icons page, clamp the homepage preview size to its supported range, and apply persisted absolute stroke settings after mount.
* fix(docs): avoid icon customizer hydration flicker
Initialize persisted icon settings synchronously and apply absolute stroke width before the first rendered state.
* fix(docs): restore icon styles before first paint
Apply stored icon styles from a head script before hydration, defer customizer visibility until mount, and render persisted switches on the client to avoid stale SSR classes. Keep absolute stroke state synchronized globally and cover prepaint initialization with regression tests.
* fix(site): persist icon customizer
* fix(packages/react): update vulnerable @tanstack packages
* fix(docs): persist icon customizer settings
Persist icon color, size, stroke width, and absolute stroke width between page navigations and reloads.
Keep a shared icon style state across the homepage and icons page, clamp the homepage preview size to its supported range, and apply persisted absolute stroke settings after mount.
* fix(docs): avoid icon customizer hydration flicker
Initialize persisted icon settings synchronously and apply absolute stroke width before the first rendered state.
* fix(docs): restore icon styles before first paint
Apply stored icon styles from a head script before hydration, defer customizer visibility until mount, and render persisted switches on the client to avoid stale SSR classes. Keep absolute stroke state synchronized globally and cover prepaint initialization with regression tests.
* fix(site): persist icon customizer
* fix(packages/react): update vulnerable @tanstack packages
* fix(site): generalize usePersistedIconStyle to reduce code duplication in icon customizers
* fix(site): home size slider now uses max="256", matching the sidebar
* fix(site): fix linting issues in iconStyleHead.js
* fix(site): make Switch.vue hydration safe
* fix(site): fix home icon customizer color input width
* fix(site): make home icon customizer not persistent
* fix(site): fix duplicate ids in sidebar icon customizer as well
* fix(site): various minor fixes to the customizer bl
* fix(site): revert "[default]" placeholder
---------
Co-authored-by: epifaniofrancisco <epifaniofrancisco03@gmail.com>
* fix(lucide-preact): import `SVGAttributes` and `SignalLike` from `preact`
`LucideProps` extended `JSX.SVGAttributes` and `createLucideIcon` used
`JSX.SignalLike`. Preact 10 marks both JSX aliases as deprecated in favour
of the top-level exports, and Preact 11 removes them: its `JSX` namespace
only keeps what TypeScript needs for JSX checking.
Against Preact 11 the package fails `tsc` (TS2694), and the published
`.d.ts` resolves `LucideProps` to an error type. Consumers with
`skipLibCheck: true` see no error, but every icon then accepts unknown
props and event handler parameters become implicit `any`.
The top-level `SVGAttributes` and `SignalLike` exports already exist in
Preact 10.27.2, the current peer floor, and are identical to the JSX
aliases there, so the props type does not change for Preact 10 users.
* fix(lucide-preact): add Preact v11 compatibility
Widen the `preact` peer range to `^10.27.2 || ^11.0.0-0`. The `-0` lets
the 11.0.0 release candidates install without peer warnings and still
covers every 11.x release.
The dev dependency stays on Preact 10. The lockfile does not record
workspace peer ranges, so it is unchanged.
Mirror the lucide-react integration tests for `@lucide/vue`. Each fixture is
scaffolded with the framework's official generator (`pnpm create vue@latest`,
`pnpm create nuxt@latest`, `pnpm create vike@latest --vue`), trimmed of demo
boilerplate, and runs a production build, `vue-tsc`, and a Vitest Browser Mode
test in Chromium that renders the public `@lucide/vue` APIs (static icon,
per-instance props, `setLucideProps` context, alias vs canonical icon).
Nuxt is pinned to 4.4.8: 4.5.x requires Vite 8, which the workspace-wide
`vite: ^7.3.6` override does not allow.
Wire it up with a `test:integrations:vue` root script and an `integration`
job in the Lucide Vue workflow.
Claude-Session: https://claude.ai/code/session_01KmQsnSECZoNxh1GJ15BmdH
Co-authored-by: Claude <noreply@anthropic.com>
* fix(shared): escape attribute values in buildLucideSvg
Attribute values were interpolated into the SVG string as-is, so a value
containing a double quote, ampersand or angle bracket (for example in a
custom attribute or class name) produced malformed markup.
* Use replace(/x/g) instead of replaceAll for broader TS lib compat
lucide-react-native's tsconfig doesn't include the ES2021 lib that
replaceAll requires, failing typecheck. A global regex replace is
functionally identical here and works under any target.
* Escape the full set of relevant HTML entities in attribute values
Also escape > and ' per review feedback, not just & " <.
* Apply suggestion from @karsa-mistmere
---------
Co-authored-by: Karsa <contact@karsa.org>
`lucide-react` and `lucide-react-native` both ship `.d.ts` files that
import React types (`ForwardRefExoticComponent`, `SVGProps`,
`RefAttributes`, `ReactNode`), but neither package declares
`@types/react`. Under a hoisted `node_modules` this resolves by
accident, so the gap is invisible in normal testing.
It does not resolve under a strict layout — most notably pnpm's global
virtual store (`enableGlobalVirtualStore`), where each package is linked
from a store path outside the consuming repo. TypeScript resolves a
package's imports relative to where that package physically lives and
ignores `NODE_PATH`, so `react` resolves to the untyped
`react/index.js`. Every icon's props silently degrade to `any`, and
consumers hit implicit-any errors on their own callbacks under
`noImplicitAny`. `skipLibCheck: true` hides the errors inside the
`.d.ts` itself, which is why this survives most typechecks.
Declaring the typings package as a peer dependency (rather than a hard
dependency) lets it dedupe against whatever `@types/react` the consumer
already has. `peerDependenciesMeta` marks it optional so JS-only
consumers get no unmet-peer warning.
Verified by packing each package and installing the tarball into a
scratch consumer with `pnpm --virtual-store-dir` pointing outside the
consumer, then typechecking with `skipLibCheck: false` and a
`@ts-expect-error` probe on a nonexistent icon prop — a positive type
assertion keeps passing when types widen to `any`, so it would not
catch a regression. Before the change the probe reports
`TS2578: Unused '@ts-expect-error' directive` plus `TS7016` inside the
shipped `.d.ts`; after it, `tsc` is clean and `--traceResolution`
shows `react` resolving to `@types/react/index.d.ts` instead of
`react/index.js`. Existing peer ranges are unchanged and the lockfile
is unaffected.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
buildLucideIconForReact is the entry point both lucide-react and
lucide-react-native use to build an icon, and its whole job is renaming
the hyphenated SVG attributes to the spellings React expects. Nothing
tested that rename directly: the other build helpers have specs in
packages/icons/tests, and this one had none anywhere in the repo.
The spec pins the five renames it applies, checks that attributes React
already accepts are left alone, that aria-hidden stays hyphenated, that
vector-effect is renamed on child nodes for a non-scaling stroke, and
that a caller's own attributeNames are merged without displacing the
React spellings.
Verified that the spec is not vacuous: removing the class -> className
entry from the rename map fails two of the five tests.
Co-authored-by: Vugar Bakhishov <vugarbbakhishov-hub@users.noreply.github.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
The Icon component destructured `testID` out of its props and re-emitted it as
`data-testid`, which is a web attribute. react-native-svg only forwards `testID`
to the native view (see extractProps) and drops `data-testid`, so
`<Icon testID="my-icon" />` rendered an element that no React Native test query
or UI automation tool can find. `LucideProps` extends `SvgProps`, so the prop
type checks and the failure is silent.
v0 spread `testID` straight onto `Svg`, so this is a regression for React Native
consumers. An explicitly passed `data-testid` still reaches the element through
the remaining props, so nothing is lost for react-native-web users.
The react-native-svg test mock now maps `testID` onto `data-testid`, so the
DOM based test suite identifies elements the way React Native does. Every
existing `testID` test fails against the previous behaviour.
* Added icons/square-sparkles.svg
* Added icons/square-sparkles.json
* apply design from @karsa-mistmere
* Add use-cases field to square-sparkles.json
* Add use cases for square sparkles icon
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* feat(icons): added square-dashed-plus
* Update icons/square-dashed-plus.json
Suggested via PR AI
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update icons/square-dashed-plus.json
Suggested by PR AI
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update icons/square-dashed-plus.json
Suggestion made by PR AI
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Revise use cases for square dashed plus icon
AI PR Suggestion
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Peter Jamrozinski <peter.jamrozinski@johnsonfit.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Add Nepali Rupee icon
* Apply suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* refactor: center nepali rupee icon and use perfect circular arc
* Updated with horizontally centered
* Update use cases for Nepali rupee
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix(docs): replace missing LucideIcon icon names in guides
* feat(docs): add How to use Lucide icons section to resources
* feat(docs): update accessibility guide links
* fix(docs): fix dead link in guide.md
* fix(docs): fix color in example image
* fix(docs): fix overlay color in example images
* fix(how-to): added caution guidance type & rework some guidance rules relating to compact interfaces
* fix(how-to): replaced caution items, what the heck, when did I reorder these 😅
* fix(how-to): fix colors
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* Added icons/plant-pot.svg
* Added icons/plant-pot.json
* Updated icons/plant-pot.svg
* Updated icons/plant-pot.svg
* Apply batched suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add use-cases field to plant-pot.json
Added an empty array for use-cases in the plant-pot icon JSON.
* Update plant-pot.svg with new design paths from @karsamistmere
* Add contributor 'karsa-mistmere' to plant-pot.json
* Add use cases for plant pot icon
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* play with image
* changes to width
* changes to contributing image to show on github
* peace-sign
* feat(lab): moved `peace-sign` icon to lab
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Brizen <bcb5360@nyu.edu>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* feat(icons): add layout-horizontal and layout-vertical
Adds two icons for layout direction: two blocks above a left-to-right
rail, and two blocks beside a top-to-bottom rail. These match the frame
layout direction modes found in design tools and CSS flex-direction
(row / column).
This fills a gap identified when the flexbox icon request (#399) was
closed: "Only missing icons are: flex-direction and flex-wrap icons,
plus baseline." The align-* and stretch-* family covers alignment,
justification and distribution, but nothing currently depicts direction
itself.
Design notes:
- Reuses the 7x7 rx=1 block already shared by layout-grid, layout-list
and layout-panel-*, rather than introducing a new base shape.
- The two icons are exact mirrors, with rails on the integer grid
(y=18 / x=18) so the 2px stroke stays sharp at low DPI.
- The 3x3 chevron is the one used by decimals-arrow-right, which shares
the same composition: elements above, directional rail below.
* Rename icons
* Apply batched suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update usecases
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Replace the misspelled comprimised tag across the five affected shield variants so displayed metadata and exact tag matching use the correct spelling.
Co-authored-by: Jakob Guddas <github@jguddas.de>
* feat(icons): add dome and dome-2 icon
* Update icons/dome.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update icons/dome-2.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* chore(icons): updare contributors for dome icons
* refactor(icons): remove dome-2 and keep the best design as dome
* chore(icons): update categories for dome icon
* feat(icons/dome): replaced design with compliant and linted version
* Update dome.json
* Update dome.json
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
* feat(icons): add gap-horizontal and gap-vertical
Adds two icons for the gap between items in a layout: facing brackets
with the gap itself marked between them.
The brackets are the container edges and the dot marks the space, which
is what distinguishes these from the align-* family — those show the
items and a guideline, these show only the space. Rails span 2-22,
matching align-horizontal-space-between's M3 2v20.
The dot uses the "M12 12h.01" zero-length path, the same idiom dice-*,
badge-percent and ~130 other icons use for a 2px dot.
* feat(icons): add gap-horizontal and gap-vertical
Adds two icons for the gap between items in a layout: two facing brackets
with a dashed line marking the space between them.
Redesigned from the earlier dot version per review on #4544. This uses
the square-centerline-dashed-horizontal / -vertical construction with the
bracket ends flipped inward, so the brackets read as the two item edges
and the dashed line as the gap. Avoids the small-circle dot that the
earlier version relied on.
Co-Authored-By: Karsa <17746067+karsa-mistmere@users.noreply.github.com>
* Apply suggestions from code review
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------
Co-authored-by: Karsa <17746067+karsa-mistmere@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add metadata information
* improve contribution
* feat(docs): added new contribution guide
* feat(docs): minor linting fix
* feat(docs): update dead link
* feat(docs): change layout, some stylistic change, et cetera
* feat(docs): alter metadata example layout
* feat(docs): update titles, split use case & tag guide
* feat(docs): finetune some design guide images & make
* feat(docs): finetune some design guide images & add icons to use case guide
* feat(docs): added ux writing instructions & proofread markdowns to match these guidelines
* feat(docs): updated design language / specification descriptions to better distinguish what is what
* feat(docs): updated design language / specification descriptions to better distinguish what is what
* feat(docs): changed some languages again
* fix(icons): add design principle do/dont about diagonal lines
* fix(icons): decrease blurriness of ideal pixel perfection pixel preview
* fix(icons): remove color from pixel perfection previews
* fix(icons): remove color from pixel perfection previews
* fix(icons): reword symmerical icon rule
* fix(icons): fix calendar design in density rule image
* fix(icons): slightly adjust centered stroke rule text
* Rename 'useCases' property to 'use-cases'
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Update allowed SVG elements in code conventions
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Add square alert icon
Introduces a new 'square-alert' icon with associated metadata and SVG file. The icon represents alert or warning notifications within a square shape.
* Reorder elements in square-alert.svg
Moved the <rect> element before the <path> elements to adjust the SVG structure. No visual changes to the icon.
* Add newline at end of square-alert.json
linting fix
* changed path to line
* Add missing contributors to square-alert.json
* Update square-alert.json
* docs(square-alert): add use cases
* refactor(icons): rename square-alert to square-exclamation-point
* fix: review comments
* Update icons/square-exclamation-point.json
* Update square-exclamation-point.json
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Karsa <contact@karsa.org>
* Added icons/shopping-cart-plus.svg
* Added icons/shopping-cart-plus.json
* feat(icons): add shopping-cart variants
Updated the base shopping-cart icon and added the plus and minus variants to satisfy the request in issue #1746. All icons have been redesigned to stay consistent with each other, adhering to the official Lucide contribution guidelines.
Closes#1746
Base icon design is related to PR #2909
* fix(icons): update shopping-cart variants
* feat(metadata): simplify search tags for shopping-cart variants
* Update shopping-cart.json
* Update shopping-cart-minus.svg
* Update shopping-cart-plus.svg
* Update shopping-cart-plus.json
* Update shopping-cart-minus.json
---------
Co-authored-by: Jakob Guddas <github@jguddas.de>
Co-authored-by: Karsa <contact@karsa.org>
* can icon
* cleaned using lucide studio
* added use cases and tags
* Update can.svg
* Update can.json
---------
Co-authored-by: Karsa <contact@karsa.org>
* fix(icons): unify check, cross and plus sizes across icons
* fix(icons): fix minor gap issues
* fix(icons): shrink x in git-merge-conflict
* fix(icons): adjust x to be aligned with matching plus in book-x, grid-2x2-x and user-round-x
* fix(icons): update checkmark in message-circle-check.svg
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-08-28 15:01:54 +02:00
Jakob Guddasgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Karsa
* Added icons/bat.svg
* Added icons/bat.json
* Username change
* Update icons/bat.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update bat.svg
* Modify SVG path data for bat icon
* Add use cases to bat.json
Added use cases for night mode and related themes.
* Update bat.svg
* Move bat icon
---------
Co-authored-by: Rajnish Mehta <172272341+KnarliX@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* fix: update icon design discussion template
Remove name and description fields from icon design template
* Add title field to icon design discussion template
* Add description for icon request template
Added a description field for icon requests.
* Update icon-design.yml
* Format code
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* feat(icons): add aspect-ratio
Adds an aspect-ratio icon: a frame with two opposing corner brackets,
depicting the proportions of a frame rather than the frame itself.
Distinct from ratio, which is two overlapping rects showing portrait and
landscape orientation, and from the scan / minimize / maximize family,
which use four corner brackets rather than two.
* feat(icons): rename aspect-ratio to square-dimensions
Per review on #4547 (@karsa-mistmere, @ericfennis): the primary shape is
a square, so it takes the square-<x> name, and square-dimensions reads
more naturally for setting width/height than the ratio-specific
aspect-ratio. Retunes tags and use-cases toward size/dimensions.
* Update icons/square-dimensions.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update icons/square-dimensions.json
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
* feat(icons): add square-text
Adds square-text: a solid square containing three ragged lines of text.
The set has square-dashed-text but no solid-border equivalent, which is
the same asymmetry solid/dashed pairs elsewhere avoid. This reuses
square-dashed-text's exact text glyph (M7 8h8 / M7 12h10 / M7 16h6) on the
standard 18x18 rx=2 square, so it reads as the solid twin.
Distinct from square-menu, whose lines are equal full-width (a menu, not
running text).
* chore(icons): expand square-text tags and fill use-cases
Applies the metadata bot's tag suggestions (curated) and fills the
use-cases field.
* chore(icons): promote lab/text-square to square-text
Per review on #4609: square-text is identical to lab/text-square, so
this removes the lab entry and merges its metadata (tags + development
category) into the promoted icon.
* chore(icons): credit danielbayley and expand square-text use-cases
Per review on #4609: adds @danielbayley (original author of lab/text-square)
to contributors, and expands use-cases per @ericfennis.
* feat(icons): add angle
Adds an angle icon: two rays meeting at a vertex with an arc marking the
angle between them. There is no icon for an angle or degree measurement
in the set today.
The arc is r=10 centred on the vertex at (3,21), so its endpoints land
exactly on the two rays rather than floating near them. The rays reuse
the 2px rounded corner used throughout the set.
* Apply suggestion from @github-actions[bot]
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Apply suggestion from @github-actions[bot]
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* ci(security): add scoped GITHUB_TOKEN permissions to all workflows
Every workflow now declares its token permissions explicitly instead of
inheriting the repository default, which satisfies OpenSSF Scorecard's
token-permissions check.
Multi-job and write-scoped workflows use `permissions: {}` as a
deny-by-default floor at the top level, with the actual grants declared
per job. Consolidating those grants at the workflow level would leak
scopes into jobs that don't need them — a `permissions` block replaces
rather than merges, so the empty top-level block also makes a forgotten
job block fail closed rather than inherit the default.
Single-job read-only package workflows keep a plain top-level
`contents: read`; there is no write scope to leak, so a second block per
file would only add noise.
Scopes were matched to what each job's steps actually do:
- linting-icons: `contents: read` per job. No `pull-requests: read` —
tj-actions/changed-files only needs that with `use_rest_api: true`,
and here it reads the local .git.
- lint-pr-title: `pull-requests: read`, which
action-semantic-pull-request needs to read the PR title.
- close-stale-prs: `pull-requests: write` only; the job never checks out.
- comment-icon-preview: `actions: read` for the cross-run artifact
download, plus `pull-requests: write` to post the comment.
- release: `contents: read` for the checkouts, `id-token: write` only on
the publishing jobs that use npm provenance, and `contents: write` only
on post-release, which uploads the release assets. The prepare job
neither checks out nor calls the API, so its empty scope is explicit.
- ci: `contents: write` only on create-release; the reusable-workflow
calls pass `id-token: write` and `contents: write` down to release.yml,
since a called workflow can only reduce what the caller grants.
Verified with actionlint (no new findings) and zizmor (no
excessive-permissions findings).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(ci): correct pull_request path filter in the lucide-vue workflow
The Vue package lives in packages/vue, not packages/lucide-vue, so the
filter never matched and the workflow did not run for changes to the
package itself.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* Remove empty scope in prepare
* Patch WeaknessCWE-506
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(icons): add layout-freeform
Adds an icon for freeform layout: three blocks, no two sharing an edge.
It matches the "no auto layout" / free positioning mode found in design
tools, as the counterpart to constrained layout modes.
Design notes:
- Reuses the 7x7 rx=1 block already shared by layout-grid, layout-list
and layout-panel-*, rather than introducing a new base shape.
- Each block is offset so that no two share an edge, which is what
separates it from layout-grid.
- The offset is 1px: a 2px offset reads more clearly at 16px, but brings
the top-right and bottom-left blocks within 1.66px of each other
diagonally, under the 2px element spacing guideline. See the PR for the
alternatives.
* Update icons/layout-freeform.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(icons): replaces `podcast` icon with new `mic-*` icons
* fix(icons): change contributors, since these are now essentially brand new icons
* fix(prettier): remove path fill from allowed SVG element attributes
* feat(docs): update pull_request_template.md
* Fix link to Lab directory in PR template
Updated link reference for the Lab directory in the pull request template.
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* feat(ci): added custom prettier plugin for icon SVG files
* feat(ci): added custom prettier plugin for icon SVG files
* feat(ci): replace prettier plugin implementation with one based on svgo
* fix(ci): fix linting issues in prettier plugin
* Allow fill in path to fix podcast icon
* Format code
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
* feat(icons): add scan-square
Adds scan-square: a scanning frame with a square detected inside it.
The scan-* family covers what is being detected — scan-face, scan-heart,
scan-text, scan-eye, scan-barcode, scan-qr-code, scan-search, scan-line —
but has nothing for a plain shape or object.
Composed entirely from two existing icons rather than new geometry: the
four corner brackets are scan's, verbatim, and the inner block is
square-square's rect(8,8,8,8) rx=1, verbatim. Nothing here is drawn from
scratch, so it sits in the family without introducing a new vocabulary.
* chore(icons): fill scan-square use-cases and fix recognise/recognize tags
Addresses review on #4550: fills the use-cases field per @ericfennis, and
collapses the duplicate recognise/recognize tags into a single
recognition tag, matching scan-text's vocabulary per @Copilot.
* Update icons/scan-square.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update icons/scan-square.json
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Karsa <contact@karsa.org>
* fix(packages/angular): add more supported attributes for SVG nodes
* fix(packages/angular): use original matcher syntax instead of toMatchInlineSnapshot matcher
---------
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Before submitting an icon request check if it has already been requested. If there is an open request, please add a 👍.
> [!CAUTION]
> New brand logos are **not** allowed, see our official statement: https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md.
>
> Existing brand icons have been phased out. Consider using https://simpleicons.org, which offers purpose-built SVGs that are also on a 24×24px grid.
- type: input
id: name
attributes:
label: Icon name
description: What should this icon depict? For multiple icons, provide a comma-separated list.
validations:
required: true
- type: textarea
id: use-cases
attributes:
label: Use cases
description: Why do you need this icon? Include at least two real-life use cases per requested icon, avoiding generic descriptions like "it's a car icon".
placeholder:e.g. I need a star icon to use in my rating system.
validations:
required:true
- type:textarea
id:design-ideas
attributes:
label:Design ideas
description:What should this icon look like? Provide simple, minimalistic icon examples from other sets or your own drafts to help us visualize your request.
validations:
required:true
- type:checkboxes
id:checklist
attributes:
label:Checklist
description:Please review the following checklist before submitting your request.
options:
- label:I have searched if someone has submitted a similar request before and there weren't any.
required:true
- label:I have searched existing icons to make sure it does not already exist and I didn't find any.
required:true
- label:I am not requesting a brand logo and the art is not protected by copyright, see more at https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md
required:true
- label:I am not requesting an icon that includes religious, war/violence related, political imagery or hate symbols.
required:true
- label:I have provided appropriate use cases for the icon(s) requested.
@@ -13,8 +13,72 @@ The `contributors` property is a required array of GitHub usernames for the peop
The `tags` property is an array of strings that describe the icon and can be used for searching.
Validate the tags against the `icon.schema.json` to ensure they are correctly formatted and adhere to the defined structure.
Provide tag suggestions based on the name of the icon and the use cases provided in the PR description. Use the existing tags in the repository as a reference for consistency and to avoid duplicates. Don't suggest words like: 'icon' and preferably use single words. Tags should always be in lowercase and should not contain spaces. The name of icon should not be included in the tags, as it is already specified.
Provide tag suggestions based on the name of the icon and the use cases provided in the PR description. Use the existing tags in the repository as a reference for consistency and to avoid duplicates. Don't suggest words like: 'icon' and preferably use single words. Tags should always be in lowercase, and may also contain spaces (e.g. `magnifying glass`). Don't include the full icon name, its space-separated form, or any individual part of its kebab-case name because those terms are already searchable. For example, don't suggest `mail-search`, `mail search`, `mail`, or `search` for the `mail-search` icon.
# Categories
## Categories
The `categories` property is an array of strings that specify the categories to which the icon belongs, such as "devices", "interface", "media", etc. See the `categories` property in the `icon.schema.json` for more details on the allowed values. The categories should be chosen based on the use cases provided in the PR description and the existing categories in the repository. The categories should be relevant to the icon and should help users find the icon when searching for specific types of icons. The name of icon should not be included in the categories, as it is already specified. Suggest categories based on the name of the icon and the use cases provided in the PR description. Use the existing categories in the repository as a reference for consistency and to avoid duplicates. Categories should always be in lowercase and should not contain spaces.
## Use Cases
The `use-cases` property is an array of strings that describe the specific scenarios in which the icon would be used. Each use case should be concise and clearly convey the context in which the icon is applicable. Use the existing use cases in the repository as a reference for consistency and to avoid duplicates.
### Writing icon use-cases
A use-case tells a reader **where and why an icon would be used in a real interface**. Each entry should let someone who has never seen the icon understand what it's for.
### Format
- Write each use-case as a short phrase, not a sentence. Start with a present participle verb: *Representing…*, *Indicating…*, *Marking…*, *Showing…*, *Confirming…*, *Toggling…*, *Categorizing…*, *Searching…*.
- Keep it to roughly 4–12 words. One clear idea per entry.
- No trailing period. No leading bullet, number, or dash (the surrounding format supplies that).
- Give each icon 1 or more use-cases, ordered most-common first. More than 4 use-cases are allowed when they are distinct and useful. Prefer fewer strong entries over many weak or repetitive ones.
### Voice
- Write from the interface's perspective, describing the function: "Indicating a low battery charge level" — not the requester's story ("I need an icon that shows…").
- Name the concrete context where useful: *in smart home apps*, *in navigation apps*, *in text editors*, *on maps*. Context is what makes a use-case self-explanatory.
- Be neutral and factual. No first person, no marketing adjectives ("perfect for", "ideal", "beautiful"), no emoji.
### What to exclude
- **The requester's personal narrative.** "I'm building a SvelteKit UI and need…" → drop the framing, keep the function.
- **References to other issues, PRs, or icons by ID.** No "As provided in #1865", "complementary to git-branch-plus", "same as above", "see #2055".
- **Design/implementation chatter.** Bezier offsets, grid alignment, path cuts, "the icon works perfectly" — none of that is a use-case.
- **Restating the icon's name.** For `microchip`, "microchip" is not a use-case; describe what it represents ("Representing processors, chips, or embedded hardware").
- **Links, image tags, emoji, and markdown artifacts.**
- **Meta-commentary.** "Self-explanatory", "lots and lots of use cases", "obvious :)".
### Cross-contamination
When a request covers several icons at once, assign each use-case only to the icon it actually describes. A bullet prefixed with another icon's name belongs to that icon, not this one. Don't let `briefcase-medical`'s meanings leak into `briefcase-business`.
### Variants
Related icons should get **variant-specific** wording, not one shared blurb. `battery-low` → "Indicating a low battery charge level"; `battery-full` → "…full…". `square-arrow-right-enter` → sign in / join; `-exit` → sign out / export. Resist copying the same line across a family.
### Deriving from source material
When mining descriptions, comments, or linked issues:
- Prefer the **stated purpose** over the backstory. Extract the function, discard the anecdote.
- If a source lists genuinely distinct uses, keep them as separate entries; if it repeats one idea five ways, collapse to one.
- Merge an intro line with its bullets ("To represent:" + "pottery" → "Representing pottery").
- If the only signal is noise (a name restatement, a link, "thanks!"), leave the icon without a use-case rather than inventing one.
- Never fabricate a use-case that isn't supported by the icon's meaning or the source.
## Examples
Good:
-`ambulance` → "Directing users to nearby emergency services in navigation apps"
-`calendar-sync` → "Representing recurring events, promotions, or limited-time offers"
-`globe-x` → "Indicating a device or application is offline or unreachable"
-`heading-2` → "Applying a level-2 heading in text editors"
Poor → fixed:
- ~~"I need a firewall icon :-)"~~ → "Representing firewalls and firewall rules on cybersecurity platforms"
- ~~"As above"~~ → "Signifying a deal, agreement, or partnership"
- ~~"microchip"~~ → "Representing processors, chips, or embedded hardware"
- ~~"Same use cases as the other currency symbols, except Turkish lira"~~ → "Displaying prices or amounts in Turkish lira"
Follow these guidelines when writing or editing Lucide documentation, especially Markdown files.
Write for people who are trying to understand a concept, follow a specification, or complete a task. Prioritize clarity, precision, and scannability over personality or decorative prose.
## Be direct and concise
State the important information first. Remove words that do not add meaning.
Prefer short sentences and paragraphs, but do not sacrifice precision just to make text shorter.
**Do:**
> Icons must use a 24 × 24 pixel canvas.
**Don't:**
> When creating a new icon, you should make sure that the canvas you're working with has dimensions of 24 × 24 pixels.
Avoid unnecessary introductions such as:
- "It's important to note that…"
- "Keep in mind that…"
- "As you can see…"
- "In order to…"
- "It should be noted that…"
State the information directly instead.
## Put the rule before the explanation
When documenting a requirement or recommendation, state it before explaining why it exists.
**Do:**
> Keep at least 1 pixel of space between unrelated elements. This prevents shapes from visually merging at small sizes.
**Don't:**
> Because shapes can visually merge at small sizes, it's important to make sure that unrelated elements have enough space between them.
This makes documentation easier to scan and makes normative requirements easier to identify.
## Explain the reason when it adds value
Explain *why* a rule exists when the reasoning helps contributors apply it to situations that are not explicitly documented.
Do not merely restate the rule.
**Do:**
> Avoid simulated fills. They don't scale consistently with the rest of the icon set.
**Don't:**
> Avoid simulated fills because simulated fills should not be used.
Reasoning is particularly useful for design rules where contributors may need to evaluate unusual cases.
## Use scannable structure
Assume readers will scan the page before reading it in detail.
Use:
- descriptive headings
- short paragraphs
- lists for sets of related items
- examples for rules that benefit from demonstration
- **bold** for important terms or short emphasis
- code formatting for filenames, properties, commands, values, and identifiers
Avoid long uninterrupted blocks of text.
Headings should communicate the subject or rule without requiring the surrounding text for context.
**Do:**
> ## Keep 1 pixel of safe space
**Don't:**
> ## Spacing
## Use sentence case
Use sentence case for:
- page titles
- headings
- table headings
- labels
- example captions
Capitalize proper nouns and branded terms normally.
**Do:**
> ## Use consistent corner radii
**Don't:**
> ## Use Consistent Corner Radii
## Address the reader directly
Use **you** and **your** when referring to something the reader does.
**Do:**
> If your icon contains overlapping shapes, simplify the hidden geometry.
Avoid referring to the reader as "the user," "the contributor," or other third-person terms when direct language is more natural.
However, prefer an imperative when the subject is obvious.
**Prefer:**
> Keep related elements visually grouped.
**Over:**
> You should keep related elements visually grouped.
## Use "we" only when it means the Lucide project or maintainers
First-person plural is acceptable when describing an intentional project decision, convention, or policy.
**Do:**
> We use `kebab-case` for icon names.
> We generally avoid adding brand logos to Lucide.
Do not use "we" merely to make documentation conversational.
**Prefer:**
> Icons use a 2 pixel stroke.
**Over:**
> We use a 2 pixel stroke for our icons.
## Use normative language consistently
Use specific language to communicate how strictly a rule applies.
- **must** — required; violating this is not acceptable
- **must not** — prohibited
- **should** — recommended; exceptions may be appropriate
- **should not** — discouraged; exceptions may be appropriate
- **can** — possible or permitted
- **may** — optional or dependent on context
Do not use **should** when something is actually required.
**Do:**
> Icons must use a 24 × 24 pixel canvas.
**Don't:**
> Icons should use a 24 × 24 pixel canvas.
Avoid vague substitutes such as "ideally," "normally," or "preferably" when a more precise normative term applies.
## Prefer active voice
Use active voice unless passive voice makes the subject clearer or avoids unnecessary repetition.
**Do:**
> Align nodes to the pixel grid.
**Don't:**
> Nodes should be aligned to the pixel grid.
Passive voice is acceptable when the actor is irrelevant.
> Deprecated icons are removed in major releases.
## Use positive instructions when possible
Tell readers what to do rather than only what not to do.
**Do:**
> Use a single continuous path when the elements form one continuous shape.
**Less useful:**
> Don't split continuous shapes into unnecessary paths.
Use negative instructions when the prohibition itself is important.
> Don't use simulated fills.
## Be precise about consequences
When explaining why something should or should not be done, describe the actual consequence rather than using vague warnings.
**Do:**
> Keep unrelated elements at least 2 pixels apart. Smaller gaps can disappear when the icon is rendered at small sizes.
**Don't:**
> Be careful when placing elements too close together.
Avoid language that exaggerates consequences or attempts to influence a contributor's decision emotionally.
## Prefer concrete language
Use specific terms instead of vague references.
**Do:**
> The two endpoints must remain inside the 1 pixel safe zone.
**Don't:**
> These should stay within the appropriate area.
Avoid ambiguous references such as:
- this
- that
- it
- things
- stuff
- appropriate
- proper
- correct
when the intended subject can be named directly.
## Introduce terminology before relying on it
Define Lucide-specific or technical terms when readers may not already know them.
Once defined, use the same term consistently.
**Do:**
> The **safe zone** is the 1 pixel area between the icon artwork and the canvas boundary.
Do not alternate between different terms for the same concept unless the distinction is intentional.
For example, don't alternate between "safe zone," "padding," and "margin" if they refer to the same rule.
## Use abbreviations sparingly
Spell out uncommon abbreviations on first use.
> Scalable Vector Graphics (SVG)
Common technical abbreviations such as HTML, CSS, SVG, API, and URL do not need to be expanded when the intended audience can reasonably be expected to know them.
Avoid Latin abbreviations such as:
- e.g.
- i.e.
- etc.
Prefer:
- for example
- that is
- and so on
## Use examples deliberately
Use examples when they clarify how to apply a rule.
Keep examples focused on the rule being demonstrated. Avoid introducing unrelated differences that make the comparison harder to understand.
When contrasting examples, use **Do** and **Don't** consistently.
**Do:**
> Use one path for a continuous outline.
**Don't:**
> Split a continuous outline into several overlapping paths.
The explanatory text should describe the principle, not merely narrate what is visible in the example.
## Use links descriptively
Link text should describe the destination or concept.
**Do:**
> See the [Icon Design Specification](./specification) for exact dimensions and spacing requirements.
**Don't:**
> For more information, [click here](./specification).
Avoid generic link text such as:
- click here
- here
- this page
- learn more
when a descriptive label is possible.
## Avoid unnecessary repetition
Do not repeat information already established by a heading, example, or immediately preceding sentence.
**Prefer:**
> ## Keep 1 pixel of safe space
>
> Keep all artwork within the 22 × 22 pixel live area.
**Over:**
> ## Keep 1 pixel of safe space
>
> When designing an icon, you should keep 1 pixel of safe space around the icon.
Cross-reference another section instead of duplicating detailed rules that already have a canonical explanation.
## Use contractions in prose
Use natural contractions such as:
- don't
- can't
- isn't
- it's
- you'll
They make explanatory prose less formal and easier to scan.
Use uncontracted forms when deliberate emphasis is useful.
> Do not change existing icon geometry solely to reduce the number of SVG nodes.
Normative statements using **must not** should not be contracted.
## Use the serial comma
Use the serial (Oxford) comma in lists of three or more items.
**Do:**
> Check the icon's size, stroke width, and spacing.
**Don't:**
> Check the icon's size, stroke width and spacing.
## Use punctuation normally in prose
Use periods for complete sentences.
Periods may be omitted from:
- headings
- short labels
- short list items that are not complete sentences
- captions consisting only of a short phrase
Be consistent within a list.
If list items are complete sentences, end them with periods. If they are fragments, generally omit periods.
## Skip colons in headings
Do not end headings with colons.
**Do:**
> ## Naming conventions
**Don't:**
> ## Naming conventions:
Use a colon normally when introducing a list or explanation in body text.
## Use exclamation points sparingly
Avoid exclamation points in technical documentation unless the context genuinely calls for excitement or celebration.
**Prefer:**
> Your first icon is ready.
**Over:**
> Your first icon is ready!
Do not use exclamation points to make instructions sound friendlier.
## Use ellipses only when they have meaning
Use an ellipsis (`…`) to represent omitted content or an intentionally incomplete statement.
Do not use ellipses decoratively or to make prose sound conversational.
When documenting literal UI text, preserve the punctuation used by the interface.
## Use parentheses for definitions and compact clarification
Use parentheses when they make a definition, abbreviation, or short clarification easier to understand.
> Scalable Vector Graphics (SVG)
Avoid using parentheses for long side notes. Rewrite important information as part of the sentence or as a separate sentence.
## Prefer "and" over ampersands
Use **and** in normal prose.
**Do:**
> Naming and metadata
**Avoid:**
> Naming & metadata
Use an ampersand only when it is part of an official name, literal UI text, code, or another established term.
## Avoid em dashes
Prefer commas, periods, colons, or parentheses when they produce a simpler sentence.
**Prefer:**
> This rule has one exception: existing legacy icons.
**Avoid:**
> This rule has one exception — existing legacy icons.
Use an en dash (`–`) without surrounding spaces for ranges.
> 1–3 pixels
> A–Z
Do not substitute a hyphen for an en dash in prose ranges unless required by a technical syntax.
## Use hyphens correctly
Hyphenate compound modifiers when necessary for clarity.
> 24 × 24 pixel canvas
> 2-pixel-wide gap
> pixel-aligned element
Do not hyphenate a phrase when it functions as a verb.
> Sign off on the design.
> Complete the sign-off.
Do not add hyphens mechanically when the meaning is already clear.
## Use code formatting consistently
Use backticks for literal technical values and identifiers, including:
- filenames and paths
- commands
- package names
- properties and attributes
- icon names
- code values
- SVG elements and attributes
**Do:**
> Add `camera-off` as an alias.
> Set `stroke-width` to `2`.
> Edit `icons/camera.svg`.
Do not use code formatting merely for emphasis.
## Use bold for semantic emphasis
Use **bold** sparingly to highlight a term or distinction that helps readers scan the page.
Do not bold entire sentences or paragraphs.
Prefer bold over italics for general emphasis.
Use *italics* only when conventional, such as when referring to a term as a term or when a specific distinction benefits from it.
## Don't use all caps for emphasis
Do not use blocks of uppercase text for emphasis.
**Don't:**
> NEVER place nodes outside the canvas.
**Do:**
> **Never** place nodes outside the canvas.
Preserve capitalization when documenting literal identifiers or established technical terms.
## Keep lists parallel
Items in the same list should use the same grammatical structure.
**Do:**
- Use a 24 × 24 pixel canvas
- Keep 1 pixel of safe space
- Use a 2 pixel stroke
- Align nodes to the pixel grid
**Don't:**
- Use a 24 × 24 pixel canvas
- Safe space should be 1 pixel
- A 2 pixel stroke
- Nodes are aligned to the pixel grid
Parallel structure makes rules easier to scan and compare.
## Avoid unnecessary filler and enthusiasm
Lucide documentation should sound helpful and confident, not promotional.
Avoid filler such as:
- "Simply…"
- "Just…"
- "Obviously…"
- "Of course…"
- "Easy…"
- "Luckily…"
- "Don't worry…"
These words can be inaccurate or dismissive when the task is not simple for the reader.
Also avoid marketing language such as:
- "powerful"
- "seamless"
- "effortless"
- "amazing"
- "best-in-class"
unless the word communicates a specific, verifiable distinction.
## Prefer timeless documentation
Avoid wording tied unnecessarily to the current state of development.
**Prefer:**
> Lucide supports custom icon aliases.
**Avoid:**
> Lucide now supports custom icon aliases.
Use time-sensitive language only when the timing itself matters, such as migration notes, deprecations, or release documentation.
## Preserve established Lucide terminology
When editing existing documentation, preserve established Lucide terminology and naming conventions unless there is a clear reason to change them.
Do not invent synonyms merely to avoid repetition. Consistency is more important than stylistic variety in technical documentation.
When terminology differs between the Lucide codebase, API, UI, and documentation, prefer the term used by the relevant canonical specification.
@@ -47,7 +47,9 @@ Common scopes: icons, docs, studio, site, dev
### Design <!-- ONLY for new icons -->
<!-- All of these requirements must be fulfilled. -->
- [ ] I've read and followed the [icon design guidelines](https://lucide.dev/contribute/icon-design-guide)
- [ ] I've made sure that the icons don't [already exist](https://lucide.dev/icons), including the [Lab directory](https://github.com/lucide-icons/lucide/tree/main/lab).
- [ ] I've made sure that the icons look sharp on low DPI displays.
- [ ] I've made sure that the icons look consistent with the icon set in size, optical volume and density.
- [ ] I've made sure that the icons are visually centered.
COMMENT_BODY="It looks like this request is about **${VALUE}**, which is a brand logo.
Lucide **does not accept** brand logos, and we do not plan to add them in the future. This is due to a combination of **legal restrictions**, **design consistency concerns**, and **practical maintenance reasons**.
[Click here to read our official statement about brand logos in Lucide.](https://github.com/lucide-icons/lucide/blob/main/BRAND_LOGOS_STATEMENT.md)
You can [search for similar discussions.](https://github.com/lucide-icons/lucide/discussions/categories/icon-design?discussions_q=category%253A%22Icon+design%22+${URL_ENCODED_VALUE})
We’re always happy to help on [Discord](https://discord.gg/EH6nSts)."
@@ -30,7 +30,7 @@ Read it here: [ICON_GUIDELINES](https://lucide.dev/contribute/icon-design-guide)
#### Lucide Studio
For formatting and adjusting SVG icons, [@jguddas](https://github.com/jguddas) made a great tool called [Lucide Studio](https://studio.lucide.dev/). It is a web-based SVG editor that allows you to edit and adjust icons in the Lucide style. You can use it to create new icons or modify existing ones.
For formatting and adjusting SVG icons, [@jguddas](https://github.com/jguddas) made a great tool called [Lucide Studio](https://studio.lucide.dev/?utm_source=lucide.dev&utm_medium=contributing-guide). It is a web-based SVG editor that allows you to edit and adjust icons in the Lucide style. You can use it to create new icons or modify existing ones.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.