Library / SDK
lmammino/financial avatar
lmammino/financial

financial is a numpy-financial port that keeps to scalar numbers

A Zero-dependency TypeScript/JavaScript financial library (based on numpy-financial) for Node.js, Deno and the browser

726 stars23 forksTypeScriptMIT

At a glance

What is it?
financial is a zero-dependency TypeScript library that reimplements the numpy-financial functions for Node.js, Deno, Bun and the browser, with no array support and no arbitrary-precision decimals. It is a good fit for spreadsheet-sized finance code and a poor fit for anything where cent-level rounding has to be exact.
Who is it for?
Use financial when you need the standard time-value-of-money formulas inside a JavaScript or TypeScript codebase and do not want to take a dependency, especially if the same code has to run in Node, Deno and the browser. Do not use it where exact decimal arithmetic is required, because the library works on IEEE doubles with no decimal type and no rounding policy.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 154 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The same functions as numpy-financial, without arrays

financial is a zero-dependency TypeScript and JavaScript financial utility library inspired by numpy-financial, usable on Node.js, Deno, Bun and the browser.

The README is explicit about the two things it gives up. It supports the same functionality offered by numpy-financial, but it only supports scalar JavaScript number values, with no numpy-like array values, and it does not support arbitrary-precision signed decimal numbers such as decimal.js, big.js or bignumber.js.

That second limitation is the one that decides whether the library is appropriate for your use case. numpy-financial is a Python library, and the Python ecosystem around it treats Decimal as a first-class citizen for money. This port cannot, because JavaScript has one numeric type for this purpose and it is a double. Anything that needs exact decimal representation of a rate, a payment schedule or a discount factor has to bring its own decimal library, and this package will not be the one providing it.

The dependency count is the other headline. There are no runtime dependencies at all, and the package is published to npm, with the repository also carrying a deno.json, a deno.lock and a jsr.json, so the same source is consumable from three package ecosystems.

Installing it and computing a future value

Installation is one command in either of the two common package managers.

bash
npm install --save-dev financial
bash
yarn add financial

The usage is a single named import and a function call.

js
import { fv } from 'financial'

fv(0.05 / 12, 10 * 12, -100, -100) // 15692.928894335748

The arguments follow the numpy-financial convention, with a rate, a number of periods, a present value and a payment, all in the same sign convention where the outflows are negative. The result is the future value of a loan of 100 paid monthly for ten years at five percent annual interest.

The package metadata sets the Node requirement at 18 or newer through the engines field, and the main entry points are dist/index.js for CommonJS, dist/index.d.ts for the typings and dist/financial.esm.js for the module build. The published files are the dist and src directories, which means the TypeScript source is shipped alongside the bundle.

That last point is worth knowing when something behaves unexpectedly. The src directory is in the package, so a stack trace in a bug report can point at original source rather than at minified output.

CommonJS, ESM and a browser bundle, but no default export

The library exports its functionality in several module formats, and the differences between them are documented one by one.

For CommonJS, the whole namespace can be required, or the individual functions can be destructured.

js
const financial = require('financial') // ./index.js

// use `financial.fv`, `financial.pmt`, etc.
js
const { fv, pmt } = require('financial') // ./index.js

// use `fv`, `pmt`, etc.

The ESM form, which also works with TypeScript, imports the functions by name.

js
import { fv, pmt } from 'financial'

// use `fv`, `pmt`, etc.

The README calls out a detail that trips up bundler configurations: there is no default export in the ESM implementation, so you have to explicitly import the functionality you need, one by one. A default-import attempt fails at build time rather than at runtime, which is at least a clear error.

For the browser there is an optimized CommonJS build that can be loaded straight from a CDN.

html
<script src="https://www.npmcdn.com/[email protected]/dist/financial.cjs.production.min.js"></script>

The README notes that you must replace the x.y.z placeholder with the version you actually want, which is a reminder that this pattern pins nothing by default.

Deno and Bun consume the same source differently

Deno is a first-class target rather than an afterthought, and the README shows the import form.

typescript
import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'
import * as f from 'https://deno.land/x/npm:[email protected]/src/financial.ts'

assertEquals(f.fv(0.05 / 12, 10 * 12, -100, -100), 15692.928894335755)

The version is specified in the import URL, and the import points at the src/financial.ts file rather than at a bundled artefact, which means Deno consumes the TypeScript source directly.

That example also contains the most useful warning in the README, and it is easy to miss. The Node example earlier in the same document returns 15692.928894335748 for the identical call, while the Deno example asserts 15692.928894335755. The two differ in the last three digits. Nothing is broken: both are valid doubles, and the difference comes from how the arithmetic is evaluated in the two runtimes. If your code compares financial results with an exact equality assertion, or if a rounding boundary sits in that tail, this is the trap.

Bun is supported too, and the test scripts in the package metadata show how each runtime is exercised. There is a Node script that runs the tests with c8 for coverage over tsx, a Deno script that runs poku in parallel with the allow-env, allow-read and allow-run permissions, and a Bun script that runs poku in parallel. The Deno test entry point is also given for local use.

bash
deno test test/deno.ts

Ten functions, each with a version where it landed

The function list is short, complete, and annotated with the release each one arrived in, which tells you the shape of the project's growth.

The first cluster is the loan and annuity arithmetic: fv() for future value, pmt() for total payment, nper() for the number of period payments, ipmt() for the interest portion of a payment and ppmt() for the payment against loan principal. These date back to v0.0.12, with ppmt() added in v0.0.14.

The next group is discounting and rate solving: pv() for present value in v0.0.15, and rate() for the rate of interest per period in v0.0.16.

The last group is the investment-return functions: irr() for internal rate of return in v0.0.17, npv() for net present value in v0.0.18, and mirr() for modified internal rate of return in 0.1.0.

Every entry has full documentation on the published API site, and the programmatic typedoc output is built into a docs folder with the build:docs script.

What the list does not include is as informative as what it does. There is no array or vectorised form, no schedule generator that returns a table of payments over time, and no rounding or currency helper. If you need an amortisation table rather than a single number, you compute it by calling ipmt() and ppmt() per period yourself, and the rounding of each result becomes your responsibility.

MIT licensed, last published in 2024, last pushed in 2026

The licence is MIT, with the copyright line naming Luciano Mammino, and the LICENSE file at the root of the repository. For a library you are likely to vendor into a pricing page or a planning tool, that is the simplest possible answer, with no copyleft obligation and no attribution requirement in shipped output.

The maintenance record is the part to look at closely. The last release was v0.2.4 on 2024-07-20, with v0.2.3 published the same day a couple of minutes earlier and v0.2.2 on 2024-03-04. The last push was on 2026-05-22 and the repository is not archived, so work is happening on the source, but the published npm versions stopped in July 2024.

That gap is the practical risk. A project installed from npm today gets v0.2.4, which is the same code as the last release. The commits made afterwards are in the repository and reachable through the JSR or Deno paths, or by building from source, but they are not in the package most people install.

The development tooling suggests the project has moved on internally regardless. The repository carries a biome.json for linting and formatting, an .eslintrc.js, and a pnpm-lock.yaml, while the package metadata still names pnpm as the package manager. The build uses dts-cli to produce the type declarations and typedoc for the API documentation, and the bundle is produced with Rollup into CommonJS, UMD and ES Module formats.

Editorial conclusion

Use financial when you need the standard time-value-of-money formulas inside a JavaScript or TypeScript codebase and do not want to take a dependency, especially if the same code has to run in Node, Deno and the browser. Do not use it where exact decimal arithmetic is required, because the library works on IEEE doubles with no decimal type and no rounding policy. Before adopting, compare the fv() result in the README against your own tolerance, since the documented Node and Deno examples already differ in the last floating point digits.

Frequently asked questions

How do I install the financial library?

With npm, run npm install --save-dev financial, or with yarn, run yarn add financial. The package requires Node 18 or newer according to its engines field and has no runtime dependencies.

Does the financial library support arrays like numpy-financial?

No. It supports the same functionality as numpy-financial but only for scalar JavaScript number values, with no numpy-like array support.

Can financial handle arbitrary-precision money?

No. The README states that it does not support arbitrary-precision signed decimal numbers such as decimal.js, big.js or bignumber.js, so a project that needs exact decimal arithmetic has to bring its own decimal library.

Which functions does the financial library implement?

Ten: fv(), pmt(), nper(), ipmt(), ppmt(), pv(), rate(), irr(), npv() and mirr(), covering future value, payments, number of periods, interest and principal portions, present value, rate, internal rate of return, net present value and modified internal rate of return.

How do I use the financial library with Deno?

Import it with the version in the URL, for example import * as f from 'https://deno.land/x/npm:[email protected]/src/financial.ts'. The Deno test entry point is run with deno test test/deno.ts.

What licence does the financial library use?

It is licensed under the MIT License, with the terms in the LICENSE file at the root of the repository.

Official sources

  1. License: MIT
  2. lmammino/financial on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/lmammino-financial.svg)](https://hysenlabs.com/projects/lmammino-financial)

Was this useful?