lucide
lucide copied to clipboard
Change icon import names to have a prefix e.g. <LucideCamera />
It's not all the time I run into this issue but I often find myself having to use different icons or renaming components within React projects so that they don't clash with the imports.
E.g. if I want to use <Login />
Lucide icon but I have a <Login />
functional component.
A suggestion would be to prefix the imports so <Camera />
would become <LcCamera />
or similar.
Hmm, I understand the issue. I think it is a bit hard to change. Because it is a breaking change for everyone. But we are thinking of adding aliases in the future, maybe we can think of a solution as well.
It would be a nice solution to have multiple names for the same export but I can't think of a nice way to do this without module / function duplication.
I disagree with this suggestion. Renaming imports is trivial and more flexible than introducing some arbitrary prefix that would be a breaking change.
Assuming you're using Typescript/Javascript, a suggestion for how to handle it could for instance be to create something like components/icons/index.[ts|js]
and do
export {
Camera as CameraIcon,
LogIn as LoginIcon,
// and whatever other icons you need with whatever pre-/postfix you prefer
} from "lucide-react";
They may then be imported as import { CameraIcon } from "/components/icons"
.
I can agree with you that this would work.
It is a workaround however, not a solution.
There needs to be a bigger change here to prevent collisions?
On Mon, 24 Oct 2022, 08:48 Erik André Jakobsen, @.***> wrote:
I disagree with this suggestion. Renaming imports is trivial and more flexible than introducing some arbitrary prefix that would be a breaking change.
Assuming you're using Typescript/Javascript, a suggestion for how to handle it could for instance be to create something like components/icons/index.[ts|js] and do
export { Camera as CameraIcon, LogIn as LoginIcon, // and whatever other icons you need with whatever pre-/postfix you prefer} from "lucide-react";
They may then be imported as import { CameraIcon } from "/components/icons".
— Reply to this email directly, view it on GitHub https://github.com/lucide-icons/lucide/issues/806#issuecomment-1288564198, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWYSVGKHEZDQBB6PSWRHEYLWEY5NPANCNFSM6AAAAAAQ7MAGVU . You are receiving this because you authored the thread.Message ID: @.***>
Another way you could do it is to import as
import * as Lucide from "lucide-react";
and then render components as
<Lucide.Camera />
I think namespacing imports properly should be the responsibility of the app developer, not the library developer, and therefore disagree that this is something that needs a solution from Lucide's or @ericfennis' end.
We have a plan to support aliases in all our packages that uses lucide icons as components.
I was thinking to add an aliases.js file with all the icons aliases. and export them in the main index.ts.
import { Camera } from "lucide-react";
or `import { CameraIcon } from "lucide-react"; will lead to the same icon file. This only will working nicely with ESModules.
If you want to have all the icons you can then still do import * as icons from "lucide-react/icons";
But importing icons this way is not recommended and bad practice if you are bundeling your application for browsers. This way of importing breaks the tree-shaking ability in bundlers. So your bundled app will include all 800+ icons.
import {CameraIcon} from "lucide-react";
would be ideal imo.
Will aliases like you mention above also be added to other language packages like Svelte and Vue? And would it still cause issues if I had a local component named Camera
?
For example:
import {Camera} from "./src/CustomButtons"
@Snailedlt yess, we want to implement it in all packages.
@ericfennis Neat! What about my second question?
And would it still cause issues if I had a local component named
Camera
? For example:import {Camera} from "./src/CustomButtons"
We have a plan to support aliases in all our packages that uses lucide icons as components. I was thinking to add an aliases.js file with all the icons aliases. and export them in the main index.ts.
import { Camera } from "lucide-react";
or `import { CameraIcon } from "lucide-react"; will lead to the same icon file. This only will working nicely with ESModules.If you want to have all the icons you can then still do
import * as icons from "lucide-react/icons";
But importing icons this way is not recommended and bad practice if you are bundeling your application for browsers. This way of importing breaks the tree-shaking ability in bundlers. So your bundled app will include all 800+ icons.
I can understand where some may think this is the responsibility of the developer, your application, your job sort of thing.
On the other side, packages are meant to make life simpler, without having to make unecessary accommodations, whilst also maintaining a small bundle size.
I raised this issue initially, and although biased, I do think it's the best approach to just simply rename them completely and announce a breaking change.
Maintaining an aliases.js
would work, but adds more room for potentially forgetting an icon and it not being supported with that naming convention.
I'd propose to simply change the naming to LucideCamera
or LICamera
.
https://react-icons.github.io/react-icons/icons?name=fi React icons has this exact setup, although it's due to it having multiple icon packages and it needs to distinguish between them, it does work really well.
@jakobsen I completely agree. Maintaining aliases.js is not a problem. I already started on this feature in #899. The aliases file is completely rendered on build time so no SVG icon will be missed that is in the icons directory.
I did already some tests and it works great. You can import each icon in three ways:
import { Camera } from 'lucide-{packageName}'
import { LucideCamera } from 'lucide-{packageName}'
`import { CameraIcon } from 'lucide-{packageName}'
It will point all to the same module. So tree-shaking is still working.
See the linked draft PR #899
This is still not ideal IMO as the icons pollute the component name scope quite a bit. For example if I want to import the NextJS Link component, the IDE automatically suggests Link icon from Lucide which is not ideal.
@piotrkulpinski: I'm afraid for the time being the old, unprefixed names will have be kept for backwards compatibility, although I do agree that using a prefixed version from the start would have been ideal. Maybe we can drop the unprefixed names in v1.0.
This is IMO a ts-server issue now.
https://github.com/microsoft/TypeScript/issues/51155
@jguddas solving it in ts-server is super super complex though.
I would love to see prefixes. Ideally we can have prefixed react components in a separate package like
import { LucideCamera } from 'lucide-react/prefixed'
? Introducing it like this would not break anyone's existing code.
@capaj We do already have prefixed components, the issue is no longer with that, but dropping support for the unprefixed ones.
@karsa-mistmere what do you mean? Where? I may be stupid, but I don't see how to import them with a prefix. Are you suggesting I use https://lucide.dev/guide/packages/lucide-react#one-generic-icon-component
? I could, but I don't like that solution, because I bundle with Vite and it would force all the icons into my bundle.
I'm not quite sure what generic components have to do with prefixed component names.
This issue has to do with adding prefixes to icon component names, which has already been implemented via alias exports, e.g. in lucide-react
ArrowUpSquare
is exported as both ArrowUpSquare
and ArrowUpSquareIcon
as well as LucideArrowUpSquare
.
E.g. you can easily use
import { LucideCamera } from 'lucide-react';
instead of
import { Camera } from 'lucide-react';
Thanks!
I was just trying it wrong
I think we should write something about these prefixes and suffixes in our documentation.
Adding my two cents here: For the following:
<Link>
I always end up with the following import:
import { Link } from 'lucide-react';
Instead I am always in need for this one:
import Link from 'next/link';
And I guess there a re more conflicts like this. Because Lucid has the alias with *Icon
I always use icons like this:
<LinkIcon />
Then it gets the import right for obvious reasons. However, I would also like to avoid it the other way around as mentioned above. I know it's a breaking change, but what if Lucide would only enable *Icon
, e.g. LinkIcon
imports (so not exporting the Link
equivalent from the library)? It would not only solve the auto import issue, but also make things more explicit in code, because there would be no mental overhead on first sight anymore.
I think prefixes are better than suffixes. Also prefix 'Lucide' is better than 'Icon'. If you have multiple icon packs in your codebase lucide prefix makes it perfectly clear what you're working with.
Agreed. I think my suggestion was more towards removing the exports in Lucid that do not have a prefix/suffix, such as Link
.
Thanks for your view on this! We have a related discussion in #1830. I've also written a proposal in #1830, so let me know what you think.