Readit News logoReadit News
Posted by u/_sinelaw_ 2 months ago
Show HN: Fresh – A new terminal editor built in Rustsinelaw.github.io/fresh/...
I built Fresh to challenge the status quo that terminal editing must require a steep learning curve or endless configuration. My goal was to create a fast, resource-efficient TUI editor with the usability and features of a modern GUI editor (like a command palette, mouse support, and LSP integration).

Core Philosophy:

- Ease-of-Use: Fundamentally non-modal. Prioritizes standard keybindings and a minimal learning curve.

- Efficiency: Uses a lazy-loading piece tree to avoid loading huge files into RAM - reads only what's needed for user interactions. Coded in Rust.

- Extensibility: Uses TypeScript (via Deno) for plugins, making it accessible to a large developer base.

The Performance Challenge:

I focused on resource consumption and speed with large file support as a core feature. I did a quick benchmark loading a 2GB log file with ANSI color codes. Here is the comparison against other popular editors:

  - Fresh:   Load Time: *~600ms*     | Memory: *~36 MB*
  - Neovim:  Load Time: ~6.5 seconds | Memory: ~2 GB
  - Emacs:   Load Time: ~10 seconds  | Memory: ~2 GB
  - VS Code: Load Time: ~20 seconds  | Memory: OOM Killed (~4.3 GB available)
(Only Fresh rendered the ansi colors.)

Development process:

I embraced Claude Code and made an effort to get good mileage out of it. I gave it strong specific directions, especially in architecture / code structure / UX-sensitive areas. It required constant supervision and re-alignment, especially in the performance critical areas. Added very extensive tests (compared to my normal standards) to keep it aligned as the code grows. Especially, focused on end-to-end testing where I could easily enforce a specific behavior or user flow.

Fresh is an open-source project (GPL-2) seeking early adopters. You're welcome to send feedback, feature requests, and bug reports.

Website: https://sinelaw.github.io/fresh/

GitHub Repository: https://github.com/sinelaw/fresh

giancarlostoro · 2 months ago
I'm a little annoyed that for a Rust based tool the recommended installation command is to use npm. Why? Is Cargo not good enough? Cargo seems exceptionally well to me.
Barathkanna · 2 months ago
I get the frustration, but I think the npm option actually makes sense here. A lot of users who’d benefit from a fast Rust tool aren’t Rust developers and won’t have Cargo installed. Shipping it through npm lowers the barrier while still giving everyone the performance benefits. It’s not a knock on Cargo, just a way to make the tool more accessible.
ljm · 2 months ago
Given the fairly shoddy security story with NPM, I genuinely don't understand the hesitation to publish a binary and have a README instruction to curl/wget it into `/usr/local/bin` or `~/.local/bin`. If it's going through NPM that publishing step has to be done already, unless the NPM build is pulling down rust to compile it all as a native extension.

Eventually it'd wangle it's way into homebrew or the unstable branch of another package registry.

But that's me, because I really dislike installing binaries via a language's package manager, because they don't get updated unless I frequently run the upgrade commands for each package manager.

krageon · 2 months ago
Anything that uses npm is fundamentally untrustworthy. I would argue that if you make an editor you should write software for people that want to use and write good software, which isn't anyone that unironically uses npm with anything other than distaste.
Gormo · 2 months ago
Many of them may not be Node developers either, and might not have npm installed. Using a dependency management tool for one language to distribute a packaged application written in an entirely different language seems like a very strange choice.

Why not use the various standard and commonplace packaging and distribution methods for application software? Distro repos, tarballs, Homebrew, AppImage, Flatpak, etc.

knowitnone3 · 2 months ago
but you could also say a lot of users are web developers and won't have npm installed
hnarn · 2 months ago
npm is certainly not something everyone has.
_sinelaw_ · 2 months ago
I took the feedback and now you can install binaries in any of these methods:

- Homebrew (MacOS)

- Arch Linux AUR

- Debian/Ubuntu .deb

- Fedora/RHEL .rpm

as well as cargo install (which builds from source), npm, npx or building from source by cloning

psvn · 2 months ago
Can you add to cargo binstall to install directly binary?
port11 · 2 months ago
Can't it be packaged as a binary/whatever that would install without either cargo or npm?
_sinelaw_ · 2 months ago
You can use: cargo install fresh-editor

Or you can use npm

Or you can download release binary packages from Github releases.

The problem is which option to make more prominent / first

_sinelaw_ · 2 months ago
I did it because not everybody has cargo installed. I'm using cargo-dist to create this npm package.
LoganDark · 2 months ago
Is there a way to install it with cargo instead? I won't install npm on my machine just to install a Rust package
ulbu · 2 months ago
i don’t (and won’t) have npm installed. i do have cargo.

strange thinking!

giancarlostoro · 2 months ago
I've been wanting a generic package manager for a while that is cross-platform. I wonder how one could find funding for such a project. Thinking about users from various OS' installing tools and software from your niche package manager, yeah that bad boy is going to grind to a halt if you have no key funding.
baq · 2 months ago
consider wget or curl if possible (why not if npm was...)
alienpingu · 2 months ago
i just used npx to try on my working machine where i do not have cargo
fcoury · 2 months ago
Shameless plug: I did a series a couple years back, before AI was this huge, about writing a Vim-like editor in Rust, in case you want to play with it in the future:

https://www.youtube.com/playlist?list=PL9KpW-9Hl_het1V3_dLhG...

dualogy · 2 months ago
Goood stuff!

One of my long-standing "would make if I had the time and perseverance" themes has been a terminal text editor that's hugely VSCode-like + compatible, so always glad to hear anyone going anywhere near that, and hence I perked up from these:

> Prioritizes standard keybindings and a minimal learning curve.

> Extensibility: Uses TypeScript (via Deno) for plugins, making it accessible to a large developer base.

Because where you are now with Fresh, you're probably really not far from supporting say `settings.json`, `launch.json`, `tasks.json`, `keybindings.json`, `.tmTheme`s and theme `.json`s, and indeed bringing up a VSCode-API-implementing "extension host" that can load up and run/host most `.vsix`es. Now, being terminal-based you'd skip over certain feature subsets such as webviews, custom (non-text) editors and the like... and might postpone Notebooks and such fancies initially, but:

Consider! 1000s of high-value, capable, tech-specific dev extensions out there, all readily supported by your just-spawned new editor. Doesn't that sound pretty exciting?

After all, there's a huge subset of VSCode fans who'd always switch in a heartbeat to a just-simply-non-Electron version (whether native or terminal) of the very same feature-scape & extensions & UI dev experience if only it was made and to max compatibility (and MS won't ever do so).

All that's missing (from screenshot glance) is the other sidebars & panels in addition to File Explorer =)

Will be putting your Fresh on my Github Watch list, but then again, I never really read the GH feed anyway.. but maybe I'll remember to check back in every quarter or so =)

_sinelaw_ · 2 months ago
I've been mulling over vscode extension compatibility... There is a challenge there, because the API surface is non-trivial and some of it is "web-ish". I wouldn't want people to be disappointed if 60% of the plugins they try to use don't really work properly.

Also, there are nuances like VSCode exposing APIs that force the entire file to be in-memory (which is how VSCode works), this is fine but in my editor I'm trying to get extensions to work well even if the file is huge (encouraging incremental / partial stuff).

But yes, it's a very compelling vision... and part of the reason I chose TypeScript.

Thanks for the input :)

dig1 · 2 months ago
> I did a quick benchmark loading a 2GB log file with ANSI color codes... Emacs: Load Time: ~10 seconds | Memory: ~2 GB

Now try opening it in Emacs with vlf [1] ;) Great work overall — looking forward to seeing further development!

[1] https://elpa.gnu.org/packages/vlf.html

_sinelaw_ · 2 months ago
Didn't know about vlf!

It loads instantly, and memory usage is minimal <80 MB.

It does seem like vlf requires configuration and adjustment, e.g. navigation with the normal keys works differently (jumps to beginning/end of current chunk instead of the whole file). Basically it exposes the chunk concept to the user.

In Fresh it's designed into the core and should be more transparent (although there are still limitations).

arkensaw · 2 months ago
I tried it, I like it a lot, but I did find an issue straight away.

I'm on MacOS and I have remapped the fn and command keys so it can be more like Windows (I can't undo 20+ years of muscle memory, and also I just don't wanna)

Anyway, Fresh seems to ignore the remapping - it's back to the command key for copy/paste and the command palette.

Is there a way to access the dropdown menus by keyboard? I can see F underlined for File but no modifier key seems to make it happen

_sinelaw_ · 2 months ago
I'll need to look into this, not sure what remapping does to the incoming key events.

Also I'm already working on a ui for customizing the key bindings so you could do whatever you wanted. (Currently managed by undocumented json)

Thanks for reporting!

20after4 · 2 months ago
This is probably not your responsibility. Modifier keys and especially rebinding them are really in the realm of the OS and the Terminal emulator. The application really shouldn't have to do special things to accommodate Mac OS idiosyncrasies.
yearolinuxdsktp · 2 months ago
You have to turn on "Use Option as Meta Key" in your terminal app's keyboard settings. (Terminal.app has it under Profile/Keyboard)
_sinelaw_ · 2 months ago
Alt+F should open the File menu. I guess that's Option+F on MacOS. Does that work?
arkensaw · 2 months ago
no
20after4 · 2 months ago
Installed it and out of the box this is the best new TUI editor I've tried, probably ever. There are so many great editors out there but I've never been a fan of modal editing, despite recognizing it's incredible power. My brain just doesn't work that way, yet I'm highly keyboard focused and prefer terminal over gui for most things, especially text.

Great work on this! Very good performance but also a very good UX and you really nailed the discoverability / accessibility - basically everything works intuitively and needs very little explanation - this is something that I can't say about really any other editor I've tried.

This may finally replace nano as my default utility editor, if not my main IDE.

_sinelaw_ · 2 months ago
I built my UX on the shoulders of giants, inspired by WordPerfect 5, Turbo Pascal, and similar legendary heros of the early 90s. Plus a command palette like VSCode.

Thank you :)

az09mugen · 2 months ago
I just tested it and I must say congrats. I really enjoy the command palette, the open file menu and the multi cursor. It's well thought, really intuitive so far and I definitively will use it regularly (more once I setup the LSP).

Keep up the good work !

_sinelaw_ · 2 months ago
Thanks and if you encounter any issues (even minor annoyances) let me know (e.g. open a github issue), I want the experience to be smooth
Findecanor · 2 months ago
> Efficiency: Uses a lazy-loading piece tree to avoid loading huge files into RAM

I once started writing a text editor on Linux, and first went down a similar route: a piece table over a mmap()'d file. But I abandoned using mmap, because Linux file systems typically don't have mandatory locking enabled, so you can't be sure that the file data won't be modified by another program.

(Then I got bogged down in Unicode handling... so 95% of the code became just about that, and I tired of it)

_sinelaw_ · 2 months ago
I considered using mmap to help manage the caching but what if your file is hosted on S3 or whatever? (Something I'm planning to support eventually)

So I opted for explicit management of chunks, also gives me more control and consistent cross platform behavior.