@nexussdk/analytics
v0.1.0
Published
A/B test statistical significance calculator and experiment analytics utilities for the Nexus SDK ecosystem
Maintainers
Readme
@nexussdk/analytics
A/B test statistical significance calculator for the Nexus SDK ecosystem.
Pure TypeScript · Zero dependencies · ~1.2 KB gzipped · Works everywhere JavaScript runs.
What It Does
Determine A/B experiment winners with mathematical certainty — directly in the browser or Node.js, with zero network calls and zero external dependencies.
- ✅ Chi-squared test with Yates' continuity correction
- ✅ Confidence levels — 99.9%, 99%, 95%, 90%, 85%, 80%
- ✅ Uplift calculation — relative change as
'+12.35%' - ✅ Sample size planner — minimum visitors needed before running an experiment
- ✅ Actionable recommendations — human-readable
ship it/keep runningtext - ✅ Framework-agnostic — React, Vue, Angular, Svelte, Nuxt, Next.js, Vanilla JS, Node.js
Installation
npm install @nexussdk/analytics
# or
pnpm add @nexussdk/analytics
# or
yarn add @nexussdk/analyticsQuick Start
import { computeABSignificance, computeRequiredSampleSize } from '@nexussdk/analytics';
// Step 1: Calculate required sample size before starting your experiment
const n = computeRequiredSampleSize(0.05, 0.10); // 5% baseline, 10% MDE
console.log(`Need ${n} visitors per variant`); // 3,693
// Step 2: Analyze results
const result = computeABSignificance({
name: 'checkout-button-color',
controlVisitors: 5000,
controlConversions: 250, // 5.0% conversion rate
variantVisitors: 5000,
variantConversions: 310, // 6.2% conversion rate
});
console.log(result.winner); // 'variant'
console.log(result.significant); // true
console.log(result.confidence); // 95.2
console.log(result.uplift); // '+12.35%'
console.log(result.pValue); // 0.0469
console.log(result.recommendation);
// 'Roll out the variant for test "checkout-button-color" to 100% of users...'Framework Examples
import { computeABSignificance } from '@nexussdk/analytics';
function ExperimentCard({ exp }) {
const result = computeABSignificance({
name: exp.name,
controlVisitors: exp.control.visitors,
controlConversions: exp.control.conversions,
variantVisitors: exp.variant.visitors,
variantConversions: exp.variant.conversions,
});
return (
<div>
<p>Winner: {result.winner}</p>
<p>Confidence: {result.confidence.toFixed(1)}%</p>
<p>Uplift: {result.uplift}</p>
<p>{result.recommendation}</p>
</div>
);
}<script setup lang="ts">
import { computed } from 'vue';
import { computeABSignificance } from '@nexussdk/analytics';
const props = defineProps<{ experiment: Experiment }>();
const result = computed(() => computeABSignificance({
name: props.experiment.name,
controlVisitors: props.experiment.control.visitors,
controlConversions: props.experiment.control.conversions,
variantVisitors: props.experiment.variant.visitors,
variantConversions: props.experiment.variant.conversions,
}));
</script>
<template>
<div>Winner: {{ result.winner }} · {{ result.confidence.toFixed(1) }}% confidence</div>
</template>import { Component, Input } from '@angular/core';
import { computeABSignificance } from '@nexussdk/analytics';
@Component({
selector: 'app-experiment',
template: `<p>{{ result.recommendation }}</p>`,
})
export class ExperimentComponent {
@Input() experiment!: Experiment;
get result() {
return computeABSignificance({
name: this.experiment.name,
controlVisitors: this.experiment.control.visitors,
controlConversions: this.experiment.control.conversions,
variantVisitors: this.experiment.variant.visitors,
variantConversions: this.experiment.variant.conversions,
});
}
}import { computeABSignificance } from '@nexussdk/analytics';
// Fail CI if experiment isn't significant yet
const result = computeABSignificance(experimentData);
if (!result.significant) {
console.error('Experiment not yet significant — do not ship!');
process.exit(1);
}API Reference
computeABSignificance(input: ABTestInput): ABTestResult
| Field | Type | Description |
|-------|------|-------------|
| name | string | Test identifier |
| controlVisitors | number | Unique visitors in control |
| controlConversions | number | Conversions in control |
| variantVisitors | number | Unique visitors in variant |
| variantConversions | number | Conversions in variant |
Returns:
| Field | Type | Description |
|-------|------|-------------|
| winner | 'control' \| 'variant' \| 'inconclusive' | Which variant won |
| significant | boolean | p < 0.05 (Chi-squared ≥ 3.841) |
| confidence | number | Confidence percentage |
| uplift | string | Relative change e.g. '+12.35%' |
| chiSquared | number | Raw test statistic |
| pValue | number | Probability of false positive |
| recommendation | string | Human-readable action item |
computeRequiredSampleSize(baselineRate, mde, alpha?, power?): number
// 5% base rate, 10% MDE, 95% confidence, 80% power
computeRequiredSampleSize(0.05, 0.10) // 3,693 per variant
computeRequiredSampleSize(0.05, 0.05) // 14,763 per variant
computeRequiredSampleSize(0.02, 0.20) // 2,417 per variantLicense
MIT © Hồ Huỳnh Dũng
