npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tour-kit/checklists

v0.11.0

Published

React onboarding checklists with task dependencies, progress tracking & persistence — for getting-started flows and activation.

Readme

@tour-kit/checklists

React onboarding checklists with task dependencies, progress tracking & persistence — for getting-started flows and activation.

npm version npm downloads bundle size types

Drop-in onboarding checklists, getting-started panels, activation funnels, and setup wizards for React. Tasks support dependencies (one unlocks the next), progress tracking, completion conditions, and headless render-prop variants.

Pro tier — requires a license key. See Licensing.

Alternative to: Appcues checklists, Userpilot checklists, Userflow, Stripe-style activation lists, hand-rolled task panels.

Features

  • Task dependencies — auto-locks tasks until prerequisites complete
  • Progress tracking{ completed, total, percentage } per checklist + aggregate hooks
  • Completion conditionsmanual, event (listen to custom events), or custom (predicate)
  • Conditional visibilitywhen() predicate to hide tasks dynamically
  • Persistence — survives reload via storage adapter
  • Headless variantsChecklistHeadless, TaskHeadless for full UI control
  • Cycle detectionhasCircularDependency() catches bad configs
  • TypeScript-first, supports React 18 & 19

Installation

npm install @tour-kit/checklists @tour-kit/license
# or
pnpm add @tour-kit/checklists @tour-kit/license

Quick Start

import { LicenseProvider } from '@tour-kit/license'
import {
  ChecklistProvider,
  Checklist,
  ChecklistTask,
  ChecklistProgress,
  ChecklistPanel,
  createChecklist,
  createTask,
} from '@tour-kit/checklists'

const onboarding = createChecklist({
  id: 'onboarding',
  title: 'Get started',
  tasks: [
    createTask({ id: 'profile', title: 'Complete your profile' }),
    createTask({ id: 'invite', title: 'Invite a teammate', dependencies: ['profile'] }),
    createTask({ id: 'project', title: 'Create your first project' }),
  ],
})

function App() {
  return (
    <LicenseProvider licenseKey={process.env.NEXT_PUBLIC_TOURKIT_LICENSE!}>
      <ChecklistProvider checklists={[onboarding]}>
        <ChecklistPanel checklistId="onboarding">
          <ChecklistProgress />
          <Checklist>
            <ChecklistTask taskId="profile" />
            <ChecklistTask taskId="invite" />
            <ChecklistTask taskId="project" />
          </Checklist>
        </ChecklistPanel>
      </ChecklistProvider>
    </LicenseProvider>
  )
}

Mark tasks complete from anywhere:

import { useTask } from '@tour-kit/checklists'

function ProfileForm() {
  const { complete, isCompleted } = useTask('profile')

  const handleSubmit = async () => {
    await saveProfile()
    complete()
  }

  return <form onSubmit={handleSubmit}>{/* ... */}</form>
}

i18n & interpolation

All user-facing strings in @tour-kit/checklists accept the {{var | fallback}} interpolation grammar from @tour-kit/core. Wrap your tree in <LocaleProvider> and every task title and description resolves automatically.

import { LocaleProvider } from '@tour-kit/core'
import { ChecklistProvider, ChecklistTask, createTask } from '@tour-kit/checklists'

const greet = createTask({
  id: 'greet',
  title: { key: 'task.greet' },
  description: 'Welcome {{user.name | aboard}}!',
})

<LocaleProvider locale="en" messages={{ 'task.greet': 'Say hi to {{user.name | the team}}' }}>
  <ChecklistProvider checklists={[{ id: 'onboarding', tasks: [greet] }]}>
    <ChecklistTask taskId="greet" />
  </ChecklistProvider>
</LocaleProvider>

Full guide: https://usertourkit.com/docs/guides/i18n

Headless variant

import { ChecklistHeadless } from '@tour-kit/checklists'

<ChecklistHeadless checklist={onboarding}>
  {({ tasks, progress, completeTask }) => (
    <div className="custom-ui">
      <progress value={progress.percentage} max={100} />
      {tasks.map((task) => (
        <button
          key={task.id}
          disabled={task.locked}
          onClick={() => completeTask(task.id)}
        >
          {task.completed ? '✓' : '○'} {task.title}
        </button>
      ))}
    </div>
  )}
</ChecklistHeadless>

API Reference

Components (styled)

| Export | Purpose | |---|---| | ChecklistProvider | Context provider — registers checklists | | ChecklistPanel | Container with title + collapsible expand | | Checklist | Task list wrapper | | ChecklistTask | Single task row | | ChecklistProgress | Progress bar + percentage | | ChecklistLauncher | Trigger button to open the panel |

Headless components

import { ChecklistHeadless, TaskHeadless } from '@tour-kit/checklists'

Hooks

| Hook | Description | |---|---| | useChecklist(id) | Single checklist state + actions | | useTask(taskId) | Single task state + complete, uncomplete, isCompleted, locked | | useChecklistPersistence(...) | State recovery via storage adapter | | useChecklistsProgress() | Aggregate progress across all registered checklists | | useChecklistContext() | Raw context (advanced) |

Utilities

| Function | Purpose | |---|---| | createChecklist(config) | Type-safe checklist factory | | createTask(config) | Type-safe task factory | | calculateProgress(state) | { completed, total, percentage } | | getNextTask(state) | First incomplete and unlocked task | | getLockedTasks(state) | Tasks blocked by dependencies | | canCompleteTask(taskId, state) | Are deps satisfied? | | resolveTaskDependencies(taskId) | Ordered dep list — throws on cycle | | hasCircularDependency(tasks) | Silent boolean check |

Slot & UI library

import {
  Slot, Slottable, UnifiedSlot,
  UILibraryProvider, useUILibrary,
} from '@tour-kit/checklists'

Types

import type {
  ChecklistConfig,
  ChecklistState,
  ChecklistTaskConfig,
  ChecklistTaskState,
  ChecklistProgressType,            // (component shadows the type name)
  ChecklistContextData,
  TaskAction,
  TaskCompletionCondition,          // 'manual' | 'event' | 'custom'
  ChecklistProviderConfig,
  ChecklistPersistenceConfig,
  PersistedChecklistState,
} from '@tour-kit/checklists'

Task completion conditions

type TaskCompletionCondition = {
  type: 'manual' | 'event' | 'custom'
  eventName?: string             // for 'event' type
  customCheck?: () => boolean    // for 'custom' type
}

Locked vs invisible tasks

  • Locked task — visible, but cannot complete until dependencies finish. Counts toward total in progress.
  • Invisible taskwhen() predicate returned false. Excluded from total.

Gotchas

  • Circular deps fail differently across APIs. createChecklist() logs an error; resolveTaskDependencies() throws; hasCircularDependency() is silent. Use the silent check before passing user-built configs.
  • Render order ≠ dependency order. Tasks render in array order; dependency resolution affects locked state, not display order.
  • <ChecklistPanel defaultExpanded> writes the expanded state once per mount to avoid render loops with context-scoped callbacks.
  • Pair with <LicenseProvider> in production. Dev environments (localhost, 127.0.0.1, *.local) bypass the Pro gate.

Related packages

Documentation

Full documentation: https://usertourkit.com/docs/checklists

License

Pro tier — see LICENSE.md. Requires a Tour Kit Pro license key.