DEV Community

Cover image for FeatureDrop v3 — Your App Now Decides When and How to Show Features
GDS K S
GDS K S

Posted on

FeatureDrop v3 — Your App Now Decides When and How to Show Features

GitHub | Docs | npm | shadcn Components | Example App


Every product adoption tool — Pendo, Appcues, Chameleon — works the same way: collect weeks of server-side analytics, then tell you which users to nudge. They charge $250–$7,000/month for it.

We built a 4 kB client-side engine that makes the same decisions from session one. No server. No data collection. MIT licensed.

This is FeatureDrop v3. (v2 launch post here if you want the backstory — it blew up, so I kept building.)

TL;DR:

  • Client-side behavioral engine, 4 kB, zero servers
  • Picks the right format (badge / toast / modal) per user automatically
  • Free, MIT licensed, 479 tests, works with Next.js / Remix / Astro / Nuxt + shadcn

The Problem With "Just Show It"

Every product adoption tool works the same way: you define a feature, pick a format (badge, modal, toast), set a date, and hope for the best.

But your power users don't need a modal. Your new users don't need a tiny badge. Someone who just dismissed three announcements doesn't want a fourth.

Pendo, Appcues, and Chameleon solve this with server-side analytics pipelines that take weeks to collect enough data.

We solved it with client-side analytics — in 4 kB, from the first session.


The Numbers

Before diving into the how — here's what v3 ships:

Metric v2.7 v3.0
Core bundle (gzip) 3.01 kB 3.02 kB
Engine bundle (gzip) 4.08 kB
Tests 374 479
Subpath exports 20 26
Framework integrations 7 11
shadcn components 0 5
CLI commands 9 10

The core didn't grow. Zero runtime dependencies. The engine is an opt-in 4 kB add-on. If you don't import it, you don't pay for it.


Meet the AdoptionEngine

npm install featuredrop@3
Enter fullscreen mode Exit fullscreen mode

The AdoptionEngine is a plugin that tracks behavior locally and makes smart decisions:

┌─────────────────────────────────────────┐
│           AdoptionEngine                │
├──────────────┬──────────────────────────┤
│ Behavior     │ Tracks sessions, dismiss │
│ Tracker      │ patterns, engagement     │
├──────────────┼──────────────────────────┤
│ Timing       │ Cooldowns, fatigue       │
│ Optimizer    │ detection, optimal gaps  │
├──────────────┼──────────────────────────┤
│ Format       │ Badge vs toast vs modal  │
│ Selector     │ based on user behavior   │
├──────────────┼──────────────────────────┤
│ Adoption     │ A-F grading, breakdown,  │
│ Scorer       │ recommendations          │
└──────────────┴──────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Here's how you use it:

import { FeatureDropProvider } from 'featuredrop/react'
import { createAdoptionEngine } from 'featuredrop/engine'
import { LocalStorageAdapter } from 'featuredrop'
import features from './features.json'

const engine = createAdoptionEngine()

function App() {
  return (
    <FeatureDropProvider
      manifest={features}
      storage={new LocalStorageAdapter()}
      engine={engine}
    >
      <YourApp />
    </FeatureDropProvider>
  )
}
Enter fullscreen mode Exit fullscreen mode

That's it. The engine now observes user behavior and makes decisions. No config.


useSmartFeature — The Hook That Thinks

Instead of manually deciding "show a badge for this feature," you ask the engine:

import { useSmartFeature } from 'featuredrop/react/hooks'

function Sidebar() {
  const { show, format, feature, dismiss, confidence } =
    useSmartFeature('ai-search')

  if (!show) return null

  // Engine decided: badge for power users, toast for new users
  if (format === 'badge') return <Badge onClick={dismiss}>{feature.label}</Badge>
  if (format === 'toast') return <Toast onClose={dismiss}>{feature.description}</Toast>
  if (format === 'banner') return <Banner onDismiss={dismiss}>{feature.label}</Banner>
}
Enter fullscreen mode Exit fullscreen mode

The confidence score tells you how sure the engine is. First session? Low confidence, conservative format. Tenth session with clear patterns? High confidence, optimal format.

Without the engine, the hook gracefully degrades — always shows, always uses badge format. Zero breaking changes.


SmartAnnouncement — Zero-Config Component

Don't want to write conditional rendering? One component handles everything:

import { SmartAnnouncement } from 'featuredrop/react'

// Engine picks the format automatically
<SmartAnnouncement featureId="dark-mode" />

// Or bring your own UI with render props
<SmartAnnouncement featureId="dark-mode">
  {({ feature, format, dismiss }) => (
    <MyCustomCard title={feature.label} onClose={dismiss} />
  )}
</SmartAnnouncement>
Enter fullscreen mode Exit fullscreen mode

Six built-in format renderers: badge, toast, banner, inline, modal, spotlight. Each adapts to the user.


Framework-Native, Not Framework-Adjacent

v3 ships first-class integrations for every major meta-framework. Not wrappers — native patterns.

Next.js (App Router + RSC)

// app/layout.tsx — Server Component
import { getNewCountServer, FeatureDropScript } from 'featuredrop/next'

export default async function Layout({ children }) {
  const manifest = await getManifest()
  const dismissed = await getDismissedIds(userId)
  const newCount = getNewCountServer(manifest, dismissed)

  return (
    <html>
      <body>
        {/* Hydrates client provider — no flash of "0 new" */}
        <FeatureDropScript manifest={manifest} dismissedIds={dismissed} />
        <nav>
          What's New {newCount > 0 && <span>{newCount}</span>}
        </nav>
        {children}
      </body>
    </html>
  )
}
Enter fullscreen mode Exit fullscreen mode

Also ships native integrations for Remix, Astro, and Nuxt — each creates a fresh MemoryAdapter per request, no shared state, no race conditions.


shadcn Registry — Copy-Paste React Components

If you use shadcn/ui, you can now install FeatureDrop components directly:

# Changelog widget for React — yours to customize
npx shadcn@latest add https://featuredrop.dev/r/changelog-widget.json
npx shadcn@latest add https://featuredrop.dev/r/new-badge.json
npx shadcn@latest add https://featuredrop.dev/r/tour.json
npx shadcn@latest add https://featuredrop.dev/r/checklist.json
npx shadcn@latest add https://featuredrop.dev/r/feedback-widget.json
Enter fullscreen mode Exit fullscreen mode

The shadcn registry turns FeatureDrop into a React component library that lives in your codebase. They use your existing shadcn primitives (Badge, Sheet, Dialog), your Tailwind theme, your design tokens. Not our CSS — yours.


AI-Native Developer Experience

Every AI coding assistant now understands FeatureDrop:

npx featuredrop ai-setup
Enter fullscreen mode Exit fullscreen mode

This auto-detects your editor and creates the right context:

Editor What it creates
Claude Code .claude/skills/featuredrop.md + MCP config
Cursor .cursorrules + .cursor/mcp.json
VS Code .vscode/mcp.json

The MCP server gives your AI assistant 5 tools (scaffold features, validate manifests, suggest components) and 6 resources (hooks reference, component catalog, adapter guide).

Tell Claude "add a changelog to my sidebar" and it generates correct imports, hooks, and provider setup — first try.


The Open Source Pendo Alternative

If you're evaluating product adoption tools, here's what the market charges:

Capability Pendo FeatureDrop v3
Feature announcements Yes Yes
Product tours Yes Yes
Checklists Yes Yes
NPS/Surveys Yes Yes
Feedback collection Yes Yes
Smart timing Server-side, weeks of data Client-side, session 1
Format adaptation Manual rules Automatic
Adoption scoring Dashboard only In-app hooks
Bundle size 100-300 kB 3 kB core + 4 kB engine
Data collection Their servers Your browser. That's it.
Price $7,000+/year $0
Vendor lock-in Yes MIT licensed

Key takeaway: You don't need a $7k analytics pipeline to make smart adoption decisions. A 4 kB client-side engine with localStorage is enough.


Get Started in 5 Minutes

npm install featuredrop
Enter fullscreen mode Exit fullscreen mode
  1. Create features.json with your features
  2. Wrap your app in <FeatureDropProvider>
  3. Drop <SmartAnnouncement featureId="..." /> wherever you want
  4. Done. The engine handles the rest.

GitHub | Docs | shadcn Components | Example App

FeatureDrop Cloud (hosted dashboard for teams) is coming soon. The open-source library stays free forever.


If you've used Pendo, Appcues, or Beamer — what made you pay for them vs. building in-house? I'd love to hear in the comments.

I'm GDS K S, building FeatureDrop at GLINR Studios. Star the repo if this is useful.

Top comments (0)