A growing open-source icon library on a single 24×24 grid.
Four weights · tree-shakeable React components · MIT
The packages are not on npm yet — the first release is coming. Until then the whole set can be downloaded from the catalog, or used through the Figma plugin and the MCP server below.
npm i luceviasimport { Basket } from 'lucevias'
<Basket size={24} />Every icon is a component named after the icon in PascalCase — address-book
becomes AddressBook. The catalog shows the exact name for each one.
| Prop | Type | Default | Description |
|---|---|---|---|
size |
number | string |
24 |
Side of the square, in pixels |
color |
string |
currentColor |
Stroke and fill color |
weight |
'thin' | 'light' | 'regular' | 'bold' |
'regular' |
Line weight |
Anything else is forwarded to the <svg> element, so className, onClick,
aria-label, ref and the rest work as expected.
Icons are painted in currentColor, so they inherit the color of their
container — no prop needed for the common case:
<button className="text-red-500">
<Basket size={20} />
Remove
</button><Basket weight="thin" />
<Basket weight="light" />
<Basket /> {/* regular */}
<Basket weight="bold" />A weight that has not been drawn yet falls back to regular instead of
rendering nothing.
Ask for an icon in your own words and the agent writes the import for you — picking from the real library instead of inventing a name that does not exist.
claude mcp add lucevias -- npx -y @lucevias/mcpYou: add a basket icon to the header
Agent: searches the set, finds
basket, writes:import { Basket } from 'lucevias' <Basket size={24} />
An MCP server ships with the set and gives the agent three tools:
| Tool | What it does |
|---|---|
search_icons |
Finds icons by name and tags — returns the names that exist |
get_icon |
Returns one icon: React, HTML and raw SVG, in any weight and size |
list_categories |
Lists the categories, for when a whole group is needed |
A wrong name is answered rather than refused: a typo (basekt) comes back with
did_you_mean: ["basket"], and a name that is not in the set at all
(shopping-cart) comes back with what is — bag, basket.
The server reads the same metadata as everything else here, so an icon added to the set is available to the agent with the next release.
Cursor, Claude Desktop, VS Code and other clients
Any MCP client runs the same command. For the config-file ones:
{
"mcpServers": {
"lucevias": {
"command": "npx",
"args": ["-y", "@lucevias/mcp"]
}
}
}- Cursor —
.cursor/mcp.jsonin the project, or~/.cursor/mcp.jsonglobally - Claude Desktop —
claude_desktop_config.json(Settings → Developer → Edit Config) - VS Code —
.vscode/mcp.json, withserversinstead ofmcpServers
Full documentation in packages/mcp.
The Lucevias Icons plugin puts the same set inside Figma: search, filter by category, switch the weight, click to insert as an editable vector.
It reads the icons straight from this repository, so new ones appear in the plugin as soon as they are drawn — no plugin update required.
|
Raw SVG and metadata npm i @lucevias/coreimport { icons } from '@lucevias/core/icons.json'For custom bindings, your own catalog, or a design-tool plugin. See packages/core. |
A single file Every icon can also be copied straight from the catalog as SVG, PNG or JSX — or the whole set downloaded as a zip. |
| Package | Contents | Who installs it |
|---|---|---|
lucevias |
React components generated from the SVGs | Application developers |
@lucevias/core |
Raw SVGs and icons.json metadata |
Custom bindings, catalogs, plugins |
@lucevias/mcp |
MCP server over the same metadata | Anyone coding with an AI agent |
All three are published from this repository under one version.
Importing one icon costs about 9 KB, not the whole library. Every generated
component is marked /* #__PURE__ */ — without it a bundler treats the
forwardRef call as a side effect and keeps all of them, which is the
difference between 9 KB and 185 KB.
Nothing to configure: any modern bundler (Vite, webpack 5, Rollup, esbuild) drops the unused ones on its own.
Icons live in packages/core/svg/ — a folder per icon, a file per weight:
packages/core/svg/basket/
Thin.svg Light.svg Regular.svg Bold.svg
Drop an .svg in and every package picks it up on the next build; no code
changes needed. Files are expected on a 24×24 grid, with strokes that the build
normalizes to currentColor.
npm install
npm run icons:check # names, weights, categories, duplicates
npm run core:build # generate packages/core/assets/icons.json
npm run pkg:build # generate and build the React package
npm run build # both
npm run icons:optimize # run SVGO over the icon foldericons:check catches what the build is happy to swallow: a misnamed weight
file, an icon with no category, a drawing exported twice. Every one of those has
happened at least once. CI runs it on every push.
The full guide is in CONTRIBUTING.md; what landed when is in CHANGELOG.md.
The parsing of names, weights and viewBox lives in one place —
scripts/svg-source.mjs — and both generators import it. These rules used to be
duplicated and drifted apart, so please do not start a third copy.
The reasoning behind each decision is kept in the comments next to the code rather than in a separate document, so it stays true when the code changes.
git tag v0.3.0 && git push --tagsThe version from the tag is applied to all three packages, which are published to
npm in dependency order. Requires the NPM_TOKEN secret.
The set is drawn by one person and given away for free. Nothing here is behind a paywall and nothing will be — supporting the work only makes the next batch arrive sooner.
Patreon — any amount, monthly or one-off.
Or directly, without a middleman:
Ethereum (ETH, USDT and any ERC-20)
0xf33b7bfd2314ba3eBBf3CacF01BA2F0711fe6691
Starring the repository or telling someone about it helps just as much.
MIT — free to use, including commercially.