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
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.
Why not use the various standard and commonplace packaging and distribution methods for application software? Distro repos, tarballs, Homebrew, AppImage, Flatpak, etc.
- 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
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
strange thinking!
https://www.youtube.com/playlist?list=PL9KpW-9Hl_het1V3_dLhG...
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 =)
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 :)
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
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).
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
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!
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.
Thank you :)
Keep up the good work !
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)
So I opted for explicit management of chunks, also gives me more control and consistent cross platform behavior.