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

@xaiku/browser

v1.1.1

Published

Vanilla JavaScript SDK for A/B testing and variant display with automatic tracking.

Readme

@xaiku/browser

Vanilla JavaScript SDK for A/B testing and variant display with automatic tracking.

Installation

npm install @xaiku/browser
# or
pnpm add @xaiku/browser

Quick Start

import xaikuBrowser from '@xaiku/browser'

// Initialize SDK
const sdk = xaikuBrowser({
  apiUrl: 'https://api.xaiku.com',
  pkey: 'your-public-key'
})

// Get variant text with fallback
const headline = sdk.getVariantText('homepage-test', 'headline', {
  fallback: 'Welcome to our site!'
})

// Update DOM element
document.getElementById('headline').textContent = headline

// Track view (automatic with getVariantText)
sdk.track.events.trackView({
  experimentId: 'homepage-test',
  partId: 'headline'
})

Core Features

Variant Text Display

Get text variants with automatic fallback handling:

// Basic usage
const buttonText = sdk.getVariantText('cta-test', 'button', {
  fallback: 'Sign Up'
})

// With control group
const headline = sdk.getVariantText('hero-test', 'headline', {
  fallback: 'Default Headline',
  control: false // or true to force control
})

// Update DOM
document.querySelector('#hero h1').textContent = headline
document.querySelector('#cta-button').textContent = buttonText

Event Tracking

Simple tracking for marketing metrics:

// Track views (impressions)
sdk.track.events.trackView({
  experimentId: 'homepage-test',
  variantId: 'variant-a', // optional, auto-detected
  partId: 'hero-section'
})

// Track clicks
sdk.track.events.trackClick({
  experimentId: 'cta-test',
  partId: 'signup-button'
})

// Track conversions with value
sdk.track.events.trackConversion({
  experimentId: 'checkout-flow',
  partId: 'purchase',
  value: 99.99
})

Complete Example

Landing Page A/B Test

<!DOCTYPE html>
<html>
<head>
  <title>Landing Page Test</title>
</head>
<body>
  <header>
    <h1 id="headline">Loading...</h1>
    <p id="subtitle">Loading...</p>
    <button id="cta-button">Loading...</button>
  </header>

  <script type="module">
    import xaikuBrowser from '@xaiku/browser'

    // Initialize SDK
    const sdk = xaikuBrowser({
      pkey: 'your-public-key'
    })

    // Get variant text and update DOM
    const headline = sdk.getVariantText('landing', 'headline', {
      fallback: 'Transform Your Business'
    })
    const subtitle = sdk.getVariantText('landing', 'subtitle', {
      fallback: 'Join thousands of satisfied customers'
    })
    const ctaText = sdk.getVariantText('landing', 'cta', {
      fallback: 'Start Free Trial'
    })

    // Update DOM elements
    document.getElementById('headline').textContent = headline
    document.getElementById('subtitle').textContent = subtitle
    document.getElementById('cta-button').textContent = ctaText

    // Track views (automatic with getVariantText)
    sdk.track.events.trackView({
      experimentId: 'landing',
      partId: 'headline'
    })
    sdk.track.events.trackView({
      experimentId: 'landing', 
      partId: 'subtitle'
    })

    // Track CTA clicks
    document.getElementById('cta-button').addEventListener('click', () => {
      // Track click
      sdk.track.events.trackClick({
        experimentId: 'landing',
        partId: 'cta'
      })

      // Handle conversion
      handleSignup()
    })

    async function handleSignup() {
      try {
        const response = await fetch('/api/signup', { method: 'POST' })
        if (response.ok) {
          // Track successful conversion
          sdk.track.events.trackConversion({
            experimentId: 'landing',
            partId: 'signup',
            value: 29.99
          })
        }
      } catch (error) {
        console.error('Signup failed:', error)
      }
    }
  </script>
</body>
</html>

E-commerce Product Page

import xaikuBrowser from '@xaiku/browser'

// Initialize for e-commerce
const sdk = xaikuBrowser({
  pkey: 'ecommerce-key'
})

// Update product page content
function updateProductPage(productId) {
  // Get variant content
  const productTitle = sdk.getVariantText('product', 'title', {
    fallback: 'Amazing Product'
  })
  const addToCartText = sdk.getVariantText('product', 'add-to-cart', {
    fallback: 'Add to Cart'
  })
  const buyNowText = sdk.getVariantText('product', 'buy-now', {
    fallback: 'Buy Now'
  })

  // Update DOM
  document.querySelector('.product-title').textContent = productTitle
  document.querySelector('.add-to-cart-btn').textContent = addToCartText
  document.querySelector('.buy-now-btn').textContent = buyNowText

  // Track product view
  sdk.track.events.trackView({
    experimentId: 'product',
    partId: 'product-page',
    productId
  })

  // Track add to cart
  document.querySelector('.add-to-cart-btn').addEventListener('click', () => {
    sdk.track.events.trackClick({
      experimentId: 'product',
      partId: 'add-to-cart',
      productId
    })
    // Add to cart logic...
  })

  // Track purchase conversion
  document.querySelector('.buy-now-btn').addEventListener('click', () => {
    sdk.track.events.trackConversion({
      experimentId: 'product',
      partId: 'purchase',
      productId,
      value: getProductPrice(productId)
    })
    // Purchase logic...
  })
}

Multi-page Application

import xaikuBrowser from '@xaiku/browser'

const sdk = xaikuBrowser({
  pkey: 'your-public-key'
})

// Update page content based on route
function updatePageContent(route) {
  switch (route) {
    case '/':
      updateHomePage()
      break
    case '/products':
      updateProductsPage()
      break
    case '/about':
      updateAboutPage()
      break
  }
}

function updateHomePage() {
  // Hero section variants
  const heroHeadline = sdk.getVariantText('homepage', 'hero-headline', {
    fallback: 'Welcome to Our Platform'
  })
  const heroSubtext = sdk.getVariantText('homepage', 'hero-subtext', {
    fallback: 'The best solution for your needs'
  })

  document.querySelector('#hero h1').textContent = heroHeadline
  document.querySelector('#hero p').textContent = heroSubtext

  // Track page view
  sdk.track.events.trackView({
    experimentId: 'homepage',
    partId: 'hero'
  })
}

function updateProductsPage() {
  // Product listing variants
  const listingTitle = sdk.getVariantText('products', 'listing-title', {
    fallback: 'Our Products'
  })
  const filterText = sdk.getVariantText('products', 'filter-label', {
    fallback: 'Filter by category'
  })

  document.querySelector('#products h1').textContent = listingTitle
  document.querySelector('.filter-label').textContent = filterText

  // Track page view
  sdk.track.events.trackView({
    experimentId: 'products',
    partId: 'listing'
  })
}

// Handle navigation
window.addEventListener('popstate', () => {
  updatePageContent(window.location.pathname)
})

// Initial page load
updatePageContent(window.location.pathname)

API Reference

SDK Initialization

const sdk = xaikuBrowser(options)

Options:

  • pkey (string) - Your public API key
  • apiUrl (string) - API endpoint URL (optional)
  • experimentIds (array) - Pre-load specific experiments (optional)

Variant Text

sdk.getVariantText(experimentId, partId, options)

Parameters:

  • experimentId (string) - A/B test experiment ID
  • partId (string) - Specific part/component ID
  • options.fallback (string) - Default text if variant fails
  • options.control (boolean) - Force control group (optional)

Event Tracking

// Track impressions
sdk.track.events.trackView(data)

// Track interactions  
sdk.track.events.trackClick(data)

// Track conversions
sdk.track.events.trackConversion(data)

Data object:

  • experimentId (string) - A/B test experiment ID
  • partId (string) - Component ID (optional)
  • variantId (string) - Variant ID (auto-detected if not provided)
  • value (number) - Conversion value (trackConversion only)

Utility Methods

// Get current variant for experiment
const variant = sdk.getVariant('experiment-id')

// Get specific variant ID
const variantId = sdk.getVariantId('experiment-id')

// Check if user is in control group
const isControl = sdk.isControl('experiment-id')

// Manually flush tracking events
sdk.track.flush()

// Clean up SDK resources
sdk.destroy()

Features

  • Automatic tracking - Views tracked when getting variant text
  • Fallback handling - Graceful degradation when variants fail
  • Lightweight - Minimal bundle size and performance impact
  • Framework agnostic - Works with any JavaScript application
  • Automatic batching - Events are batched and sent efficiently

Browser Support

  • Chrome 60+
  • Firefox 60+
  • Safari 12+
  • Edge 79+

Development

# Install dependencies
pnpm install

# Run tests
pnpm test

# Build package
pnpm build

# Lint code
pnpm lint