English · 简体中文
JSRay code rendering for the terminal · ANSI truecolor · 35 language families · zero dependencies
Public beta · bundles a JSRay Core snapshot
This repository is the standalone terminal CLI project around JSRay Core — an official open-source integration in the JSRay ecosystem, with its own version and release notes.
It bundles a snapshot of Core (vendor/jsray.cjs) rather than depending on it at runtime, so the CLI keeps working exactly as shipped until a sync deliberately advances it.
jsray renders code in the terminal with ANSI colors, powered by the same tokenizer and the same palettes as every other JSRay surface: JSRay.tokenize() produces a renderer-agnostic token stream, and this project maps it to ANSI escape sequences instead of HTML spans. Nine-family separation included — parameters italic amber, declarations bold mint, keywords bold.
- 35 language families (everything Core supports), auto-detected from the file extension, filename (
Dockerfile,Makefile), or content - 4 palettes × dark/light: default, aurora, ember, fjord — the variant matches your terminal's background, asked rather than assumed
- Truecolor by default, with xterm-256 downsampling and plain-text fallback; piped output degrades to plain automatically
- Zero dependencies — plain Node ≥ 20
jsray src/app.py # highlight a file
cat query.sql | jsray # stdin, auto-detected
jsray notes.md --theme aurora # pick a palette
jsray config.toml --mode light # override the detected variant
jsray server.go -n # line numbers
jsray build.log --color none # force plain
jsray --list-languages # everything Core supports
jsray --list-themesLanguage resolution order: --lang → file extension → special filenames → JSRay.detectLanguage() on the content. Undetectable input degrades to plain text, never an error.
Color resolution: --color auto (default) uses truecolor when COLORTERM advertises it, xterm-256 otherwise, and plain text when stdout is not a TTY. Override with --color truecolor|256|none.
Variant resolution: --mode if given, else COLORFGBG, else the terminal's own answer to an OSC 11 background query. A terminal that does not answer gets the dark variant. This matters more than it sounds: the dark palette on a white background puts 21 of its 25 colors under 3:1 contrast.
npm i -g github:jsrayorg/jsray-terminalThere is no build step and there are no dependencies, so installing from the repository gives you the same files a registry install would.
jsray --verify-core # confirm the bundled engine against Core's digestsFrom a clone, for development:
npm link # exposes `jsray` on PATHjsray-terminal/
├── bin/jsray.mjs ← CLI: args, IO, language resolution
├── lib/ansi.mjs ← token stream → ANSI (truecolor / 256 / none)
├── vendor/jsray.cjs ← Core runtime snapshot — do not edit
├── palettes/ ← palette JSON synced from Core — do not edit
├── tools/ ← sync-core.sh · check-versions.mjs
└── tests/ ← node --test suites (renderer + end-to-end CLI)
After changing the Core project, rebuild Core dist/ (run sh build.sh there), then:
npm run sync:core # expects Core at ../jsray, or set JSRAY_CORE_DIRnpm run check:versions fails if the bundle drifts from a sibling Core checkout.
The CLI runs the bundled engine straight off disk, so the file rendering your
code is one careless npm install script away from being something else.
core-integrity.json pins the digests JSRay Core published for this snapshot,
and every run verifies them — hashing ~70KB costs far less than Node's own
startup.
jsray --verify-core
# official build verified — JSRay Core 0.0.2-beta.5, 6 filesA mismatch warns on stderr and still renders, so it can never contaminate a
pipeline; --verify-core exits non-zero for use in a script.
jsray app.js --palette ~/my-colors.json # layered over --theme
jsray app.js --theme fjord --palette ~/tweak.jsonTakes the same JSON every other JSRay surface uses — what the
Theme Studio exports — so one palette file
works in the terminal, on the web, and in the editor. Tokens you omit keep the
built-in palette's value. Keys are checked against the bundled vocabulary.json;
unknown ones (from a newer Core) are reported on stderr and skipped rather than
being fatal.
The ANSI layer consumes only the ecosystem token-stream contract (tokenize(code, lang) → strings and {type, content} nodes). Any renderer that produces this shape can be dropped into vendor/.
npm test
npm run check:versions