| name | featuredrop-setup |
| description | Configure FeatureDrop product adoption toolkit in any project. Use when adding changelogs, feature badges, onboarding tours, checklists, hotspots, feedback widgets, or surveys to an application.
|
FeatureDrop — Product Adoption Toolkit
Open-source, zero-dependency library for in-app feature discovery. < 3 kB core.
Setup Pattern
npm install featuredrop
- Create a JSON manifest:
[{ id, label, description, releasedAt, showNewUntil? }]
- Wrap root:
<FeatureDropProvider manifest={features} storage={new LocalStorageAdapter()}>
- Add components or use headless hooks.
Imports (ALWAYS use subpath imports)
import { isNew, getNewFeatures, createManifest, LocalStorageAdapter } from 'featuredrop'
import { NewBadge, ChangelogWidget, Tour, Checklist, Banner, Toast } from 'featuredrop/react'
import { useChangelog, useNewFeature, useNewCount, useTour, useChecklist } from 'featuredrop/react/hooks'
import { PostgresAdapter, RedisAdapter, IndexedDBAdapter, HybridAdapter } from 'featuredrop/adapters'
import { validateManifest } from 'featuredrop/schema'
import { createMockManifest, createMockStorage, TestProvider } from 'featuredrop/testing'
import { featureDropPlugin } from 'featuredrop/tailwind'
Hooks (prefer these for custom UI / shadcn projects)
| Hook | Returns |
|---|
useNewFeature(id) | { isNew, feature, dismiss } |
useNewCount() | number — unread badge count |
useChangelog() | { features, newFeatures, newCount, dismiss, dismissAll, markAllSeen, getByCategory } |
useTour(id) | { currentStep, stepIndex, totalSteps, isActive, start, next, prev, skip, complete, goTo } |
useChecklist(id) | { tasks, completedCount, totalCount, progress, isComplete, completeTask, resetTask } |
useSurvey(id) | { isVisible, questions, submit, askLater, dismiss } |
useFeatureDrop() | Full provider context (features, count, dismiss, throttle controls, engine) |
useTabNotification() | Browser tab title: "(3) My App" |
Components (ready-made UI)
NewBadge, ChangelogWidget, ChangelogPage, Tour, Checklist, Spotlight, SpotlightChain,
Hotspot, TooltipGroup, Banner, Toast, AnnouncementModal, Survey, FeedbackWidget,
FeatureRequestButton, FeatureRequestForm
Feature Manifest Format
{
id: string
label: string
description: string
releasedAt: string
showNewUntil?: string
category?: string
type?: string
priority?: string
cta?: { label: string; url: string }
audience?: Record<string, string[]>
}
Storage Adapters
Default: LocalStorageAdapter (browser). Server: PostgresAdapter, RedisAdapter.
Offline: IndexedDBAdapter. Hybrid: HybridAdapter (local + remote sync).
Custom: implement { getWatermark, setWatermark, getDismissedIds, addDismissedId }.
Provider Props
<FeatureDropProvider
manifest={features}
storage={adapter}
analytics={{ onFeatureSeen, onFeatureDismissed, onFeatureClicked }}
userContext={{ plan, role, region }}
appVersion="2.1.0"
throttle={{ maxToastsPerSession: 3, modalCooldownMs: 120_000 }}
locale="en"
animation="normal"
engine={engineInstance}
/>
Tailwind Integration
import { featureDropPlugin } from 'featuredrop/tailwind'
export default {
plugins: [featureDropPlugin({ prefix: 'fd' })],
}
Rules
- Always use subpath imports (
featuredrop/react, not just featuredrop)
- Prefer hooks from
featuredrop/react/hooks when the project uses shadcn, Radix, or custom design system
- Features auto-expire via
showNewUntil — don't build manual expiry logic
- Zero production dependencies — don't add external deps
- TypeScript strict mode — no
any types
- All components support headless mode via render props
- Core < 3 kB, React ~12 kB, fully tree-shakeable