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

hownow

v1.0.2

Published

Explainable calculator with internationalization support - track calculation steps and provide transparent, translatable explanations

Readme

HowNow

Explainable calculator with internationalization support

HowNow is a JavaScript library that tracks calculation steps and provides transparent, translatable explanations. Perfect for financial calculators, tax calculations, insurance quotes, or any application where you need to show users "how we got this number."

Features

  • 🔢 High-precision math using BigNumber (via mathjs)
  • 🌍 Internationalization-first design with token-based translations
  • 📊 Step-by-step calculation tracking with full audit trail
  • Zero performance overhead when debug mode is disabled
  • 🎯 Builder pattern API for clean, readable code
  • 📝 Rich metadata support for contextual explanations
  • 🔧 TypeScript support with full type definitions

Installation

npm install hownow

Quick Start

import HowNow from 'hownow';

// Enable debug mode to track calculation steps
HowNow.setDebugMode(true);

// Perform calculations with context
const result = new HowNow(72000)
    .as('convertAnnualToMonthly', { annual: 72000 })
    .div(12)
    .as('applyTaxRate', { rate: 0.15 })
    .multiply(0.85)
    .as('roundResult')
    .round(2);

console.log(result.valueOf()); // 5100

// Get detailed explanation
const explanation = result.toDisplayFormat();
console.log(explanation.steps);
/*
[
  {
    tokenKey: 'convertAnnualToMonthly',
    operation: '/',
    inputs: [72000, 12],
    result: 6000,
    metadata: { annual: 72000 },
    interpolation: { input: 72000, value: 12, result: 6000, annual: 72000 }
  },
  {
    tokenKey: 'applyTaxRate',
    operation: '*',
    inputs: [6000, 0.85],
    result: 5100,
    metadata: { rate: 0.15 },
    interpolation: { input: 6000, value: 0.85, result: 5100, rate: 0.15 }
  },
  {
    tokenKey: 'roundResult',
    operation: 'round',
    result: 5100,
    interpolation: { input: 5100, result: 5100 }
  }
]
*/

Internationalization

HowNow is designed for i18n from the ground up. Use token keys instead of English strings:

// translations-en.json
{
  "convertAnnualToMonthly": "Convert annual salary of ${{annual}} to monthly: ${{result}}",
  "applyTaxRate": "Apply {{rate}} tax rate to ${{input}} to get ${{result}}",
  "roundResult": "Round to ${{result}}"
}

// translations-es.json
{
  "convertAnnualToMonthly": "Convertir salario anual de ${{annual}} a mensual: ${{result}}",
  "applyTaxRate": "Aplicar tasa de impuesto {{rate}} a ${{input}} para obtener ${{result}}",
  "roundResult": "Redondear a ${{result}}"
}

// In your application
function translate(tokenKey, interpolation) {
  let text = translations[tokenKey];
  Object.entries(interpolation).forEach(([key, value]) => {
    text = text.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value);
  });
  return text;
}

explanation.steps.forEach(step => {
  console.log(translate(step.tokenKey, step.interpolation));
});
// Output: "Convert annual salary of $72000 to monthly: $6000"

API Reference

Core Methods

new HowNow(value)

Create a new HowNow instance with an initial value.

const calc = new HowNow(100);

HowNow.setDebugMode(enabled: boolean)

Enable or disable step tracking globally. When disabled, all tracking operations are no-ops for zero performance overhead.

HowNow.setDebugMode(true); // Enable tracking
HowNow.setDebugMode(false); // Disable for production

.as(tokenKey: string, metadata?: object)

Set context for the next operation. This provides a descriptive token key and metadata for the upcoming calculation step.

calc.as('applyDiscount', { discountRate: 0.10 }).multiply(0.9);

Math Operations

.add(value) / .sub(value) / .multiply(value) / .div(value)

Perform basic arithmetic operations.

new HowNow(100)
    .add(50)      // 150
    .multiply(2)  // 300
    .sub(50)      // 250
    .div(5);      // 50

.floor(precision?) / .round(precision)

Rounding operations.

new HowNow(123.456)
    .floor(2)    // 123.45
    .round(1);   // 123.5

.max(value)

Take the maximum of current value and provided value.

new HowNow(50).max(100); // 100

.gt(value) / .lt(value)

Comparison operations (returns boolean, not HowNow).

new HowNow(50).gt(30);  // true
new HowNow(50).lt(100); // true

Labeling Methods

.rollUp(tokenKey, metadata?)

Mark this value as a named intermediate result.

calc.multiply(12).rollUp('annualSalary', { year: 2024 });

.label(tokenKey, metadata?)

Add a label to the current value.

calc.round(2).label('finalResult');

.step(tokenKey, metadata?)

Mark a calculation milestone.

calc.add(100).step('afterBonus');

.branch(condition, trueToken, falseToken, metadata?)

Conditional labeling based on a boolean condition.

const age = 65;
calc.branch(age >= 65, 'fullBenefit', 'reducedBenefit', { age });

Output Methods

.valueOf()

Get the numeric value.

const num = calc.valueOf(); // returns number

.toString()

Get the string representation.

const str = calc.toString(); // returns string

.toDisplayFormat()

Get structured output with all calculation steps.

const display = calc.toDisplayFormat();
/*
{
  value: 5100,
  steps: [ ... ],
  tables: [ ... ]
}
*/

.getSteps()

Get array of calculation steps.

const steps = calc.getSteps(); // returns CalcStep[]

Types

CalcStep

type CalcStep = {
  tokenKey: string;
  operation?: string;
  inputs?: (string | number)[];
  result: number;
  metadata?: Record<string, unknown>;
  interpolation?: Record<string, string | number>;
}

DisplayFormat

type DisplayFormat = {
  value: number;
  steps: CalcStep[];
}

Use Cases

Financial Calculators

Show users exactly how their loan payment, mortgage, or investment returns were calculated.

Tax Calculators

Provide transparent tax calculations with step-by-step breakdowns.

Insurance Quotes

Explain premium calculations with all the factors that went into the price.

Pricing Engines

Show how complex pricing formulas arrive at the final price.

Regulatory Compliance

Maintain audit trails of calculations for compliance purposes.

Educational Tools

Help students understand multi-step calculations by showing each step.

Performance

When debug mode is disabled, HowNow adds virtually zero overhead to your calculations. All tracking logic is gated behind the debugMode flag:

// Production: disable tracking
HowNow.setDebugMode(false);
const result = new HowNow(100).multiply(2).div(5); // Fast!

// Development/user-facing: enable tracking
HowNow.setDebugMode(true);
const result = new HowNow(100).multiply(2).div(5); // With full audit trail

Examples

See the /examples directory for complete examples including:

  • Financial calculator with step filtering
  • Multi-language support
  • React integration
  • Complex formula calculations

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © Charles McNulty

Related Projects