There’s no first-class integration for . But making a custom one isn’t too hard. Lucide Astro This is the component I made to do the job: --- const { icon, ...props } = Astro.props; const [, attributes, children] = icon; const componentChildren = children ?.map( ([shape, attributes]) => `<${shape} ${Object.entries(attributes) .map(([k, v]) => `${k}="${v}"`) .join(" ")} />` ) .join(""); const componentAttributes = {...attributes, ...props} --- <svg {...componentAttributes} set:html={componentChildren} /> If this component looks reasonable to you, copy it and go forth. If you’d like to learn how it works, let’s get it! Our goal For this build, our goal is to render icons directly into an Astro site — converting Lucide’s JSON files to inline s at build time. <svg> This — the one that fits my needs best. is just one of many ways to add Lucide icons to a site Initial setup Add the package. lucide pnpm install lucide In the standard package, icons are exported as JSON arrays with the following contents: lucide : : element attributes : children [0] "svg" [1] [2] [ "svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": 2, "stroke-linecap": "round", "stroke-linejoin": "round", }, [ ["circle", [Object]], ["path", [Object]], ["path", [Object]], ["path", [Object]], ["path", [Object]], ], ]; We need to import these JSON files and render their data as . HTML Render a single icon To render a single Lucide icon: Import any icon lucide Destructure and array items from that icon attributes children Reduce children nodes to HTML string Render an component <svg> Spread directly on the element attributes Apply with the directive childElements set:html --- // 1. Import any `lucide` icon import { Accessibility } from "lucide"; // 2. Destructure the `attributes` and `children` array items const [, attributes, children] = Accessibility; // 3. Reduce children nodes to HTML string const componentChildren = children ?.map( ([child, attributes]) => `<${child} ${Object.entries(attributes) .map(([k, v]) => `${k}="${v}"`) .join(" ")} />` ) .join("\n"); --- <!-- 4. render svg element --> <svg {/* 4.1. Spread `attributes` directly on the element */} {...attributes} {/* 4.2. Apply `childElements` with the `set:html` directive */} set:html={childrenElements} /> Extract component LucideIcon Now that we can render icons let’s extract this code as a reusable component. Move the relevant code to src/components/lucide-icon.astro Refactor to as a prop icon Take rest so HTML and SVG attributes can be applied at the call site ...props Merge icon and component attributes props Apply munged attributes-props to exported element svg --- // 1. Take `icon` as a prop // 2. Take rest `props` - import { Accessibility } from "lucide"; + const { icon, ...props } = Astro.props; const componentChildren = children ?.map( ([child, attributes]) => `<${child} ${Object.entries(attributes) .map(([k, v]) => `${k}="${v}"`) .join(" ")} />` ) .join("\n"); // 3. Merge `attributes` and `props` + const componentAttributes = {...attributes, ...props} --- <svg {/* 4. Apply munged `componentAttributes` to svg */} - {...attributes} + {...componentAttributes} set:html={childrenElements} /> Use the component LucideIcon To use our new component, import it along with any icon. Provide the icon JSON to using the prop. LucideIcon lucide LucideIcon icon --- import LucideIcon from "@components/lucide-icon.astro"; import { Accessibility } from "lucide"; --- <LucideIcon icon={Accessibility} /> Apply attributes to LucideIcon The receives props that it merges with the default values. Use these to change SVG attributes like , , , and . Or apply common attributes like and . LucideIcon lucide height width fill stroke-width class id --- import LucideIcon from "@components/lucide-icon.astro"; import { Accessibility } from "lucide"; --- <LucideIcon icon={Accessibility} width="56" height="56" stroke-width="4" /> Taking it further My preference is to keep icon importing and SVG rendering separated. But you may find this cumbersome. If so, create a facade for that exposes your favorite icons via interface. LucideIcon string This could look something like this: --- import { Github as github, Youtube as youtube, Twitter as twitter, Instagram as instagram } from "lucide"; const icons = { github, youtube, twitter, instagram } const { name = "github", ...props } = Astro.props; if !(icons[name]) { return null } const [, attributes, children] = icons[name]; const componentChildren = children ?.map( ([child, attributes]) => `<${child} ${Object.entries(attributes) .map(([k, v]) => `${k}="${v}"`) .join(" ")} />` ) .join("\n"); const componentAttributes = {...attributes, ...props} --- <svg {...componentAttributes} set:html={childrenElements} /> Go further with TypeScript does not expose its type for external use. lucide IconNode So, if you want to use in TypeScript, you’ll need to get clever. my code above Import just the type of any component. Infer the for that icon in the type declaration. IconNode LucideIcon Add any optional attributes you’d like to support. (e.g., , , , , etc.) svg height width fill stroke-width src/components/lucide-icon.astro --- // 1. Import just the type of any component. import type { Accessibility } from "lucide"; type Props = { // 2. Infer the `IconNode` for that icon in the `LucideIcon` type declaration icon: typeof Accessibility; }; --- That’s it! I hope that you found this useful in building an Astro site. If you’d like to see more Astro tips and tricks, bug me on Twitter/X or Discord. 😄