@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.
Maintainers
Readme
@m8t-jacob/pln-utils
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-utilsQuickstart
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
