2023-05-08, updated: 2023-05-13

Tags: release.

Nyxt 3.0.0

Nyxt 3.0.0

After working on 3.0.0 for approximately two years, it is finally here.

Happy Hacking :-)

Obligatory screenshots:

Note: many of the links below are designed to be opened in Nyxt.



New features

  • Add Flatpak build.
  • New migration-guide command to help the user migrate their configuration between major version releases. Migration suggestions are automatically given on startup error.
  • The auto-config file is now suffixed with the major version number. This means that upgrading Nyxt to a new major version will ignore the previous auto-configuration (which probably wouldn't work anyways).
  • UserScript support (such as GreaseMonkey scripts).
  • Prompt buffer updated for intuitive matching with new algorithms and settings.
  • Revamp status buffer design for increased readability and aesthetics. Make it fully customizable with format-status framework.
  • Status buffer placement can be changed with status-buffer-position (thanks to @mianmoreno)
  • Most help pages, including the manual are more readable and interactive.
  • Add support for the Gopher and Gemini protocols.
  • Headless mode available through --headless CLI switch. Config file (--config ) becomes the script to run in the headless instance on Nyxt.
  • Color-picker support when native-dialogs are on.
  • New hinting-type setting to configure one's favorite link hints style (Vimium-style vs. body-matching prompts). Thanks to @heiwiper!
  • Hinting now highlights hints by dimming the matched characters (thanks to @heiwiper!)
  • Session is restored on startup by default. Slot session-restore-prompt has been replaced by restore-session-on-startup-p , a boolean.
  • reduce-tracking-mode clears widely known tracking query parameters.
  • Add a %slot-value% value to define-configuration to allow configuration to compose from different define-configuration forms.
  • execute-command ( C-space ) evaluates arbitrary Lisp code and provides inline documentation for symbols.
  • New prediction capabilities. Nyxt can now predict your next command, it will show up automatically in the execute-command menu. Nyxt uses a stochastic model to generate predictions for what your next command will be. The model is stored locally and is cleared after every session.
  • Support for key files and Yubikey locking in KeePassXC password interface.
  • History globality can be set on a per-buffer basis. See the global-history-p .
  • backtrack-to-hubs-p allows to revisit the "hub" URLs you often visit, instead of adding them to history anew.
  • When started with --remote and without --quit , Nyxt now reads s-expression from standard input and sends it to the remote process. This avoids the performance penalty of a new process startup on each iteration.
  • define-configuration automatically resolves class names and slot names even without package prefix. For instance :style-mode -> nyxt/mode/style:style-mode .
  • Keybindings are also resolved to existing commands when necessary. For instance :jump-to-heading -> nyxt/mode/document:jump-to-heading .
  • after-init-hook and after-startup-hook are browser slots, instead of the global variables they used to be.
  • Universal describe-* commands have been replaced with new sources for the regular commands, such as function-non-nyxt-source , function-internal-source and so on.
  • The browser class has a profile slot.
  • With dynamic-attribute-width-p on, prompt buffer attribute columns adjust to their content, allowing for a better overview of lengthy attributes.
  • Search engines are now listed with their full name (when available).
  • Internal buffers/pages are now rendered in the status area as internal .

Prompt buffer improvements


New modes


New commands



  • auto-mode is incorporated into Nyxt core, with its settings residing in modable-buffer .
    • The new apply-all-matching-auto-rules-p allows you to apply all the matching auto-rules instead of the most specific one.
    • There are default rules for Gopher, Gemini, and Nyxt-internal-pages.
    • The rules file is now moved toauto-rules.lisp (instead of the old auto-mode-rules.lisp ).
  • Major search-buffer-mode refactor. The new implementation is more accurate and more flexible, as it allows manipulating matches as Lisp objects.
  • Major improvement of editor-mode .

Moves and removals

  • Move the prompter library to a separate repository.
  • Some of the Nyxt-internal logic was abstracted into separate libraries/systems:
    • define-class macro — to nclasses .
    • Portable GUI-friendly debugger — to ndebug .
    • JSON parsing — to njson .
    • Symbol search and listing — to nsymbols .
  • Move lisp-system to separate repository as extension. The functions list-system and load-system are no longer available.
  • Move os-package-manager-mode to separate repository as extension.
  • diff-mode has been removed.

Bug fixes

  • Lisp code run with the --script or --eval command line arguments now defaults to the nyxt-user package.
  • Various spell-check-mode fixes. (Thanks to @hendursaga!)
  • All copying and pasting commands populate clipboard-ring reliably, thus fixing the paste-from-clipboard-ring ( M-v ) command.
  • Fix touchscreen gestures for VI mode.
  • Fix processing via relative paths when opening files.
  • Fix buffer re-attachment from the deleted window.
  • Fix history-backwards ( UNBOUND ) by gracefully handling pages that are not yet done loading.
  • Fix full-screening event handling — status buffer no longer goes off-sync with the full-screened page/video.
  • Startup is more robust against corrupted history files.
  • VI insert mode is triggered in more cases where it should be triggered.
  • Invoke the right WebKit command when cutting text with ffi-buffer-cut .
  • Fix the display of history suggestions when going forward in history.
  • Security: all the non-ASCII domain names are shown as IDN punycodes in addition to aesthetic display in the status buffer.
  • The canceled page requests are stored to history, making it more consistent.
  • Extensions directory is more carefully checked to avoid crashes.
  • Trying to delete a hanged buffer destroys it, instead of leaving it dangling forever.
  • Switching focus away from Nyxt doesn't make it unfullscreen anymore (thanks to @shaunsingh!)
  • Fix select-frame-new-buffer ( UNBOUND ) and select-frame-expedition ( UNBOUND ) .
  • Numerous documentation and functionality fixes thanks to @shamazmazum, @hendursaga, @Gavinok, @mianmoreno, @edgar-vincent, @K1D77A, @kchanqvq, @tiberious726, @createyourpersonalaccount, @khinsen, @aaron-tan, @chrisboeg, @taiju, @odanoburu, @wasamasa, @fabian-thomas, @shakatoday, @grawlinson, @kenranunderscore, @Uthar, @e0a6, @comradekingu, @whirm, and others!





Programming interface

  • Internal pages are now using the nyxt URL scheme. They support the lisp protocol to allow evaluating arbitrary Lisp, for instance from a button click. Internal pages also have a URL now, which means they have history support.
  • New define-internal-page-command and define-internal-page-command-global helpers to define internal pages.
  • define-panel-command and define-panel-command-global helpers to define new panels.
  • New define-internal-scheme helper to define custom schemes.
  • Nyxt-native debugger available via toggle-debug-on-error ( UNBOUND ) .
  • Better Lisp values inspection in describe-* commands and repl ( UNBOUND ) , extensible through value->html methods.
  • Universaldescribe-* commands describing things in any Nyxt-accessible package. Available via C-h u key prefix.
  • after-startup-hook to attach headless mode actions or configuration to.
  • Thread name is now mandatory in run-thread .
  • New nyxt-unstable *features* when built from source on an untagged commit. A feature with the commit is also added.
  • New prompt1 helper.
  • New theme library.
  • Input processing is now easier to customize with command-dispatcher and input-skip-dispatcher .
  • Rename buffer slot load-status to status .
  • The core nyxt packages are now locked to prevent against accidental clobbering from the user side.
  • New ffi-buffer-load-html and ffi-buffer-load-alternate-html . This is useful to set the buffer content without resorting to expensive JavaScript calls.
  • Removed clipboard-text since it's redundant with ffi-buffer-copy .
  • General purpose helpers can be found in the nyxt/utilities package.
  • New nxref Spinneret tag for cross-referencing.
  • if-confirm now allows configuring its yes/no options and can return booleans.
  • Move download hooks to download enabling proper typing and adding handlers to them.
  • Spinneret tags like :nxref , :nbutton , :ninput , :nselect , :ncode , :nsection , :ntoc for better help pages markup enhanced by the compiler data.
  • All mode packages have been renamed to nyxt/mode/mode-name .
  • Renderers are now first class objects, see the renderer class. It's possible to change renderer from a same REPL session.
  • set-url ( C-l ) and set-url-new-buffer ( M-l ) accept the :URL keyword argument and load it when provided.
  • New ffi-height and ffi-width methods to unify most of the height & width methods used before.
  • Generate methods instead of functions in define-parenscript and define-parenscript-async to ease hooking into those with, for example, :around methods.
  • Allow the command argument to ffi-add-context-menu-command to be an arbitrary function.
  • New package nicknames:
    • time for local-time
    • types for trivial-types
    • sym for nsymbols
  • The third value in the object-attributes attribute list is interpreted as display HTML for the suggestion. See the color-picker support as an example application for this feature.
  • New match-port URL designator predicate for auto-rules.

Did you enjoy this article? Register for our newsletter to receive the latest hacker news from the world of Lisp and browsers!