CLI tool
letstri/druk avatar
letstri/druk

Druk: a terminal code editor in one self-contained binary

A code editor that lives in your terminal — one self-contained binary with tree-sitter syntax, language servers, git and extensions.

778 stars39 forksTypeScriptMIT

At a glance

What is it?
Druk ships as a single executable with tree-sitter syntax highlighting for 30+ languages, a fuzzy file opener, project search, git marks and a markdown preview. It is aimed at developers who want VS Code habits without leaving the terminal, and it is honest about what terminals cannot send.
Who is it for?
Druk suits developers who already live in a terminal and want a file tree, tabs, fuzzy open and project search without a second window; it is a poor fit if you rely on the mouse in a terminal that cannot report it, or if you need extension features the built-in set does not cover.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 9, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What druk solves, and for whom

Most terminal editors make you choose between two compromises. Either you get a fast modal editor with no file tree, no tabs and no fuzzy project search, or you get a full editor that needs a runtime installed before it will start. Druk takes the second path but removes the runtime: the README states it is one self-contained executable with nothing else to install, no Node and no Bun. That single sentence is the whole pitch. A developer on a fresh server, a container, or a locked-down laptop can fetch one file and have a file tree, tabs, search, git marks and syntax highlighting for 30+ languages.

The target user is someone who already works in a terminal and keeps a second window open only to browse and edit files. Druk is not trying to replace a full IDE for debugging, refactoring or extension-heavy workflows. The README describes the window as a file tree on the left, tabs along the top, the editor, and a status bar with the branch, unsaved state and cursor position. That is a deliberately small surface. If your work is mostly reading and editing files in a repository, the surface is enough. If your work is mostly running a debugger, it is not.

How druk is built: Bun, OpenTUI and tree-sitter WASM

The repository layout tells you more than the README does. The source is TypeScript under src/, built with bun build.ts, and the dependencies are @opentui/core and @opentui/solid for the terminal UI, solid-js for the component layer, and tree-sitter-wasms for syntax highlighting. The presence of a file named OPENTUI-TRADEOFFS.md at the top level is worth noting: the project keeps a written record of what the OpenTUI dependency costs, rather than presenting the choice as free. fast-png and jpeg-js are also dependencies, which fits the screenshot in the README and the image handling the editor implies.

The architecture is a compiled binary wrapping a Bun runtime, not a shell script that calls out to an installed interpreter. That is why the install section can say no Node and no Bun are needed even though the package.json declares a Bun build pipeline. It also explains the extension story: there is an extensions/ directory and an extensions build script, and the README lists git, language servers and extensions in the project description. The npm and bun packages are described as a launcher that downloads that same binary on install, so the package manager path and the install script path converge on one artifact.

Installing druk and opening a first file

The install script is the shortest path. The README gives this exact command, and it puts the binary in ~/.druk/bin and adds it to your PATH:

bash
curl -fsSL https://druk.letstri.dev/install | bash

If you prefer a package manager, Homebrew, npm and bun are all listed. The npm and bun packages install a launcher that downloads the binary, so they behave the same once installed:

bash
brew install letstri/tap/druk

On Debian or Ubuntu the README points at the .deb on the releases page and gives sudo dpkg -i druk_*.deb; on Fedora or openSUSE it is the .rpm with sudo rpm -U druk-*.rpm. macOS on arm64 and x64, Linux on arm64 and x64, and Windows on x64 are the listed platforms. To pin a version with the script, the README shows a --version flag; --no-modify-path keeps your shell config untouched.

Once installed, opening a project takes one argument. With no argument druk opens the current directory:

bash
druk ./my-app
druk src/main.ts:42:7

The second form opens a single file at line 42, column 7. The README notes that when you give druk a file it opens with the sidebar hidden, and Ctrl+B brings the tree back; the folder around the file is still the project for search and git. That detail matters because it means file-level invocation does not break project search. If you want to try it without installing, npx druk and bunx druk are documented as working without an install.

The keyboard model, and the terminal limitations behind it

Druk leans on the command palette rather than expecting you to memorize a shortcut table. F1, or Ctrl+Shift+P where the terminal can send it, opens a palette where typing filters every feature. Ctrl+P opens any file in the project with fuzzy matching, described as working as in VS Code. Ctrl+K peeks at every key that works in the current pane and disappears on the next keypress. Ctrl+T switches between open tabs. The tree has its own single-key bindings: a for a new file, A for a new folder, r to rename, d to delete, x to cut, c to copy, p to paste.

The project is unusually explicit about terminal constraints. Most terminals cannot distinguish Ctrl+Shift from plain Ctrl, so druk spells a second modifier as Ctrl+Opt, and terminals with the kitty keyboard protocol accept Ctrl+Shift as well. The README names macOS Terminal.app as one terminal that cannot send Ctrl+/ at all, which is why Toggle comment also answers to Ctrl+L. Ctrl+C copies when text is selected and quits when nothing is, so it never discards unsaved work. These are not marketing points; they are the kind of detail that decides whether an editor feels broken on your machine. If your terminal is in the group that cannot report a key, the fallback binding is documented, and if it is not, the palette is the escape hatch.

Search, previews and the review workflow

Search is split in two. Ctrl+F searches the open file and Ctrl+R searches the project, with Ctrl+Opt+F as an alternative for vim mode where Ctrl+R is redo. Whatever text you had selected is already in the box. Results are grouped by file with line numbers and the matching line, and Tab folds the file you are on so one file with forty hits stops burying the rest. In file search, Tab opens the replace field, Enter replaces the selected match, and Ctrl+A replaces every match in the file.

The part worth calling out is that search outlives its panel. Ctrl+F reopens carrying the last query on the last match, with the text selected so typing replaces it. If you have text selected in the editor, that selection wins instead. This is a small design decision with a clear rationale: closing the panel to look at the file and reopening it should cost nothing.

Three other features round out the editing loop. Opening a file from the tree previews it in an italic tab that the next file replaces; double-clicking or editing makes the tab permanent. Ctrl+Opt+M toggles a markdown file between rendered and source views, and the README states it renders the buffer, so unsaved edits appear without saving. Ctrl+Opt+G opens a source-control panel for commit and push, and Ctrl+Opt+R opens a review panel with notes and pull-request comments, with Ctrl+Opt+A to note the current line. That review panel is the most opinionated feature in the README: it assumes you review code in the same window you edit it.

Where druk is the wrong tool

The README does not document rollback, and it does not document what happens when the install script is run in an environment where ~/.druk/bin is not writable or PATH cannot be modified. The --no-modify-path flag exists, but the README does not say what you are expected to do afterward. The npm and bun packages download a binary at install time, which means the first install depends on reaching GitHub; DRUK_DOWNLOAD_BASE is documented as a mirror escape hatch, but the README does not describe the failure mode when the mirror is also unreachable.

The larger limitation is the terminal itself. Mouse support is advertised, but it depends on the terminal reporting mouse events, and the README's own notes about Ctrl+Shift and Ctrl+/ show the project is working within what terminals can send rather than around it. If you work over a terminal multiplexer or a remote session with unusual key handling, the shortcut table is a starting point, not a guarantee. The clipboard is documented as using OSC52 over SSH, which some terminals and some SSH configurations restrict.

Finally, druk is not a debugger and the README does not present it as one. There is no mention of breakpoints, a test runner UI, or a diff view beyond the source-control panel. If your daily work depends on those, a terminal editor with a small built-in feature set will not carry it. And if you need a plugin ecosystem, the extensions directory and build script exist, but the README does not document an extension API or a marketplace, so you cannot assume the breadth of a mature editor.

Druk compared with Helix

Helix is the natural comparison for anyone considering a terminal editor today. The difference in approach is the interaction model, not the language support. Helix is modal: you select first, then act, and the selection is the object you operate on. Druk is not described as modal anywhere in the README; it is described as keyboard and mouse driven, with a file tree, tabs, a command palette on F1, and Ctrl+P fuzzy file opening that the README explicitly likens to VS Code. The muscle memory you bring from a GUI editor transfers more or less intact, including Ctrl+S, Ctrl+Z and Ctrl+F.

That is a real trade. A modal editor gives experienced users a compact grammar for text objects and motions that a non-modal editor has to express through selection and commands. Druk's answer is the palette and the Ctrl+K peek strip, which lists every key that works right now. Whether that is enough depends on how much of your editing speed comes from modal motions. If it does, Helix is the better fit. If your speed comes from fuzzy file opening, project-wide search and a visible file tree, druk's model is closer to what you already do. The other difference is packaging: druk's README makes the single-binary, no-runtime claim central, and that is a deployment argument as much as an editing one.

Maintenance, upgrades and the MIT licence

The last push to the repository was on 2026-09-15, and v1.28.0 was released the same day, with v1.27.2 and v1.27.1 in the two days before that. The repository is not archived. That release cadence is the strongest signal available about how the project is run, and it is worth checking again before you commit to it, because a terminal editor is a daily-use tool and a stalled one is expensive to migrate away from.

Upgrades are handled by the binary itself. The README states that druk update works out how this copy was installed, whether Homebrew, the install script, or a global npm, pnpm, yarn or bun package, and runs that upgrade after printing the command first. Printing the command before running it is the right call for a tool that can modify your PATH and your global package state. The README does not document a downgrade path or a way to pin an installed copy to an older version after the fact, though the install script accepts --version 1.0.1 as an example.

The licence is MIT, which is permissive and places few obligations on how you redistribute or embed the binary. Two files at the top level, THIRD_PARTY_NOTICES.md and LICENSE, are where the actual terms and the bundled dependency notices live; read them before shipping druk inside a product, since the MIT licence covers druk itself but not necessarily every dependency the binary links. That is a factual pointer, not legal advice.

Editorial conclusion

Druk suits developers who already live in a terminal and want a file tree, tabs, fuzzy open and project search without a second window; it is a poor fit if you rely on the mouse in a terminal that cannot report it, or if you need extension features the built-in set does not cover. Before adopting it, verify three things on your own machine: that your terminal forwards Ctrl+Shift (or accept Ctrl+Opt as the second modifier), that the Opt/Alt line commands are not swallowed by your window manager, and that druk update detects your install method correctly. The npm and bun packages are launchers that download the same binary, so the DRUK_DOWNLOAD_BASE mirror variable is the first thing to check if GitHub is unreachable from your network.

Frequently asked questions

Does druk need Node or Bun installed?

No. The README states druk is one self-contained executable with nothing else to install, no Node and no Bun. The npm and bun packages are a launcher that downloads that same binary on install.

How do I upgrade druk after installing it?

Run druk update. The README says it works out how this copy was installed, whether Homebrew, the install script, or a global npm, pnpm, yarn or bun package, and runs that upgrade, printing the command first.

Can I open a file at a specific line with druk?

Yes. The README gives druk src/main.ts:42 to open at line 42 and druk src/main.ts:42:7 to open at line 42, column 7. When you give druk a file it opens with the sidebar hidden, and Ctrl+B brings the tree back.

Official sources

  1. letstri/druk on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/letstri-druk.svg)](https://hysenlabs.com/projects/letstri-druk)