Building FeaturedDrop: Feature Announcements That Don't Suck
Why I built FeaturedDrop, a lightweight library for in-app feature announcements and changelog drops.
Gagan Deep Singh
Founder | GLINR Studios
Every app needs a "what's new" moment
You ship a feature. You are excited about it. Your users have no idea it exists.
This happens constantly. You build something useful, deploy it, and then hope people stumble into it. Maybe you write a blog post. Maybe you add a line to your changelog. Most users will never see either of those.
What actually works is showing people the update right inside the app, at the moment they are using it. A small, tasteful announcement that says "hey, we built this for you." That is what FeaturedDrop does.
What FeaturedDrop is
FeaturedDrop is a lightweight library for in-app feature announcements. You define your drops, pick when they show, and the library handles the rest. Rendering, dismissal, persistence, all of it.
No iframe embeds. No third-party dashboard. No monthly fee. Just a package you install and own.
npm install featuredropHow it works
You define a drop with a title, description, and optional actions. Then you render it wherever makes sense in your app.
import { FeaturedDrop, Drop } from 'featuredrop';
const drops: Drop[] = [
{
id: 'dark-mode-v2',
title: 'Dark Mode, Redesigned',
description: 'We rebuilt dark mode from scratch. New contrast ratios, new palette, easier on the eyes.',
action: {
label: 'Try it',
href: '/settings/appearance',
},
publishedAt: '2026-03-10',
},
];
function App() {
return (
<FeaturedDrop
drops={drops}
position="bottom-right"
onDismiss={(id) => console.log(`Dismissed: ${id}`)}
/>
);
}That is it. The component appears for new drops, users can read and dismiss them, and dismissed state is persisted in localStorage so they do not see the same announcement twice.
Design philosophy
I had a few non-negotiable goals when building this.
Zero dependencies. FeaturedDrop has no runtime dependencies beyond React as a peer dependency. No animation libraries, no state management tools, no CSS-in-JS frameworks hiding in the bundle. The entire thing is a few kilobytes.
Customizable without fighting. The default styles look good out of the box, but every element accepts className props. If you use Tailwind, you can restyle the entire component without ejecting or overriding CSS specificity chains.
<FeaturedDrop
drops={drops}
className="rounded-xl shadow-2xl"
titleClassName="text-lg font-bold"
descriptionClassName="text-sm text-muted-foreground"
/>Controlled or uncontrolled. You can let FeaturedDrop manage its own state with localStorage, or you can control everything yourself. Pass your own isVisible and onDismiss handlers if you want to sync dismissal state with your backend or analytics.
Positioning that makes sense. The component supports multiple positions and stays out of the way of your main content.
Why not just use a toast library?
I tried that. Toast libraries are designed for transient messages. They pop up, they disappear, they are gone. Feature announcements are different. You want them to persist until the user actively dismisses them. You want to track which announcements a user has seen. You want the content to be richer than a single line of text.
FeaturedDrop is purpose-built for this specific use case. It is not trying to replace your toast library. It is the thing you reach for when "new feature shipped" needs more than a 3-second notification.
The small details
A few things I spent time on that might not be obvious:
Ordering. Drops render in publishedAt order, newest first. If a user has three unread drops, they see the most recent one with a count indicator.
Animations. Entry and exit animations are CSS-only. No JavaScript animation runtime. They respect prefers-reduced-motion automatically.
TypeScript first. Every prop, every drop shape, every callback is fully typed. Your editor knows exactly what you can pass and what you get back.
SSR safe. The component checks for window before touching localStorage. It works with Next.js, Remix, Astro, and any other SSR framework without hydration mismatches.
Try it out
- Site: featuredrop.dev
- GitHub: github.com/GLINCKER/featuredrop
- npm:
npm install featuredrop
If your app ships features and your users do not know about them, give FeaturedDrop a look. It is free, it is small, and it solves a real problem.