React Icon Button
React icon button with particle burst and glow effects on activation. Lucide icons with smooth animations, TypeScript support, and shadcn/ui styling.
Powered by
Building icon-based interactions?
Join our Discord community for help from other developers.
Icon buttons are everywhere—like buttons, favorite stars, bookmark icons. But most are just static SVGs that change color on click. Boring. No feedback. No delight. Meanwhile, users expect that Instagram-style heart explosion or Twitter's star burst. This React component gives you particle explosions, glow effects, and smooth animations that make every click feel special.
Particle burst on activation
Click to trigger particle explosions and glow effects with smooth spring animations:
Built for React applications with TypeScript and Next.js. Works with any Lucide icon—hearts, stars, bookmarks, thumbs up, you name it. The particle burst uses Framer Motion for physics-based animations that feel natural. RGB color system lets you match any brand. Works seamlessly with shadcn/ui design systems.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/icon-button.json
npx shadcn@latest add https://www.shadcn.io/registry/icon-button.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/icon-button.json
bunx shadcn@latest add https://www.shadcn.io/registry/icon-button.json
Usage
import { IconButton } from "@/components/ui/icon-button";
import { Heart, Star, Bookmark, ThumbsUp } from "lucide-react";
export default function SocialActions() {
const [liked, setLiked] = useState(false);
const [starred, setStarred] = useState(false);
return (
<div className="flex gap-4">
{/* Heart with red particles */}
<IconButton
icon={Heart}
active={liked}
color={[239, 68, 68]} // red-500
onClick={() => setLiked(!liked)}
size="md"
/>
{/* Star with golden particles */}
<IconButton
icon={Star}
active={starred}
color={[251, 191, 36]} // amber-400
onClick={() => setStarred(!starred)}
animate={true}
/>
{/* Bookmark without animations */}
<IconButton
icon={Bookmark}
active={bookmarked}
color={[59, 130, 246]} // blue-500
animate={false} // No particles, just color change
/>
</div>
);
}
Why most icon buttons are lifeless
Developers just toggle a fill color and call it done. Or they add a weak scale animation that nobody notices. The problem? Users are conditioned by social media to expect visual rewards. That heart should explode. That star should burst. These micro-delights trigger dopamine and keep users engaged.
This React component handles the complex animation orchestration: particle physics, glow effects, color transitions, and spring animations. The particles aren't random—they burst outward with physics-based trajectories. The glow pulses with perfect timing. It's the difference between a button that functions and one that delights.
Plus, the RGB color system means you're not locked into preset colors. Match your brand exactly. Create custom themes. Change colors dynamically based on state.
Examples
Different Icons & Colors
Popular icon combinations with matching particle colors:
Size Variants
Four sizes optimized for different UI contexts and touch targets:
Features
- Particle burst animations with physics-based trajectories and customizable colors
- Radial glow effects pulsing outward from the icon center on activation
- Any Lucide icon support with automatic sizing and consistent styling
- RGB color system for exact brand matching and dynamic theming
- Four size presets optimized for different UI densities and touch targets
- Smooth spring animations for natural press and release interactions
- TypeScript definitions with complete prop types and Lucide icon compatibility
- Controlled animation toggle allowing static or animated state changes
- Accessible button semantics with proper ARIA attributes and keyboard support
API Reference
IconButton
The main component for animated icon button interactions.
Prop | Type | Default | Description |
---|---|---|---|
icon | React.ElementType | required | Any Lucide React icon component |
active | boolean | false | Current activation state |
animate | boolean | true | Enable particle and glow animations |
size | "sm" | "default" | "md" | "lg" | "default" | Button and icon size preset |
color | [number, number, number] | [59, 130, 246] | RGB color values for theme |
transition | Transition | { type: "spring", stiffness: 300, damping: 15 } | Spring animation config |
onClick | () => void | - | Click handler for state changes |
className | string | - | Additional CSS classes |
...props | ButtonHTMLAttributes | - | All native button props supported |
Size Specifications
Each size is optimized for specific use cases:
Size | Button | Icon | Touch Target | Use Case |
---|---|---|---|---|
sm | 24px | 16px | 44px padded | Inline actions, dense UI |
default | 32px | 20px | 44px | Standard interactions |
md | 40px | 24px | 48px | Mobile-first, touch UI |
lg | 48px | 28px | 56px | Hero sections, CTAs |
Color System
RGB arrays for precise color control:
// Popular color combinations
const colors = {
red: [239, 68, 68], // red-500
pink: [236, 72, 153], // pink-500
orange: [249, 115, 22], // orange-500
amber: [251, 191, 36], // amber-400
yellow: [250, 204, 21], // yellow-400
green: [34, 197, 94], // green-500
blue: [59, 130, 246], // blue-500
purple: [168, 85, 247], // purple-500
gray: [107, 114, 128], // gray-500
};
Common gotchas
Particle performance on mobile: The particle burst creates multiple DOM elements. On low-end devices with many buttons, consider disabling animations (animate={false}
) or reducing particle count in the component.
Touch target sizing: Even the sm
size maintains a 44px touch target through padding. Don't override this with custom styles—it's there for accessibility.
Color array format: Colors must be RGB arrays, not hex strings or CSS colors. Convert hex to RGB: #ef4444
becomes [239, 68, 68]
. There are online converters if needed.
Icon import requirements: Icons must be imported from lucide-react, not inlined SVGs. The component expects Lucide's consistent props interface for proper sizing.
Active state management: The component doesn't manage state internally. You must track active
state and update it in the onClick handler. This gives you full control but requires state setup.
Animation cleanup: Rapidly clicking can create multiple particle bursts. The component handles cleanup, but very fast clicking might cause visual overlap. This is intentional for enthusiastic users.
You might also like
Explore other interactive button components for React applications:
GitHub Stars Button
Display repository stars with animated counting
Ripple Button
Material Design ripple effects from click position
Liquid Button
Fluid fill animations that flow on interaction
Copy Button
One-click clipboard copying with visual feedback
Questions developers actually ask
React GitHub Stars Button
React GitHub stars button with live API counts and particle effects. Social proof component with animated transitions, TypeScript, and shadcn/ui styling.
React Input Button
React input button that transforms into input field with smooth transitions. Framer Motion animations and compound patterns with TypeScript and shadcn/ui.