Skip to content

ivan-podgurskiy/humanizer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Humanizer

Hex.pm Hex Docs CI License: MIT

Human-friendly formatting for Elixir. One flat module of pure functions that turn raw values into the strings you actually show to people — file sizes, durations, relative time, large numbers, thousands separators, ordinals, string truncation and list enumerations.

English-only, zero configuration, no global state. Replaces a handful of single-purpose dependencies (filesize, humanize_time, ad-hoc helpers) with one.

Installation

Add humanizer to your mix.exs:

def deps do
  [
    {:humanizer, "~> 0.2.0"}
  ]
end

Documentation is on HexDocs.

Quick start

Humanizer.bytes(2_456_789)
# => "2.5 MB"
Humanizer.bytes(2_456_789, system: :binary)
# => "2.3 MiB"

Humanizer.duration(3725)
# => "1 hour, 2 minutes"
Humanizer.duration(45, format: :short)
# => "45s"

Humanizer.relative_time(~U[2026-05-13 10:00:00Z], ~U[2026-05-15 10:00:00Z])
# => "2 days ago"
Humanizer.relative_time(~U[2026-05-13 10:00:00Z], ~U[2026-05-15 10:00:00Z], format: :short)
# => "2d ago"

Humanizer.number(1_234_567)
# => "1.2M"
Humanizer.delimit(1_234_567)
# => "1,234,567"

Humanizer.ordinal(23)
# => "23rd"

Humanizer.truncate("the quick brown fox", 9)
# => "the quic…"

Humanizer.list_join(["Alice", "Bob", "Charlie"])
# => "Alice, Bob and Charlie"
Humanizer.list_join(["Alice", "Bob", "Charlie", "Dave", "Eve"], max: 2)
# => "Alice, Bob and 3 others"

Every function takes its options as a keyword list — there is no Application env and nothing to configure globally.

API

Function Example Result
bytes/2 Humanizer.bytes(2_456_789) "2.5 MB"
duration/2 Humanizer.duration(3725) "1 hour, 2 minutes"
relative_time/2,3 Humanizer.relative_time(past, now) "2 days ago"
number/2 Humanizer.number(1_234_567) "1.2M"
delimit/2 Humanizer.delimit(1_234_567) "1,234,567"
ordinal/1 Humanizer.ordinal(23) "23rd"
truncate/3 Humanizer.truncate("the quick brown fox", 9) "the quic…"
list_join/2 Humanizer.list_join(["a", "b", "c"]) "a, b and c"

Numbers use one consistent rule: round-half-away-from-zero with a single fractional digit by default (override with :precision). Output is never in scientific notation, for any input up to 10 ** 15.

Localization

English only. This is deliberate. Real localization means pluralization, gender, grammatical cases and locale-specific decimal separators — a single bytes/1 under locales is a project of its own.

If you need serious internationalization, use ex_cldr and ex_cldr_numbers. Localization may arrive in a later version as an optional layer, but it is out of scope here.

Comparison

Humanizer is not "better than everything". It replaces four or five small dependencies with one, if English output is enough for you.

You need Use
One package for all small English formatting Humanizer
Only file sizes filesize, sizeable
Times/durations with i18n timex + manual localization
Pluralize, singularize, camel/snake case inflex
Full number/date localization (CLDR) ex_cldr + ex_cldr_numbers
Parsing human time back into values chronic

Roadmap

v0.2.0 added thousands separators, string truncation, list limits and richer relative time. Remaining planned work (an optional localization layer) is tracked in ROADMAP.md.

License

MIT. See LICENSE.

About

Human-friendly formatting for Elixir: bytes, durations, relative time, large numbers, ordinals and list joins. English-only, zero config.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages