Skip to main content
Fresh’s functionality can be extended with a powerful plugin system. Plugins are written in TypeScript and run in a sandboxed QuickJS environment (transpiled via oxc_transformer), providing full access to the editor’s API while maintaining security and performance.

What are Plugins?

Plugins are TypeScript files that extend the editor’s functionality by:
  • Registering custom commands and keybindings
  • Creating interactive panels and virtual buffers
  • Running external processes and tools
  • Integrating with LSP servers
  • Adding visual decorations and overlays
  • Responding to editor events

Plugin Architecture

TypeScript Runtime

Plugins are written in TypeScript and automatically transpiled to JavaScript using the blazing-fast oxc_transformer.

Sandboxed QuickJS

All plugins run in an isolated QuickJS environment, providing security and preventing plugins from interfering with each other.

Editor API

Access a comprehensive TypeScript API through the global editor object for all editor operations.

Async/Await Support

Native support for async/await allows plugins to spawn processes, make LSP requests, and perform I/O without blocking.

Available Plugins

Fresh ships with a rich collection of production-ready plugins:

Core Plugins

PluginDescription
welcome.tsDisplays welcome message on startup
manual_help.tsManual page and keyboard shortcuts display
diagnostics_panel.tsLSP diagnostics panel with navigation
search_replace.tsSearch and replace functionality
path_complete.tsPath completion in prompts

Git Integration

Powerful Git workflow integration:
PluginDescription
git_grep.tsInteractive search through git-tracked files
git_find_file.tsFuzzy file finder for git repositories
git_blame.tsGit blame view with commit navigation
git_log.tsGit log viewer with history browsing
git_gutter.tsShow git diff markers in the gutter

Code Enhancement

PluginDescription
todo_highlighter.tsHighlights TODO/FIXME/HACK keywords in comments
color_highlighter.tsHighlights color codes with their actual colors
find_references.tsFind references across the codebase
clangd_support.tsClangd-specific LSP features (switch header/source)

Language Support

Built-in LSP integration for multiple languages:

TypeScript/JavaScript

typescript-lsp.ts

Rust

rust-lsp.ts

Python

python-lsp.ts

Go

go-lsp.ts

C/C++

clangd-lsp.ts

Java

java-lsp.ts
And many more: css-lsp.ts, html-lsp.ts, json-lsp.ts, latex-lsp.ts, marksman-lsp.ts, zig-lsp.ts, odin-lsp.ts, templ-lsp.ts

Editing Modes

PluginDescription
markdown_compose.tsSemi-WYSIWYG markdown editing with soft breaks
merge_conflict.ts3-way merge conflict resolution
vi_mode.tsFull Vim emulation with modal editing

Advanced Features

PluginDescription
theme_editor.tsInteractive theme customization
pkg.tsBuilt-in package manager for plugins and themes
audit_mode.tsCode review and audit workflow
code-tour.tsGuided code tours and walkthroughs

Plugin Lifecycle

Plugins are loaded automatically when Fresh starts:
1

Discovery

All .ts files in the plugins/ directory are discovered at startup.
2

Transpilation

Each plugin is transpiled from TypeScript to JavaScript using oxc_transformer.
3

Execution

The transpiled JavaScript runs in a sandboxed QuickJS runtime with access to the editor API.
4

Registration

Plugins register commands, event handlers, and modes during initialization.
There is no explicit activation step. All plugins in the plugins/ directory are loaded automatically.

Core Concepts

The editor Object

The global editor object is the main entry point for the Fresh plugin API:
/// <reference path="../types/fresh.d.ts" />

// Access the editor API
editor.setStatus("Hello from my plugin!");
The editor object provides methods for:
  • Commands: Register custom actions in the command palette
  • Buffers: Read and modify text content
  • Overlays: Add visual decorations without changing content
  • Processes: Spawn external commands and tools
  • Events: Subscribe to editor state changes
  • LSP: Communicate with language servers
  • File System: Read/write files and directories

Commands

Commands are actions that appear in the command palette and can be bound to keys:
globalThis.my_action = function(): void {
  editor.setStatus("Command executed!");
};

editor.registerCommand(
  "My Custom Command",        // Name in command palette
  "Does something useful",    // Description
  "my_action",                // Global function to call
  "normal"                    // Context: normal, insert, prompt, etc.
);

Virtual Buffers

Create special buffers for displaying structured data like search results or diagnostics:
await editor.createVirtualBufferInSplit({
  name: "*Search Results*",
  mode: "search-results",
  readOnly: true,
  entries: [
    {
      text: "src/main.rs:42: match found\n",
      properties: { file: "src/main.rs", line: 42 }
    }
  ],
  ratio: 0.3  // Takes 30% of screen height
});

Event Handlers

Subscribe to editor events to react to user actions:
globalThis.onSave = function(data: { buffer_id: number, path: string }): void {
  editor.debug(`Saved: ${data.path}`);
};

editor.on("buffer_save", "onSave");
Available Events:
  • buffer_save - After a buffer is saved
  • buffer_closed - When a buffer is closed
  • cursor_moved - When cursor position changes
  • render_start - Before screen renders
  • lines_changed - When visible lines change

Package Types

Fresh supports multiple package types:

Plugins

TypeScript code that extends editor functionality

Themes

Color schemes for syntax highlighting and UI

Language Packs

Syntax highlighting, language config, and LSP support

Bundles

Bundles combine multiple languages and plugins into a single package. Useful for language ecosystems with multiple file types:
{
  "name": "elixir-bundle",
  "type": "bundle",
  "fresh": {
    "languages": [
      {
        "id": "elixir",
        "grammar": { "file": "grammars/elixir.sublime-syntax" },
        "lsp": { "command": "elixir-ls" }
      },
      {
        "id": "heex",
        "grammar": { "file": "grammars/heex.sublime-syntax" }
      }
    ],
    "plugins": [
      { "id": "elixir-tools", "entry": "plugins/tools.ts" }
    ]
  }
}

Next Steps

Getting Started

Learn how to install and use plugins

Plugin Development

Create your own plugins with TypeScript

Plugin Examples

Explore real plugin examples with code

API Reference

Complete API documentation

Build docs developers (and LLMs) love