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

@nand.computer/okane

v0.3.0

Published

Minimalist, type-safe money library

Readme

okane

okane provides immutable money objects using bigint in minor units, ensuring exact financial calculations without floating-point errors. Each Money object combines an amount and a currency type, enabling type-safe arithmetic and preventing mixing of currencies.

Installation

bun add @nand.computer/okane

Quick example

import { okane, USD, EUR, fixedFx } from "okane";

// create and operate
const total = okane(9999n, USD).add(okane(9999n, USD).mul(0.23)).sub(okane(9999n, USD).mul(0.1));
console.log(total.format("en-US")); // "$111.87"

// allocate
const [a, b, c] = okane(10000n, USD).allocate([1, 1, 1]);
console.log(a.format(), b.format(), c.format()); // "$33.34 $33.33 $33.33"

// FX
const eurTotal = total.convert(EUR, fixedFx({ USD_EUR: 0.92 }));
console.log(eurTotal.format("de-DE")); // "102,64 €"

// compile-time safety
const eur = okane(1000n, EUR);
// total.add(eur); // TS error

Getting Started

Create a Money instance using minor units:

import { okane, USD } from "okane";
const price = okane(9999n, USD); // $99.99

Arithmetic operations preserve immutability and type safety. Addition or subtraction requires the same currency:

const tax = okane(2500n, USD);
const total = price.add(tax); // $124.99
// price.add(okane(100n, EUR)) // compile-time error

Multiplication and division accept numbers or bigint with optional rounding modes (half-up, half-down, floor, ceil, banker). Decimal factors use scaled integer arithmetic to maintain precision:

price.mul(1.08); // apply 8% tax
price.div(3); // split in 3 parts

Money can be split proportionally using allocate, guaranteeing no loss due to rounding:

okane(100n, USD).allocate([1, 1, 1]); // [$0.33, $0.33, $0.34]

Currency conversion uses explicit exchange rates. Differences in decimal precision between currencies are handled automatically:

import { EUR, convertWith, fixedFx } from "okane";
const fx = fixedFx({ USD: { EUR: 0.85 } });
const eur = convertWith(price, EUR, fx); // $99.99 → €84.99

Parsing from strings or numbers provides exact results. fromDecimal converts decimal strings, fromMajor rounds floating-point numbers, and fromMinor accepts minor units:

import { fromDecimal } from "okane";
const amount = fromDecimal("12.34", USD); // 1234n

Money objects support comparisons (eq, lt, gt, isZero, isPos, isNeg) and formatting (fmt, decimal, json). All methods return new immutable instances, enabling chaining:

const final = price.add(tax).mul(1.08).sub(okane(500n, USD));
console.log(final.fmt()); // '$135.74'

okane separates core operations from parsing, formatting, and validation. Validation returns a Result type, allowing safe handling of untrusted data without exceptions:

import { parseMoney, unwrap } from "okane";
const m = unwrap(parseMoney({ amount: "9999", currency: { code: "USD", decimals: 2 } }));

Predefined currencies cover common fiat and crypto assets, and custom currencies can be created with currency(code, decimals, symbol). Minor unit multipliers are accessible via minorUnits(currency).

By representing money as bigint in minor units and enforcing type safety at compile-time, okane delivers reliable financial calculations with explicit pipelines, immutable values, precise allocation, and clear rounding behavior, while remaining simple to integrate in JavaScript or TypeScript projects.

Todo

  • [ ] lazy evaluate for chained operations
  • [ ] Streaming sum for very large arrays
  • [ ] Rounding Strategies Plugin