PLG OS

Implementation worksheet · 6 min read

A component library consolidation worksheet

List every library that renders in-app guidance (tours, tooltips, positioning, toasts, surveys, celebration effects), then record for each where it's used, its licence as published on the npm registry, its size and its focus behavior. Pick one per job and retire the rest, starting with the least used. Check licences first. As of September 2026 the npm registry lists Shepherd.js and Intro.js as AGPL-3.0, and both offer commercial licences according to their npm readmes; Driver.js, React Joyride, Reactour and Floating UI are listed as MIT. Consolidating onto an AGPL library in a closed-source product without checking the terms swaps a maintenance problem for a legal one, so check with counsel.

Guidance libraries accumulate. A tour library from the first onboarding project, a tooltip package a designer added, a positioning engine two other components depend on, a confetti script from a hackathon, a survey widget from a vendor trial. Each works. Together they ship duplicate code, inconsistent focus behavior and several ways to show a popover. Actor: the engineer who owns the front end, with the growth team that uses the components. Boundary: one product's in-app guidance UI, not the whole design system.

Put it into practice

1. Inventory from the lockfile and the imports

Search package.json, the lockfile and import statements, not memory. Include dependencies pulled in by other packages, such as a tooltip library bringing its own positioning engine, and vendor scripts loaded by URL.

2. Record each licence from the registry, with the date

Take the licence field for the version you actually run, and note the date you checked. Licences can change between major versions. The registry also shows when a package last published: tippy.js's latest release, 6.3.7, dates from November 2021, which is worth knowing even if it isn't a reason to remove it on its own.

3. Measure what each one costs

Bytes shipped, whether it loads on every page or only when guidance runs, and main-thread time where it's significant. The SDK performance budget worksheet has the method; use the same one for every library so the comparison is fair.

4. Test focus and keyboard behavior the same way for each

Escape to close, focus landing after close, labels, reduced motion for any animation. The library you keep should pass the focus restoration test plan, because it will set the behavior for every flow built on it.

5. Pick one per job and write down why

Positioning, tour sequencing, toast, survey, celebration. One library can cover several jobs; two libraries for one job need a stated reason. The reason goes in the worksheet so the next person doesn't re-add what you removed.

6. Retire in order, least used first

Put the kept library behind a small internal component so call sites don't import it directly. Migrate the call sites of the least-used library first, compare behavior before and after, remove the package, repeat. Small removals are easy to review and easy to revert.

7. Block reintroduction

Add retired packages to a dependency check or ESLint's no-restricted-imports rule, with a message pointing at the internal component. Without that, the next hackathon brings the confetti library back.

Consolidation worksheet

Copy this structure into your review document and record your observed result for each row.

Consolidation worksheet
Library and jobLicence on npm, September 2026Usage (illustrative)Decision in this example
Shepherd.js, toursAGPL-3.0; commercial licence offered2 legacy toursRetire; move tours to the kept library
Intro.js, toursAGPL-3.0; commercial licence offered1 admin walkthroughRetire
Driver.js, tours and highlightsMIT4 feature highlightsKeep as the single tour library
React Joyride, toursMIT1 onboarding tourRetire; overlaps the kept tour library
Reactour, toursMITImported, never renderedRemove
Floating UI, positioningMITTooltips, menus, popoversKeep as the single positioning engine
Tippy.js, tooltipsMIT; latest release 6.3.7, November 202112 tooltipsMigrate to a tooltip built on Floating UI
canvas-confetti, celebrationsISCMilestone celebrationKeep; respect reduced motion
Vendor survey widgetCommercial, per contractNPS surveyKeep; review at contract renewal

A failure worth checking

Consolidating onto whatever has the most call sites. The team keeps the tour library used in the most places, which happens to be AGPL-3.0, inside a closed-source product, and nobody reads the licence or asks about the commercial option. The migration is clean and well tested, and the question it never asked is now concentrated in one dependency. That's why licence is the second column of the worksheet and the first thing checked.

Common questions

Is AGPL-3.0 a problem for a SaaS product?

It can be. AGPL-3.0 carries obligations when the software is conveyed, and its section 13 adds one for modified versions that users interact with over a network. How that applies to a closed-source product shipping a library to browsers is a question for counsel. Both AGPL-licensed tour libraries above also offer commercial licences, so there's usually a path; record which one you took.

Should we replace the libraries with a vendor SDK instead?

That's a different decision: it trades code you own for a service you rent, and the vendor's script then needs its own performance budget, licence review and owner. Run the worksheet either way. The vendor just becomes another row.

Basis and scope

This is a proposed implementation method using illustrative examples, not a measured benchmark or a customer case study. Prepared with AI assistance. Validate product-specific behavior against current documentation and your own test environment.

Continue with PLG OS

Explore onboarding →