A look at tonsky/tongue: 315 stars on GitHub, written primarily in Clojure. Do-it-yourself i18n library for Clojure/Script
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
Tongue is a do-it-yourself i18n library for Clojure and ClojureScript.
Tongue is very simple yet capable:
Dictionaries are just Clojure maps.
Translations are either strings, template strings or arbitrary functions.
No additional build steps, no runtime resource loading.
It comes with no built-in knowledge of world locales. It has all the tooling for you to define locales yourself though.
Pure Clojure implementation, no dependencies.
Can be used from both Clojure and ClojureScript.
In contrast with other i18n solutions relying on complex and limiting string-based syntax for defining pluralization, wording, special cases etc, Tongue lets you use arbitrary functions. It gives you convenience, code reuse and endless possibilities.
As a result you have a library that handles exactly your case well with as much detail and precision as you need.
Who’s using Tongue?
Cognician, coaching platform
Logseq - Privacy-first, open source knowledge base
Setup
Add to project.clj:
[tongue "0.4.4"]
In production:
Add -Dclojure.spec.compile-asserts=false to JVM options (actual JVM on Clojure, during build on ClojureScript)
In development:
Add -Dclojure.spec.check-asserts=true to JVM options.
Usage
Define dictionaries:
(require '[tongue.core :as tongue])
(def dicts
{ :en { ;; simple keys
:color "Color"
:flower "Flower"
;; namespaced keys
:weather/rain "Rain"
:weather/clouds "Clouds"
;; nested maps will be unpacked into namespaced keys
;; this is purely for ease of dictionary writing
:animals { :dog "Dog" ;; => :animals/dog
:cat "Cat" } ;; => :animals/cat
;; substitutions
:welcome "Hello, {1}!"
:between "Value must be between {1} and {2}"
;; For using a map
:mail-title "{user}, {title} - Message received."
;; aliases, to share common strings but still use specific i18n keys
:frontpage-greeting :welcome
;; arbitrary functions
:count (fn [x]
(cond
(zero? x) "No items"
(= 1 x) "1 item"
:else "{1} items")) ;; you can return string with substitutions
;; optional -- override “Missing key” message
:tongue/missing-key "Missing key {1}"
}
:en-GB { :color "colour" } ;; sublang overrides
:tongue/fallback :en } ;; fallback locale key
(translate :en :color) ;; => "Color"
;; namespaced keys
(translate :en :animals/dog) ;; => "Dog", taken from { :en { :animals { :dog "Dog }}}
;; substitutions
(translate :en :welcome "Nikita") ;; => "Hello, Nikita!"
(translate :en :between 0 100) ;; => "Value must be between 0 and 100"
(translate :en :mail-title {:user "Tom" :title "New message"}) ;; => "Tom, New message - Message received."
;; if key resolves to fn, it will be called with provided arguments
(translate :en :count 0) ;; => "No items"
(translate :en :count 1) ;; => "1 item"
(translate :en :count 2) ;; => "2 items"
;; multi-tag locales will fall back to more generic versions
;; :zh-Hans-CN will look in :zh-Hans-CN first, then :zh-Hans, then :zh, then fallback locale
(translate :en-GB :color) ;; => "Colour", taken from :en-GB
(translate :en-GB :flower) ;; => "Flower", taken from :en
;; if there’s no locale or no key in locale, fallback locale is used
(translate :ru :color) ;; => "Color", taken from :en as a fallback locale
;; if nothing can be found at all
(translate :en :unknown) ;; => "|Missing key :unknown|"
Localizing numbers
Tongue can help you build localized number formatters:
The dictionary can contain other kinds of values. In that case, interpolation
must be defined for the type by implementing the tongue.core/IInterpolate
interface:
No homepage URL was recorded for tonsky/tongue in TopGit's last sync. The README tab above frequently contains screenshots and demo links, or check the repository description on GitHub.
Does tonsky/tongue have any tags?
TopGit's last sync did not record any GitHub topics for tonsky/tongue. GitHub topics appear in the right sidebar of a repository page; that's the authoritative place to check.
How active is development on tonsky/tongue?
The most recent commit recorded on tonsky/tongue was 11 months ago, based on the GitHub push timestamp. The repository has 21 forks — one of the better signals of community interest.
Is tonsky/tongue open source?
Yes — tonsky/tongue ships under the EPL-1.0 license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/tonsky/tongue.
What license does tonsky/tongue use?
tonsky/tongue is released under the EPL-1.0 license. Always verify the LICENSE file directly on GitHub for the authoritative terms — license strings can be edited out of sync with a project's actual stance.
Where do I read more about tonsky/tongue?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/tonsky/tongue is the definitive source.
Read full README in the tab above.
Want a second opinion on tongue?
Ask an AI that can read this page — one click and you get its take on tongue.