● 0.31.0 MIT Rust

Modal editor.
Reusable engine.

A vim-style editor in Rust — and the engine that powers it.

Multi-buffer TUI editor with fuzzy file/buffer/grep pickers, lazygit-adjacent <leader>g git surface (status, log, branches, file history, stash, tags, remotes), tree-sitter highlighting via runtime-loaded grammars (hjkl-bonsai 0.7), the new backend-agnostic hjkl-theme + hjkl-theme-tui stack, marks / macros / dot-repeat / @: last-ex repeat, and focus-regain disk auto-reload. Same vim FSM (hjkl-vim) drives sqeel, buffr, inbx.

hjkl — ~/code/hjkl
main.rs
  1 // vim FSM driving a rope buffer.
  2 use hjkl_engine::{Editor, Host};
  3 use hjkl_buffer::Rope;
  4 
  5 fn main() -> io::Result<()> {
  6     let mut ed = Editor::<Rope, _>::new(TuiHost);
  7     ed.open("src/main.rs")?;
  8 
  9     while let Some(key) = ed.poll()? {
 10         ed.feed(key);
 11     }
 12     Ok(())
 13 }
NORMAL main.rs 10:21

why

One vim, many surfaces.

01 — REUSE

One FSM, many surfaces

Same FSM that drives sqeel, hjkl, and inbx drives the standalone hjkl editor.

02 — PURE

No I/O in the core

Bring your own renderer, your own clipboard, your own filesystem. The engine just transitions states.

03 — PORTABLE

Pure Rust, host-agnostic

The engine doesn't pin a renderer, clipboard, or filesystem. Same crate drives ratatui TUIs, GPU-composited overlays, and egui windows.

04 — TYPED

Trait-driven

Buffers, clipboards, search providers — all traits. Swap implementations without touching the FSM.

05 — TESTED

Property-tested

Rope invariants hold under any edit sequence. Vim grammar regression-suite covers motions, operators, text objects, and ex commands.

06 — OPEN

MIT, all of it

Every crate, every adapter. Fork it, vendor it, ship it. No catch.

crates

One binary. Twelve ecosystem crates. Each in its own repo.

hjkl
binary · TUI app

The standalone editor. cargo install hjkl — multi-buffer, pickers, tree-sitter, smart indent, .editorconfig.

hjkl-engine
core · controller

Pure controller: cursor, motions, operators, registers, marks, macros. No I/O deps. The vim FSM was extracted to hjkl-vim in 0.7 — the engine just executes primitives now.

hjkl-vim
core · vim FSM

The vim grammar reducer. Pending-state machine for chords (m<x>, q<x>, @<x>, 5dd, "a5dd), count accumulator, dot-repeat, @: last-ex replay. hjkl_vim::handle_key is the canonical FSM entry point.

hjkl-buffer
data · rope

Rope-backed text buffer with cursor, edits, and undo tree. O(log n) inserts and deletes.

hjkl-editor
std · glue

Engine + buffer + registers + ex commands wired together. The "ready-to-host" surface.

hjkl-bonsai
std · highlighting

Runtime grammar loader. Clones, compiles, and caches tree-sitter-* grammars on demand. Bare and @-prefixed capture names both resolve; lua-match? / not-lua-match? predicates built in. Comment-marker overlay (TODO/FIXME/NOTE/WARN). Re-exports hjkl_theme::StyleSpec — zero grammars baked in.

hjkl-theme
core · theming

Backend-agnostic theme schema. TOML parse, palette interning, tree-sitter capture fallback chain. StyleSpec shared between bonsai, hjkl, and any downstream renderer.

hjkl-theme-tui
optional · adapter

ToRatatui extension trait — converts hjkl_theme::Color / Modifiers / StyleSpec into ratatui types. Drop into any TUI.

hjkl-picker
std · UI

Fuzzy picker subsystem. Picker, PickerLogic, FileSource, RgSource, scorer. Reusable across hosts.

hjkl-form
std · UI

Single-line form input built on the engine. Powers : / / prompts and picker query lines.

hjkl-config
std · loader

Shared TOML config loader. XDG path resolution, span-aware parse errors, opt-in Validate hook, layered defaults + user overrides.

hjkl-clipboard
std · adapter

System clipboard adapter. Bridges "+ / "* registers to the OS pasteboard.

hjkl-ratatui
optional · adapter

Ratatui Style adapters, KeyEvent conversions, and a shared braille spinner. Drop into any TUI.

install

Prebuilt binaries on every tagged release.

macOS via Homebrew tap, Arch via AUR, or grab a prebuilt binary. Linux (x86_64, aarch64) — .tar.gz / .deb / .rpm / .apk / musl. macOS (Apple Silicon, Intel) — .tar.gz. Windows (x64) — .zip. SHA-256 sidecars on every artifact.

hjkl — macOS (Homebrew)
$ brew install kryptic-sh/tap/hjkl
$ hjkl
hjkl — Arch Linux (AUR)
$ yay -S hjkl-bin
$ paru -S hjkl-bin
hjkl — Alpine Linux
# download .apk from releases page, then:
$ apk add --allow-untrusted hjkl-*.apk
$ hjkl
hjkl — from source
# crates.io
$ cargo install hjkl

# or build from the repo
$ git clone https://github.com/kryptic-sh/hjkl
$ cd hjkl
$ cargo build --release