For the work that matters.

A fast, native text editor for macOS.

Apple Silicon · macOS 13.2+ · Changelog · Releases

Fast

Responsive editing, from small files to millions of lines.

View benchmarks →

Local

Your files, configuration, and tools stay under your control.

Explore local AI →

Focused

Everything you need to edit, nothing to get in your way.

Explore features →

peeknext.py
 22960   # EditorContainer : _on_tab_label_clicked
 22961   @func_trace
 22962  def _on_tab_label_clicked(self):
 22963       editor = ensure_not_deleted(self.main_editor.editor)
 22964      if editor is not None:
 22965           safe_focus(editor)
 22966  
 22967   # EditorContainer : _on_tab_label_toggle
 22968   @func_trace
 22969  def _on_tab_label_toggle(self):
 22970       window = ensure_not_deleted(self.window)
 22971      if window is None:
 22972           return
 22973  
 22974       buffer = self.buffer
 22975      if buffer is None:
 22976           return
 22977  
 22978       window.buffer_manager.toggle_active(buffer)
 22979  
 22980   # EditorContainer : _on_tab_label_exclusive
 22981   @func_trace
 22982  def _on_tab_label_exclusive(self):
 22983       window = ensure_not_deleted(self.window)
 22984      if window is None:
 22985           return
 22986  
 22987       buffer = self.buffer
 22988      if buffer is None:
 22989           return
 22990  
 22991       window.buffer_manager.set_as_active_tab(buffer)
 22992  
 22993   # EditorContainer : _file_changed
 22994   @func_trace
 22995  def _file_changed(self, *_): [97 lines folded]
 23093  
 23094   # EditorContainer : _do_after_file_changed
 23095   @func_trace
 23096  def _do_after_file_changed(self): [5 lines folded]
 10373       directory = os.path.dirname(path) or "."
 10374       tmp_path = None
 10375  
 10376       os.makedirs(directory, exist_ok=True)
 10377  
 10378       fd, tmp_path = tempfile.mkstemp(dir=directory, prefix=".tmp_")
 10379  
 10380      try:
 10381          with os.fdopen(fd, "w", encoding="utf-8") as f:
 10382               f.write(text)
 10383               f.flush()
 10384               os.fsync(f.fileno())
 10385  
 10386           os.replace(tmp_path, path)
 10387           tmp_path = None
 10388  
 10389      finally:
 10390          if tmp_path is not None:
 10391              try:
 10392                   os.remove(tmp_path)
 10393              except OSError:
 10394                   pass
 10395  
 10396   # CodeEditor : _save_file
 10397   # @func_trace
 10398  def _save_file(self): [113 lines folded]
 10512  
 10513   # CodeEditor : _save_shadow_file
 10514   @func_trace
 10515  def _save_shadow_file(self): [18 lines folded]
 10534  
 10535   # CodeEditor : save_file_as
 10536   @plugin_api
 10537   @command("Save file as...")
 10538  def save_file_as(self): [20 lines folded]
 10559  
 10560   # CodeEditor : save_file_copy_as
 10561   @plugin_api
 10562   @command("Save copy of file as...")
 10563  def save_file_copy_as(self): [20 lines folded]
~/Desktop/peeknext peeknext.py indexer.py todo.org Line 22,974, Column 29 Python

In a world of agents, be human.

Software is changing. Understanding it still matters. Peeknext keeps developers close to their code, whether you're writing it yourself or working alongside agents.

Our vision →

At the speed of thought.

Peeknext is built around a native C++ editing core, with responsiveness treated as a constraint rather than an optimization added later.

From everyday source files to millions of lines, Peeknext is designed to maintain consistently low editing latency.

Performance isn't just a promise. It's measured on real source files and documented through reproducible benchmarks.

View features →

CLexer.cpp
  267   // enter new state
  268  
  269  if (sc.state == SCE_HACK_DEFAULT) {
  270       // numbers
  271      if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
  272           sc.SetState(SCE_HACK_NUMBER);
  273       }
  274       // identifiers
  275      else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch) || (sc.ch == '@'))) {
  276           sc.SetState(State_Identifier);
  277       }
  278       // block comment
  279      else if (sc.Match('/', '*')) {
  280           sc.SetState(State_BlockComment);
  281           sc.Forward();
  282       }
  283       // line comments
  284      else if (sc.Match('/', '/')) {
  285           sc.SetState(State_LineComment);
  286       }
  287       // strings
  288      else if (sc.ch == '\"') {
  289           sc.SetState(SCE_HACK_STRING);
  290           isIncludePreprocessor = false;
  291       }
  292       // includes
  293      else if (isIncludePreprocessor && sc.ch == '<') {
  294           sc.SetState(SCE_HACK_STRING);
  295       }
  296       // characters
  297      else if (sc.ch == '\'') {
  298           sc.SetState(State_Character);
~/hackerman/lexers CLexer.cpp clexer.sip Line 199, Column 22 C

Measured, not claimed

16.6 ms

P95 typing latency in a 753,821-line source file.

20M lines

Largest syntax-highlighted file tested.

698 MB

Memory usage when editing a 5-million-line source file.

Benchmarks →
dsl.py
  15   types
  16       int
  17       float
  18   arguments
  19       out     : stdin to use previous output as input
  20               : stdout to print
  21   """
  22  
  23   program = """
  24   Module add 1 2 3 type=float out=stdin
  25   Module sub stdin 1 2 type=int out=stdout
  26   """
  27  
  28   # Module definition
  29  class Module:
  30  
  31       # Add function
  32      def add(*args, **kwargs):
  33           type_ = globals()["__builtins__"].getattr(globals()["__builtins__"], kwargs["type"])
  34           
  35  
  36       # Sub function
  37      def sub(*args, **kwargs):
  38           type_ = globals()["__builtins__"].getattr(globals()["__builtins__"], kwargs["type"])
  39           return float(args[0]) if type_ == 'float' else int(args[0]) - sum(map(type_, args[1:]))
  40  
  41  def get_args(tokens, STDIN): [18 lines folded]
  60  
  61  def interpret(program): [25 lines folded]
  87  
  88   interpret(program) # 3
  89  
~/Desktop qwen2.5-coder:1.5b Line 34, Column 9 C

Everything stays yours.

Your files, your tools, your machine.

Peeknext works directly with local files and indexes, without relying on cloud services. Context-aware autocomplete works without a language server, while optional AI features integrate with Ollama.

No accounts, no telemetry, and no internet connection required.

View features →

Privacy by design

No telemetry. No tracking. No background downloads. Not even an auto-updater.

Offline mode not required.

Less interface. More work.

A powerful editor doesn't need a complicated interface.

Peeknext keeps your code at the center, with useful tools available when you need them. Run shell commands, execute Python, or work with local AI directly from your document.

No unnecessary panels, complex workflows, or distractions. Just a familiar text editor with more beneath the surface.

View features →

Untitled
   9     ////////////////////////`     Resolution: 3440x1440 
   10    -+++++++++++++++++++++++`      DE: Aqua
   11    /++++++++++++++++++++++/       WM: Quartz Compositor
   12    /sssssssssssssssssssssss.      WM Theme: Graphite (Dark)
   13    :ssssssssssssssssssssssss-     Font: MenloRegular
   14     osssssssssssssssssssssssso/`  Disk: 375G / 494G (83%)
   15     `syyyyyyyyyyyyyyyyyyyyyyyy+`  CPU: Apple M2 Pro
   16      `ossssssssssssssssssssss/    GPU: Apple M2 Pro 
   17        :ooooooooooooooooooo+.     RAM: 1914MiB / 16384MiB
   18         `:+oo+/:-..-:/+o+/-      
   19  
   20   % git log --oneline -5
   21   7e43c91 Fix stale index results after file changes
   22   20b9ad4 Add PHP symbols to file outline
   23   e3816fc Preserve cursor position when reopening files
   24   9ad0c72 Reduce allocations while indexing large files
   25   615bc84 Fix split view restoring the wrong document
   26   
   27   > Summarize these changes for the changelog.
 
 ## Editor

 - Added PHP symbols to the file outline.
 - Cursor position is now preserved when reopening files.
 - Fixed split views occasionally restoring the wrong document.

 ## Performance and reliability

 - Reduced memory allocations while indexing large files.
 - Fixed stale autocomplete results after files changed on disk.


   1  
   2   # This is the default scripts-file for Peeknext
   3  
   4   @command("Word count")
   5  def word_count():
   6       import re
   7  
   8       text = selected_text()
   9       count = len(re.findall(r"\b[\w'-]+\b", text))
  10  
  11       message (f"Word count: {count:,} words")
  12  
  13   @command("Insert UUID")
  14  def insert_uuid(): [2 lines folded]
  17  
  18   @command("Markdown: Selection to link")
  19  def insert_link(): [2 lines folded]
  22   
  23   @command("Markdown: Insert unchecked box")
  24  def insert_unchecked_box(): [1 lines folded]
  26   
  27   @command("Markdown: Wrap selection in fenced block")
  28  def fenced_block(): [2 lines folded]
  31  
  32   @command("Markdown: Bold")
  33  def make_bold():
  34       text = selected_text()
  35       insert_text(text=f"**{text}**")
  36  
  37   
  38   
  39   
~/peeknext _ .hackerman-scripts glm-5.3-flash:cloud Generic-Default

Reasons to use Peeknext

Zero-latency typing

Peeknext maintains a measured P95 typing latency of 17.86 ms while editing a 1 million-line Odin source file with syntax highlighting enabled.

Read more →

Local AI, on your Mac

Peeknext works directly with local Ollama models, with no account, telemetry, or cloud intermediary. Use local code completion and inline AI while keeping your code and inference on your Mac.

Read more →

Native macOS code editors

A look at code editors built specifically for macOS, from long-running editors like BBEdit and TextMate to newer alternatives like Nova, CodeEdit, and Peeknext.

Read more →

Plain text note taking

Keep notes as ordinary Markdown, plain text, Org Mode, or other files. Open directly into your notes folder, search with ripgrep, and organize everything without a proprietary database.

Read more →

An editor, not an environment.

Not every editor needs to become an IDE. Peeknext focuses on editing, leaving you free to choose everything else.

Simple, straightforward licensing

All features included. Free for non-commercial use, with simple licensing for professional and organizational use.

Professional

$195* $325 40% off

One-time purchase.

Buy professional

Teams

$795 /year

Up to 10 users per license, with shared deployment.

Buy for teams

Business

$79 /user/year

Flexible licensing for organizations of any size.

Contact sales

*Early adopter pricing with lifetime updates.

Compare plans →

Roadmap

What we're currently working on and have planned.

Submit feature request

File preview in file explorer

Diff preview as second split pane

Writer mode with focused interface

Optional variable fonts sizes and wikilinks

Faster search in very large files

One command palette for all dialogs

Built-in language support

Fast, native syntax highlighting for dozens of programming languages.

Peeknext combines custom C++ lexers with established Lexilla implementations, keeping highlighting responsive even in large files.

Language-aware folding and symbol navigation make it easier to work with complex source files.

Ada Lexilla

AsciiDoc Lexilla

Asm

Bash Lexilla

C

Clojure

CMake Lexilla

CSS Lexilla

C++

D

Dart Lexilla

Diff

Elixir

Erlang Lexilla

Fortran Lexilla

F# Lexilla

Gleam

Go

Haskell Lexilla

HTML

Jai

Java

JavaScript

Julia Lexilla

JSON Lexilla

LaTeX Lexilla

Lisp Lexilla

Lua Lexilla

Makefile Lexilla

Markdown

MATLAB

Mojo

Nim Lexilla

Nix Lexilla

OCaml Lexilla

Odin

Org

Pascal Lexilla

Perl

PHP

Python

R Lexilla

Ruby Lexilla

Rust

SQL Lexilla

Swift

Tcl Lexilla

TOML Lexilla

TypeScript

Typst

WAT

YAML

Zig

Latest from Peeknext

Development updates, technical notes, and occasional thoughts on software.

IDEs are dead. Long live the text editor.

Could AI agents make traditional text editors more relevant than increasingly complex IDEs?

Read more →

Bye, bye custom lexer feature

Some behind-the-scenes upgrades to Qt, Scintilla, and Peeknext's lexer system.

Read more →

Koi is now Peeknext

Koi Editor and Hackerman are now Peeknext, with a shared name and visual identity.

Read more →