dorkhub

moji

find and download fonts from the terminal

Microck
Go2074 forksMITupdated 5 days ago
visit the demogit clone https://github.com/Microck/moji.gitMicrock/moji
moji

moji

npm version badge npm total downloads badge ci badge MIT license badge

moji.mov

ask for a font and get the file you actually meant. moji searches across font sources, ranks candidates by family and filename, and downloads the best match. browse interactively with Bubble Tea, pipe a stable table into shell workflows, or request JSON for programmatic use.

quick start

install with the package manager you already use:

npm install -g @microck/moji
pnpm add -g @microck/moji
bun add -g @microck/moji

search for a family:

moji
# or jump straight to results
moji "Futura"

bare moji opens the home TUI so you can type a query. pass a query to jump straight to the live result list. redirect or pipe a queried command to get a stable table instead.

moji "Futura" --format otf,ttf
moji "Futura" --format woff2 --json

download the best match, preview the choice first, or ask for the whole family:

moji get "Futura bold" --dry-run
moji get "Futura bold"
moji get "Futura entire family" --download-dir ~/Downloads/moji

convert a local desktop font to WOFF2, or restore a WOFF2 font to the TTF or OTF flavor stored inside it:

moji convert Inter.ttf
moji convert Inter.woff2
moji convert Inter.otf --to woff2 --output build/Inter.woff2

conversion detects the input from its content and never replaces an existing output file. it changes the font container without changing TrueType or CFF glyph outlines.

inspect a downloaded TTF, OTF, or WOFF2 font before using it:

moji inspect Inter.ttf
moji inspect Inter.woff2 --json

inspection reads the font's character map and reports exact Unicode script coverage counts. This answers whether a font includes Cyrillic, Arabic, Han, or another script without relying on its filename.

providers

the default GetFonts and registry providers work without an account. GitHub's repository, tree, and release search also uses its small unauthenticated allowance. Moji automatically uses an existing authenticated gh session when GitHub CLI is installed. GITHUB_TOKEN and github_token take precedence and also enable Code Search and higher limits. the TUI points this out when GitHub search is limited.

the websearch provider automatically uses kagi-cli when it is installed. Run kagi auth once. Ordinary web pages are ignored. direct CSS font URLs and bounded ZIP or TAR archive members can become results. configured source plugins pass through the same HTTPS, format, and download validation boundary. Direct binary responses with missing or misleading extensions can also be recognized as ZIP, TAR, or compressed TAR archives by signature; webpages and interactive download flows remain excluded.

export GITHUB_TOKEN=github_pat_example
moji "Futura" --provider github

do not pass tokens as command-line flags. use --token-stdin when a token only needs to exist for one invocation.

the same websearch provider also uses SearXNG when an instance URL is configured.

commands

command purpose
moji open the home TUI and type a font query
moji <query> search interactively or print a table when piped
moji get <query> rank results and download the best match
moji convert <input> convert TTF/OTF to WOFF2 or restore WOFF2
moji inspect <input> report Unicode script coverage for a local font
moji config create the default config when needed and open $EDITOR
moji config show print the current config with its token redacted
moji cache clear remove cached provider results

run moji --help for the complete flag and example reference.

download safety

downloads use HTTPS by default and stop at 50 MiB. before the final file appears, moji validates its font magic bytes, sanitizes its filename, writes to a temporary path, and renames it atomically. SHA-256 hashes prevent duplicate files from being saved twice.

If the first ranked link returns invalid font bytes, moji get remembers that URL and tries the next candidate. Whole-family downloads validate one coherent same-source group in staging, so a broken member cannot leave a partial family or mix sources.

search results include source and best-effort license metadata. an unknown license is not permission to use or redistribute a font. check the font's license before shipping it.

configuration

the default config lives at ~/.moji/config.yaml and is written with mode 0600. set MOJI_CONFIG to use a different file.

download_dir: ~/Downloads/moji
search_timeout_seconds: 15
cache_ttl_seconds: 3600
default_formats: [otf, ttf, woff2, dfont, pfb, pfm]
source_plugins: []

providers:
  github:
    enabled: true
  getfonts:
    enabled: true
  registry:
    enabled: true
  websearch:
    enabled: true
    instance: ""

documentation

the Fumadocs site covers the complete workflow:

the original product and architecture research remains in research/cli-design.md.

development

verify the Go CLI and production documentation build together:

npm install
npm run verify

run the parts independently when working on one side of the repository:

make verify
npm run docs:check
npm run docs:build
npm run docs:dev

Before a release, npm run release rebuilds and verifies the exact npm archive without publishing it. The operator-only npm run release:publish runs the same gate before npm publication, the annotated tag, and the GitHub release. See the release runbook.

the end-to-end suite builds the real binary, searches a controlled HTTP provider, downloads a valid fixture font, checks the file on disk, and exercises cache clearing. conversion tests use FontTools fixtures, and CI runs a pinned FontTools interoperability check in both directions.

license

MIT

more like this

search

search projects, people, and tags