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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@jaydixit/experimental-mode

v1.0.6

Published

A memorialized implementation of the experimental mode pattern from If Then Canonical - complete solution for prototyping and comparing UI variants.

Readme

@jaydixit/experimental-mode

A memorialized implementation of the experimental mode pattern from If Then Canonical - a complete solution for prototyping and comparing UI variants in production applications.

Overview

This package provides everything needed to implement A/B variant testing UI in your applications. Born from the "perfect implementation" in If Then Canonical's identity timeline, it offers:

  • URL-flag detection - ?experimental=true enables experimental mode
  • Keyboard-driven cycling - Option-X cycles through variants (customizable)
  • React hooks - useExperimentalMode provides full state management
  • Styled components - Beautiful navigation and instruction panels (styles injected automatically)
  • Variant metadata - WHAT/WHY/TEST/ASK instructions for each variant

⚠️ IMPORTANT: This package handles keyboard shortcuts (Option-X) automatically. Do NOT add custom keyboard event listeners for variant cycling - duplicate handlers will cause conflicts.

Installation

npm install @jaydixit/experimental-mode

Quick Start

import { useExperimentalMode } from '@jaydixit/experimental-mode/react'
import { VariantNavigation, InstructionsBox, parseInstructionString } from '@jaydixit/experimental-mode'

function App() {
  const experimentalMode = useExperimentalMode({
    variants: [
      {
        key: 'baseline',
        label: 'Baseline',
        description: 'WHAT: Original design with standard spacing | WHY: Proven layout users know | TO TEST: Navigate and verify all features work | ASK: Is this still the best default?',
      },
      {
        key: 'compact',
        label: 'Compact',
        description: 'WHAT: Tighter spacing and smaller typography | WHY: Fit more content on screen | TO TEST: Check readability and clickability | ASK: Does density help or hurt?',
      },
    ],
    defaultKey: 'baseline',
    experimentalDefaultKey: 'compact',
  })

  // Option-X automatically cycles variants - no manual keyboard handling needed!

  const activeVariant = experimentalMode.variants.find(v => v.key === experimentalMode.activeKey)
  const instructions = activeVariant?.description ? parseInstructionString(activeVariant.description) : null

  return (
    <div data-experimental-variant={experimentalMode.activeKey}>
      {experimentalMode.enabled && (
        <div className="variant-switcher">
          <VariantNavigation
            variants={experimentalMode.variants}
            activeKey={experimentalMode.activeKey}
            onSelect={experimentalMode.setActiveKey}
          />
          {instructions && <InstructionsBox instructions={instructions} />}
        </div>
      )}

      {/* Your app content */}
    </div>
  )
}

Add variant-specific CSS:

/* Default styles */
.content {
  padding: 24px;
  font-size: 16px;
}

/* Compact variant */
[data-experimental-variant="compact"] .content {
  padding: 12px;
  font-size: 14px;
}

Core Concepts

URL Flag

Visit yourapp.com?experimental=true to enable experimental mode. The active variant persists in the URL.

Variant Metadata

Each variant should describe:

  • WHAT: What changes in this variant
  • WHY: The hypothesis or goal
  • TO TEST: How to evaluate it
  • ASK: Questions to answer

Format: "WHAT: ... | WHY: ... | TO TEST: ... | ASK: ..."

Keyboard Control

  • Option-X (Alt-X): Cycle forward through variants
  • Handled automatically by the package
  • Customizable via cycleHotkey option

API Reference

useExperimentalMode(options)

React hook that manages experimental mode state.

Options:

  • variants - Array of variant objects with key, label, description
  • defaultKey - Variant to use when experimental mode is OFF
  • experimentalDefaultKey - Variant to use when experimental mode is ON
  • paramName - URL param name (default: "experimental")
  • paramValue - URL param value to enable (default: "true")
  • cycleHotkey - Hotkey config (default: { code: 'KeyX', altKey: true })

Returns:

  • enabled - Whether experimental mode is active
  • activeKey - Current variant key
  • variants - Array of variants
  • setActiveKey(key) - Switch to a specific variant
  • cycleVariant() - Cycle to next variant (rarely needed - keyboard does this)

Components

<VariantNavigation>

Pill-style navigation for switching variants.

Props:

  • variants - Array of variant objects
  • activeKey - Currently active variant key
  • onSelect(key) - Called when user clicks a variant
  • className - Optional additional CSS class

<InstructionsBox>

Displays WHAT/WHY/TEST/ASK instructions in a formatted grid.

Props:

  • instructions - Object with what, why, toTest, ask strings
  • className - Optional additional CSS class

parseInstructionString(description)

Utility to parse pipe-delimited description into instruction object.

const instructions = parseInstructionString(
  "WHAT: New layout | WHY: Better UX | TO TEST: Click everything | ASK: Is it faster?"
)
// Returns: { what: "New layout", why: "Better UX", toTest: "Click everything", ask: "Is it faster?" }

Styling

All component styles are automatically injected into the page. No CSS imports needed!

The package uses hardened styles with !important to prevent conflicts with your app's global CSS.

Customizing Wrapper

You typically wrap the components in a sticky container:

.variant-switcher {
  position: sticky;
  top: 80px; /* Below your header */
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  margin: 24px auto;
  width: min(880px, 100%);
  padding: 0 24px;
}

Advanced Usage

Custom Hotkey

const experimentalMode = useExperimentalMode({
  variants: [...],
  cycleHotkey: { code: 'KeyE', metaKey: true }, // Cmd-E instead
})

Programmatic Control

// Switch to specific variant
experimentalMode.setActiveKey('compact')

// Cycle to next variant (keyboard does this automatically)
experimentalMode.cycleVariant()

Disable Hotkey

const experimentalMode = useExperimentalMode({
  variants: [...],
  cycleHotkey: null, // No keyboard shortcut
})

Example: Calendar App

See how this pattern was used in If Then Canonical:

const experimentalMode = useExperimentalMode({
  variants: [
    { key: 'default', label: 'Default UI', description: '...' },
    { key: 'compact', label: 'Compact View', description: '...' },
    { key: 'modern', label: 'Modern UI', description: '...' },
    { key: 'minimal', label: 'Minimal UI', description: '...' },
  ],
  defaultKey: 'default',
  experimentalDefaultKey: 'modern',
})

Then in CSS:

[data-experimental-variant="modern"] .day-cell {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.1));
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

Best Practices

  1. Keep variants focused - Test one concept per variant
  2. Document thoroughly - Write clear WHAT/WHY/TEST/ASK
  3. Use semantic keys - 'compact' not 'variant-2'
  4. Style with data attributes - [data-experimental-variant="..."] in CSS
  5. No custom keyboard handlers - Let the package handle Option-X
  6. Sticky positioning - Keep navigation visible while scrolling
  7. Test all variants - Cycle through and verify each works

Common Pitfalls

Don't add your own keyboard event listener for cycling:

// WRONG - Will conflict with package
window.addEventListener('keydown', (e) => {
  if (e.altKey && e.code === 'KeyX') {
    experimentalMode.cycleVariant()
  }
})

Don't override button styles globally without excluding package buttons:

/* WRONG - Will break navigation buttons */
button {
  background: blue;
}

/* RIGHT - Exclude package buttons */
button:not(.variant-nav__button) {
  background: blue;
}

Do let the package handle keyboard shortcuts automatically

Do use data-experimental-variant for styling variants

How This Compares to Other Tools

Based on a search by Claude Sonnet 4.5, this package fills a unique niche in the ecosystem. However, there may be other tools that weren't discovered in that search:

Feature Flag Libraries (LaunchDarkly, Unleash, Split.io, PostHog, Prefab)

  • What they do: Boolean flags, percentage rollouts, user segmentation, analytics
  • Gap: Focused on measuring performance with cohorts and analytics, not rapid visual comparison
  • This package: Built for designer/developer visual comparison with keyboard shortcuts and zero analytics overhead

A/B Testing Platforms (VWO, Optimizely, Google Optimize, Maze)

  • What they do: Statistical A/B testing with user cohorts and metrics tracking
  • Gap: Require analytics setup and are meant for measuring outcomes, not rapid iteration
  • This package: Instant switching for design review without any analytics infrastructure

React Feature Flag Libraries (react-feature-flags, feature-switch)

  • What they do: Simple boolean feature flags in React
  • Gap: No UI for switching, no variant metadata, no keyboard shortcuts, no styling support
  • This package: Complete UI solution with navigation, instructions, and developer experience

Design Tools (Figma, Storybook variants)

  • What they do: Compare designs before implementation
  • Gap: Not in the actual production app with real data and state
  • This package: Works in the live app with real interactions and data

What This Package Is For

✅ Showing stakeholders live variants side-by-side ✅ Rapid designer iteration with keyboard shortcuts ✅ Internal testing of UI approaches with real data ✅ Documenting design decisions (WHAT/WHY/TEST/ASK)

What This Package Is NOT For

❌ Analytics-driven A/B testing (use LaunchDarkly) ❌ User cohort segmentation (use Optimizely) ❌ Design mockup comparison (use Figma)

In short: This package is purpose-built for rapid visual prototyping and comparison in production apps, without the overhead of analytics infrastructure.

License

MIT © Jay Dixit

Credits

Memorialized from the experimental mode implementation in If Then Canonical, which provided the perfect blueprint for this pattern.