Skip to content
dnfPublic

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Sayable

License: MIT

A thoughtful collection of libraries for how humans actually speak.

Sayable is a family of zero-dependency formatting libraries. Each library tackles a different aspect of human-friendly output — the kind of phrasing people use in conversation, not the kind machines produce.

Libraries

age date duration time
What it does Formats ages the way parents talk Formats dates the way people reference them Formats durations and relative time Formats clock time conversationally
Example "14 months" · "4½ years" "last Tuesday" · "3 days ago" "about 2 hours" "quarter past 3"
Languages 51 51 51 51
Locales 168 168 168 168

Language support

All 51 languages have identical implementations across all 4 libraries:

Ada, Bash, C, C#, C++, Clojure, COBOL, Common Lisp, Crystal, D, Dart, Elixir, Elm, Erlang, F#, Fortran, Gleam, Go, Goose, Groovy, Haskell, Janet, Java, Julia, Kotlin, Lua, Mojo, Nim, OCaml, Octave, Odin, Pascal, Perl, Pharo, PHP, PowerShell, Prolog, Python, R, Racket, Raku, Ruby, Rust, Scala, Swift, Tcl, TypeScript, V, VB.NET, Wren, Zig

See the full compatibility matrix.

Locale coverage

See the locale coverage maps for a visual breakdown of how well Sayable's locales cover each country's languages.

World locale coverage

Design principles

  • Zero dependencies. Pure standard-library code in every language.
  • Polyglot. Identical implementations across languages, sharing canonical test cases and locale data.
  • Localization-first. Culture-aware output with CLDR-compliant plural rules.
  • Deterministic. All tests use explicit inputs — no flaky tests from system state.

Development

Getting started

Develop and test natively on macOS/Linux or inside a Docker container. Either way you need just and hecatron, the separate tool that installs, checks and repairs each language's toolchain and runs the per-language commands. Sayable's side of it is .hecatron/: the project config and each language's test, lint, build and clean hooks. Until hecatron has a Homebrew formula, use a checkout:

brew install just                # or your package manager's just
git clone https://github.com/dnf/hecatron ~/hecatron
export PATH="${HOME}/hecatron/bin:${PATH}"   # add to your shell profile

Native setup

hecatron bootstrap       # base packages + every language toolchain (macOS or Ubuntu/Debian)
hecatron doctor          # check every toolchain works; --fix repairs

Docker (no local toolchains)

./tools/docker-test.sh          # build the image (age/Dockerfile) and run every test suite
./tools/docker-test.sh bash     # interactive shell inside the container

Install or uninstall individual languages:

just install go          # single language
just install ts py rb    # multiple (aliases work)
just install             # all languages
just uninstall go        # remove a language

Commands

A top-level justfile provides a single entry point:

just test                # run all test suites + codegen check
just test go             # one language's tests, all four libraries
just test go -c age      # one language, one library
just test cli            # canonical tests through every language's CLI
just build               # build all compiled languages
just lint                # run all linters
just doctor              # check every toolchain works (--fix repairs)
just generate locales    # regenerate locale files from canonical JSON
just check               # verify generated files are up-to-date
just --list              # see all available commands

Contributing

See CONTRIBUTING.md for guidelines. All implementations share identical test cases — changes to formatting logic must be applied to all languages.

License

MIT

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages