Library / SDK
Rhymond/go-money avatar
Rhymond/go-money

Rhymond/go-money: precise currency values for Go applications

Go implementation of Fowler's Money pattern

1,913 stars166 forksGoMIT

At a glance

What is it?
Rhymond/go-money is a Go library for Fowler's Money pattern, storing currency values in integer minor units and supporting arithmetic, comparison, formatting, splitting, and ratio allocation. It suits applications that need predictable calculations, but it is not a full accounting or payment system.
Who is it for?
Go developers should adopt Rhymond/go-money for application-level amounts, especially when integer minor units and deterministic allocation matter. They should not treat it as a replacement for an accounting ledger, payment gateway, or currency conversion service.
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 177 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

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

From daily snapshots

Star history

  • Rhymond/go-money1,913 ★ · +0
Star history
Repository2026-10-162026-10-23
Rhymond/go-money1.9k1.9k

0 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Why Rhymond/go-money stores minor units

Rhymond/go-money addresses a specific problem in Go applications: calculating monetary amounts without the small rounding differences introduced by floating-point values. Its central `Money` type stores an amount together with a currency. The README states that the amount is represented as an integer in the currency's smallest unit, so `money.New(100, money.GBP)` represents one pound.

This model is appropriate for prices, invoices, order totals, refunds, and other values that must remain precise through several calculations. It is aimed at developers who want currency carried with a value instead of passing a bare number between functions. The attached currency also gives arithmetic and comparison methods a basis for rejecting incompatible operands.

The scope stops there. The README does not document exchange rates, tax calculation, bank settlement, payment authorization, journal entries, or a complete accounting workflow. Although the repository contains `db.go`, its contents are not explained in the README, so no persistence API can be confirmed from the available project documentation. Developers should classify this package as a monetary value and calculation library rather than a financial system.

The Money value model and currency checks

The library exposes two connected structures. `Money` represents a monetary value with its currency, while `Money.Amount` encapsulates the information for a monetary unit. A `Money.Currency` instance carries the currency definition. The README says the package uses ISO 4217 currency codes and provides constants for all ISO 4217 codes, including values such as `money.GBP` and `money.EUR`.

Currency is not merely presentation data in this model. Arithmetic and comparison require matching currency units. The documented example shows `twoPounds.Equals(twoEuros)` returning `false` together with an error because the currencies differ. `Compare` can return `ErrCurrencyMismatch`. This gives the caller an explicit failure instead of allowing a pound amount to be treated as interchangeable with a euro amount.

Comparison methods include `Equals`, `GreaterThan`, `GreaterThanOrEqual`, `LessThan`, `LessThanOrEqual`, and `Compare`. Assertions include `IsZero`, `IsPositive`, and `IsNegative`. These operations let business rules distinguish zero and signed amounts without extracting a numeric field and reimplementing each comparison. The README does not explain behavior for malformed or unsupported currency instances, so applications should not assume validation rules that it does not state.

Arithmetic, splitting, and ratio allocation

Rhymond/go-money provides arithmetic through `Add`, `Subtract`, `Multiply`, `Absolute`, and `Negative`. Its examples return `Money` results and handle errors where the operation can fail. Addition and subtraction accept another monetary value, while multiplication uses an integer factor. Comparisons and operations require the same currency units.

Division is treated as allocation instead of ordinary floating-point division. `Split(n)` divides an amount among n parties and distributes leftover minor units in round-robin order. The README says parties listed first will likely receive the extra units. Splitting 100 GBP minor units among three parties produces `£0.34`, `£0.33`, and `£0.33`. The distributed values still add up to the original amount.

`Allocate` applies ratios and uses the same round-robin treatment for leftover units. The documented call `Allocate(33, 33, 33)` produces `£0.34`, `£0.33`, and `£0.33`. Ratios may be passed as separate integer arguments or as a slice. These methods are useful when shares must preserve every minor unit. The README does not state how zero ratios, negative ratios, or a party count of zero are handled, so those edge cases should be verified before relying on them in business rules.

Display formatting and the float64 boundary

Formatting is separate from the internal calculation model. `Display()` returns a formatted currency string. The README shows `money.New(123456789, money.EUR).Display()` producing `€1,234,567.89`, with grouping separators and a major-unit decimal value.

For interfaces that require a numeric major-unit value, `AsMajorUnits()` returns a `float64`. The documented example turns `123456789` EUR minor units into `1234567.89`. This can be convenient at an API or display boundary, but it gives up the integer representation that prevents binary floating-point rounding errors. Calculations should remain in `Money`; conversion should occur only when an external interface requires major units.

The README does not document locale selection, custom formats, configurable decimal places, or a mechanism for selecting among multiple formatting policies. It also does not document currency exchange. `AsMajorUnits()` changes representation, not currency. A service that must accept USD and charge EUR needs a separate rate source and policy, neither of which is specified by this project.

Installing Rhymond/go-money and running its first calculation

The README's quick start directs users to fetch the module with Go's package command. The `go.mod` file declares the module path as `github.com/Rhymond/go-money` and sets the Go language version to 1.13.

Use the documented installation command:

bash
$ go get github.com/Rhymond/go-money

The first example creates one pound, adds that value to itself, and splits the result among three parties. Errors from `Add` and `Split` are sent to `log.Fatal`.

go
package main

import (
  "log"
  "github.com/Rhymond/go-money"
)

func main() {
    pound := money.New(100, money.GBP)
    twoPounds, err := pound.Add(pound)
    if err != nil {
        log.Fatal(err)
    }
    parties, err := twoPounds.Split(3)
    if err != nil {
        log.Fatal(err)
    }
    parties[0].Display()
}

The README shows the three displayed shares as `£0.67`, `£0.67`, and `£0.66`. The repository also defines a race-enabled test command in the `Makefile`:

bash
$ go test -v -race ./...

The README does not give a module-creation tutorial or document a release-specific installation procedure beyond `go get`.

Maintenance signals, releases, and the MIT license

The GitHub repository is not archived, and its last push was on 2026-04-29. The listed releases are `v1.0.15` from 2025-04-30, `v1.0.14` from 2024-07-29, and `v1.0.13` from 2024-06-13. These records show recent repository activity and a versioned release history. They do not establish compatibility with every Go toolchain or describe a future maintenance commitment.

The `go.mod` file declares `go 1.13`, which is the module's language version rather than a promise that development has stopped on older syntax. Consumers should review their own supported Go versions and inspect release changes before pinning a version. The README does not document a semantic versioning policy, deprecation process, migration guide, or support schedule.

The project uses the MIT License. That license permits use, copying, modification, merging, publication, distribution, sublicensing, and sale, subject to its notice and warranty conditions. This is not legal advice. The repository's `LICENSE` file contains the controlling terms. Upgrade work is limited by the absence of documented migration notes, but version pinning and review of changes between releases remain necessary.

Limits of go-money and the role of an alternative

The main limitation is scope. Rhymond/go-money handles a monetary amount and its currency, but the README does not claim to manage accounts, payment authorization, settlement, refunds, tax, exchange rates, or an audit trail. Merely attaching `Money.Currency` to a value does not supply rates or external transaction state.

It is also the wrong abstraction for calculations that freely pass through `float64`. The library's principal design choice is integer minor units. Calling `AsMajorUnits()` and continuing the calculation in `float64` removes that protection. `Display()` produces presentation output and should not serve as a localized accounting format.

A real alternative is to use a dedicated accounting system or payment service alongside this library. The architectural difference is concrete: Rhymond/go-money represents and calculates amounts in memory, while an accounting component records journal entries and a payment processor handles authorization and settlement. The README does not name a competing Go package, so selecting one would require evidence beyond this project. Developers should first inspect `db.go` and the currency definitions because the README does not document their public behavior. If those files do not satisfy persistence and currency requirements, the library can still serve as an internal value type, but it cannot replace the missing financial infrastructure.

Editorial conclusion

Go developers should adopt Rhymond/go-money for application-level amounts, especially when integer minor units and deterministic allocation matter. They should not treat it as a replacement for an accounting ledger, payment gateway, or currency conversion service. Verify first that its currency constants, formatting rules, error handling, and persistence model fit the application. The README does not document exchange rates or transaction settlement, which makes those external dependencies an adoption boundary.

Frequently asked questions

How do I install Rhymond/go-money?

The README uses `go get github.com/Rhymond/go-money`. The `go.mod` file declares the same module path and sets the Go language version to 1.13.

How should I initialize a monetary value in Rhymond/go-money?

Use `money.New` with an integer amount in the currency's smallest unit, such as `money.New(100, money.GBP)`. The README also shows `money.NewFromFloat(0.25, money.EUR)` for direct major-unit initialization.

Does Rhymond/go-money support currency conversion?

The README does not document exchange-rate lookup or conversion between different currencies. Operations involving different currencies can instead produce a currency mismatch error.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. Rhymond/go-money on GitHub
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/rhymond-go-money.svg)](https://hysenlabs.com/projects/rhymond-go-money)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/rhymond-go-money.svg)](https://hysenlabs.com/projects/rhymond-go-money)

Was this useful?