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

@m8t-jacob/pln-utils

v0.1.0

Published

Zero-dependency TypeScript utilities for Polish finance: NBP exchange rates, public holidays/working days, VAT calculations, and PLN formatting.

Readme

@m8t-jacob/pln-utils

CI npm version npm downloads bundle size license: MIT

Fully typed TypeScript utilities for Polish finance: NBP exchange rates, public holidays / working days, VAT calculations, and PLN formatting.

  • Strict TypeScript, ships dual ESM + CJS builds with .d.ts
  • Zero runtime dependencies — the NBP client uses the global fetch (Node.js 20+), everything else is pure logic
  • Tree-shakeable; import the whole package or a single subpath
  • Moving Polish holidays computed from Easter Sunday (Meeus/Jones/Butcher algorithm), not a hardcoded table

Install

npm install @m8t-jacob/pln-utils

Quickstart

import { addVat, formatPln, getExchangeRate, isWorkingDay } from '@m8t-jacob/pln-utils';

await getExchangeRate('USD'); // { code: 'USD', rate: 4.05, date: '2025-01-15', table: 'A' }
addVat(100, 23); // 123
formatPln(1234.56); // '1 234,56 zł'
isWorkingDay('2025-05-01'); // false (Święto Pracy)

You can also import from a subpath if you only need one module, which keeps bundlers from pulling in the others:

import { getExchangeRate } from '@m8t-jacob/pln-utils/nbp';
import { getHolidays, isWorkingDay } from '@m8t-jacob/pln-utils/holidays';
import { addVat, removeVat } from '@m8t-jacob/pln-utils/vat';
import { formatPln, parsePln } from '@m8t-jacob/pln-utils/format';

API

NBP exchange rates (nbp)

| Function | Description | | -------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | getExchangeRate(code, options?): Promise<ExchangeRate> | Table A mid rate for one currency, for today or options.date | | getExchangeRates(options?): Promise<ExchangeRate[]> | Full table (A, B, or C) for today or options.date | | getGoldPrice(options?): Promise<{ price: number; date: string }> | NBP gold price (PLN per gram) | | convert(amount, from, to, options?): Promise<number> | Converts an amount between two currencies via PLN (table A mid rates) | | NbpError | Thrown for invalid input, network failures, or non-OK API responses |

All NBP functions throw NbpError for an invalid 3-letter currency code, a malformed date (must be YYYY-MM-DD), a 404 (e.g. no table published for that date), or a network failure. None of them are tested against the live API — the test suite mocks fetch so CI runs deterministically offline.

Holidays and working days (holidays)

| Function | Description | | ----------------------------------------------- | --------------------------------------------------------------------- | | getHolidays(year): Holiday[] | All Polish statutory public holidays for a year, sorted chronologically | | isHoliday(date): boolean | Whether a Date or YYYY-MM-DD string is a public holiday | | isWorkingDay(date): boolean | true unless the date is a weekend or a public holiday | | addWorkingDays(date, n): Date | Adds (or subtracts, for negative n) n working days | | workingDaysBetween(start, end): number | Counts working days strictly between two dates (order-independent) | | getEaster(year): Date | Easter Sunday for a year (Meeus/Jones/Butcher algorithm) |

Moving holidays (Easter Sunday and Monday, Pentecost +49 days, Corpus Christi +60 days) are derived from getEaster, not hardcoded per year.

VAT (vat)

| Function | Description | | ---------------------------------------- | ------------------------------------------------------- | | VAT_RATES | { STANDARD: 23, REDUCED_8: 8, REDUCED_5: 5, ZERO: 0 } | | addVat(net, rate): number | Adds VAT to a net amount, returning the gross amount | | removeVat(gross, rate): number | Removes VAT from a gross amount, returning the net amount | | vatAmount(net, rate): number | The VAT amount itself | | netToGross(net, rate): number | Alias for addVat | | grossToNet(gross, rate): number | Alias for removeVat | | roundToGrosze(value): number | Float-safe rounding to two decimal places (grosze) |

All amounts are rounded to grosze (two decimal places) using a float-safe rounding helper, avoiding classic IEEE-754 issues like 1.005 * 100 not rounding as expected.

Formatting (format)

| Function | Description | | ------------------------------------------------------------------ | ------------------------------------------------------------------- | | formatPln(amount, options?): string | Formats a number as 1 234,56 zł (Polish locale, Intl.NumberFormat) | | parsePln(str): number | Parses a formatted PLN string back into a number |

formatPln accepts { decimals?: number; symbol?: boolean }. Note that the thousands separator is a non-breaking space (U+00A0), matching Intl.NumberFormat('pl-PL') output — parsePln accepts both regular and non-breaking spaces.

🇵🇱 Po polsku

@m8t-jacob/pln-utils to biblioteka narzędzi finansowych dla Polski: klient kursów walut NBP, polskie dni ustawowo wolne od pracy i dni robocze, kalkulacje VAT oraz formatowanie kwot w PLN. Moduł nbp korzysta z globalnego fetch (Node.js 20+) i wymaga dostępu do sieci; pozostałe moduły (holidays, vat, format) to czysta logika bez zależności i bez operacji I/O. Święta ruchome (Wielkanoc, Zielone Świątki, Boże Ciało) są wyliczane algorytmem Gaussa/Meeusa, a nie zapisane na sztywno dla każdego roku.

Contributing

Contributions are welcome! See CONTRIBUTING.md for the development workflow and GOOD_FIRST_ISSUES.md for ideas if you're looking for a place to start. This project follows the Contributor Covenant.

License

MIT © 2026 Jakub Jagiełło