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

payafter-currency

v1.0.0

Published

Shared currency utilities for PayAfter applications

Readme

@payafter/currency

Shared currency utilities for PayAfter applications supporting RWF (Rwandan Franc) and XOF (West African CFA Franc).

Features

  • Precise monetary calculations using Dinero.js
  • RWF rounding constraint - All installments (except last) are multiples of 100
  • Multi-currency support - RWF and XOF
  • Type-safe - Full TypeScript support
  • Well-tested - >90% code coverage

Installation

npm install @payafter/currency dinero.js

Note: dinero.js is a peer dependency and must be installed separately.

Usage

Calculate Installments

import { calculateInstallments } from '@payafter/currency';

// RWF - with rounding to multiples of 100
const installments = calculateInstallments(100000, 3, 'RWF');
// [33300, 33300, 33400]

// XOF - no rounding constraint
const installments = calculateInstallments(100000, 3, 'XOF');
// [33333, 33333, 33334]

Format Money

import { formatMoney } from '@payafter/currency';

// Format RWF
const formatted = formatMoney(100000, 'RWF');
// "RWF 100,000"

// Format XOF with French locale
const formatted = formatMoney(100000, 'XOF', 'fr-FR');
// "100 000 XOF"

Calculate Monthly Repayment

import { calculateMonthlyRepayment } from '@payafter/currency';

const result = calculateMonthlyRepayment(
  100000,  // amountFunded
  20000,   // expectedProfit
  6,       // paymentLength (months)
  'RWF'    // currency
);

console.log(result);
// {
//   monthlyReturn: 20000,
//   monthlyPrincipal: 16700,
//   monthlyProfit: 3300
// }

Round to Minimum Unit

import { roundToMinimumUnit } from '@payafter/currency';

// RWF - rounds to nearest 100
roundToMinimumUnit(33333, 'RWF'); // 33300
roundToMinimumUnit(33350, 'RWF'); // 33400

// XOF - no rounding
roundToMinimumUnit(33333, 'XOF'); // 33333

API Reference

Types

type Currency = 'RWF' | 'XOF';
type Locale = 'rw' | 'ci';

interface CurrencyConfig {
  currency: Currency;
  minimumUnit: number;
  locale: string;
}

Constants

CURRENCY_CONFIGS: Record<Currency, CurrencyConfig>
LOCALE_TO_CURRENCY: Record<string, Currency>

Functions

calculateInstallments(totalPrice: number, count: number, currency: Currency): number[]

Calculates installment amounts with precise distribution.

  • RWF: Each installment (except last) is rounded to multiples of 100
  • XOF: No rounding constraint
  • Last installment absorbs any remainder to ensure sum = totalPrice

formatMoney(amount: number | Dinero.Dinero, currency: Currency, locale?: string): string

Formats money for display.

roundToMinimumUnit(amount: number, currency: Currency): number

Rounds amount to the currency's minimum unit.

calculateMonthlyRepayment(amountFunded: number, expectedProfit: number, paymentLength: number, currency: Currency)

Calculates monthly repayment details for investors.

createMoney(amount: number, currency: Currency): Dinero.Dinero

Creates a Dinero money object.

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Watch mode
npm run dev

Testing

The package has comprehensive test coverage (>90%) including:

  • Installment calculations for both currencies
  • Rounding constraints for RWF
  • Money formatting
  • Edge cases (zero count, single installment, etc.)

Run tests:

npm test

License

UNLICENSED - Private package for PayAfter

Support

For issues or questions, contact the PayAfter development team.