# SublimeLinter: a lint framework with no linters and seven named fixers

> SublimeLinter is the linting layer for Sublime Text, installed once and paired with a separate adapter package per tool such as eslint or flake8. Its own repository ships no linter, yet it hard-codes quick actions for seven of them, and three of those live outside the project.

**SublimeLinter/SublimeLinter** — The code linting framework for Sublime Text

- Repository: https://github.com/SublimeLinter/SublimeLinter
- Website: https://www.sublimelinter.com/
- Stars: 2,040 · Forks: 269
- Language: Python
- License: MIT
- Published: 2026-10-14 · Updated: 2026-10-14 · Language: en
- Canonical page: https://hysenlabs.com/projects/sublimelinter-sublimelinter

## Zero bundled linters, seven hard-coded quick action targets

SublimeLinter is a framework, not a linter. The project states up front that no linters come with it and that you get them through Package Control. A working setup takes three pieces: this plugin, the command line tool itself, which SublimeLinter invokes as a command, and an adapter package named after that tool, such as SublimeLinter-eslint or SublimeLinter-flake8. Keeping the tools out of the framework is the design, and it is why the package stays small.

The same document then names seven specific tools for its quick actions: eslint, stylelint, flake8, mypy, shellcheck, codespell and phpcs. A framework that bundles nothing has still written down a long list of what it knows about, which is the first thing worth noticing when you read it closely. Even that list is not owned in one place. Four of those repositories sit under the SublimeLinter organisation, while mypy arrives through `SublimeLinter-contrib-mypy` by fredcallaway and codespell through `SublimeLinter-contrib-codespell` by kaste, so the set of fixers grows when somebody outside the project opens a pull request.

## Diagnostics live in seven root modules and two view packages

The repository root shows how a lint result travels. The `lint/` package holds the linting core, `sublime_linter.py` is the plugin entry point and `log_handler.py` sends warnings to the Sublime Text console. Presentation is split apart: `panel_view.py` for the diagnostics panel, `highlight_view.py` for the squiggles themselves, `status_bar_view.py` for the status bar, `active_linters_view.py` for which linters are live, `busy_indicator_view.py` for the spinner and `goto_commands.py` for jumping between errors. The `panel/` and `gutter-themes/` directories sit beside them as assets.

Commands are registered just as visibly. `Default.sublime-commands` holds the palette entries, and `Main.sublime-menu` together with `Context.sublime-menu` wires those same actions into menus, which is why the practical advice is to open the Command Palette with ctrl+shift+p and type SublimeLinter rather than hunt through menu trees. Around that sit the packaging and developer files: `SublimeLinter.sublime-settings`, `dependencies.json`, `requirements.lock`, `requirements-dev.lock`, `.python-version`, `mypy.ini`, `unittesting.json`, plus `vendor/`, `stubs/`, `docs/`, `scripts/`, `tests/` and `messages/`. One detail a skim misses: the root carries `__init__.py`, `_init.py` and `__allo__.py`, three file names that differ only by leading underscores and a single letter.

## Background lint by default, and a plugin host transition still moving

Linting runs in the background out of the box, and most linters support that mode, which is why squiggles appear while you type instead of after a manual run. The caveat sits in the installation note: the project is in a transition phase to the newer ST4 plugin host, and after installing or upgrading helper packages a restart of Sublime Text may be necessary. The same note then says that on the author's machine no restarts were necessary.

Read that pair of statements twice. The documented risk is real, the personal experience is not a rule, and the note asks you to check whether everything works and whether the console shows permanent errors. Startup timing matters for a second reason, because some code in the plugin only runs on startup, which is why the support advice ends with a restart followed by a read of the console output. Fresh adapters therefore land inside a host that is still being reshaped, and a restart you skip on a good day costs you on a bad one.

## Install through Package Control, then clone over the installed package

Start the way the project intends. Install SublimeLinter from Package Control, install the command line tool you actually want, then install the matching adapter package, which carries the linter's name, through Package Control as well. Open the settings from the Command Palette by searching for `Preferences: SublimeLinter Settings`, where the mnemonic is sls, and the defaults appear on the left or on top. Those defaults cover most users, and the per-linter detail lives in `SublimeLinter.sublime-settings` in the repository.

To work on the plugin itself, clone it into the Packages folder, reached through Preferences then Browse Packages. That clone overrules the installed copy at once, and deleting the folder reverses it:

```shell
> git clone https://github.com/SublimeLinter/SublimeLinter.git
> subl SublimeLinter
```

The development environment is pinned in `pyproject.toml`, which sets requires-python to `>= 3.12`, enables managed and virtual mode for rye, and lists Sphinx and sphinx-autobuild as dev dependencies. One command installs it:

```shell
> rye sync
```

## The keymap table renames next and previous error on macOS

Four commands arrive with shortcuts. On Linux and Windows they are chords on ctrl+k followed by l to lint the view, a to open the diagnostics panel, n for the next error and p for the previous one. On macOS the first half of every chord becomes ctrl+cmd, and the second half stops matching the table: next error becomes e and previous error becomes cmd+shift+e. Memory built on the Linux row lands on the wrong action.

The table is a starting point, because the default bindings live in `keymaps/Default (Windows).sublime-keymap`, which also carries commands the summary table leaves out. The binding worth adding by hand is `sublime_linter_quick_actions`, and the project shows its shape:

```jsonc
    // To trigger a quick action
    // { "keys": ["ctrl+k", "ctrl+f"],
    //   "command": "sublime_linter_quick_actions"
    // },
```

Everything else the plugin registers is found the same way, through the Command Palette with ctrl+shift+p and a search for SublimeLinter.

## Quick actions suppress messages instead of rewriting code

The plugin does linting and stops there. No fixers and no code formatters ship with it. What exists is a fixer API, reached from the palette entry `SublimeLinter: Quick Action`, and the actions that ship are mostly of one kind, fix by ignoring, which silences a specific message inline and on the spot.

The reason for stopping short of formatting is concrete. Adding a semicolon or a space is easy, but the inline ignore rules and their syntaxes are cumbersome to type and hard to remember, and there is no project of any size where nothing ever has to be ignored somewhere once. Rewriting code belongs to the linter itself; suppressing one line belongs to you, so the plugin offers the second half. Covering another target means opening a pull request against `quick_fix.py`, and the shipped set is guarded by tests in `tests/test_ignore_fixers.py`.

## The console, not the issue tracker, is the first place to look

Warnings do not come to you by default. They go to the Sublime Text console, opened through View then Show Console. Beyond that, enable `debug` mode in the settings, which turns on much more detail, including the exact command SublimeLinter runs and the working directory it runs in. Those two values deserve the first look when a linter produces nothing, because a wrong working directory and a missing binary look identical from inside the editor.

After that, where an issue belongs depends on where the fault lives. A problem specific to one linter goes to that linter's repository, such as SublimeLinter-eslint, and anything else goes to the framework's own tracker. Restarting Sublime Text and reading the console again closes the loop, since code that runs only at startup will not repeat its output on a plain reload.

## Where the framework ends and an LSP bridge begins

The boundary is drawn in the addons the project points at. `SublimeLinter-addon-toggler` and `SublimeLinter-addon-goto-flash` add switching and navigation on top of the framework, while `SublimeLinter-any-lsp` is what integrates LSP servers, and none of the three are part of the framework itself. A team that has standardised on a language server, or that wants a formatter applied on save, is holding the wrong tool, because neither capability arrives with this package.

Licensing adds nothing to weigh: SublimeLinter sits under the MIT licence, and the last push to the repository landed on 2026-10-02. The version dates are less even than the push date itself: version 4.28.2 is dated 2025-10-31, version 4.29.0 is dated 2026-09-21 and version 4.30.0 is dated 2026-10-01, so the two newest versions landed ten days apart after a gap of close to eleven months. Pin what you validated.

## Conclusion

Take SublimeLinter when your editor already is Sublime Text and you want squiggles from the command line linters your pipeline runs. Pass on it when a team standardises on language servers, since LSP support lives in a separate addon, and when you expect a formatter on save, because none ships here. Before moving past the version you validated, turn on `debug` and read the exact command and working directory in the console, then check the adapter package for your linter. Anything not specific to one linter goes to the framework's own issue tracker instead.

## FAQ

### Does SublimeLinter include any linters?

No. The package is the framework only, so you add the command line tool plus an adapter package named after it, such as SublimeLinter-eslint or SublimeLinter-flake8, through Package Control.

### How do I install SublimeLinter for development?

Clone the repository into the Sublime Text Packages folder, reached through Preferences then Browse Packages. That clone overrules the installed package at once and deleting the folder reverses it, and `rye sync` installs the development requirements listed in `pyproject.toml`.

### Why do no squiggles appear after I install a linter package?

The installation note warns that a restart of Sublime Text may be needed after installing or upgrading helper packages during the move to the newer ST4 plugin host, and some plugin code only runs at startup. Check the console through View then Show Console for warnings.

### How do I see the exact command SublimeLinter runs?

Enable `debug` mode in the settings. The console then reports the exact command and the working directory, which are the two values to check when a linter produces no output at all.

### Can SublimeLinter fix or format code?

No fixers or formatters ship with it. There is a fixer API behind `SublimeLinter: Quick Action`, and the actions that ship are mostly fix by ignoring, which suppresses one specific message inline.

## Sources

- [License: MIT](https://github.com/SublimeLinter/SublimeLinter/blob/master/LICENSE)
- [Project website](https://www.sublimelinter.com/)
- [README](https://github.com/SublimeLinter/SublimeLinter/blob/master/README.md)
- [Releases](https://github.com/SublimeLinter/SublimeLinter/releases)
- [SublimeLinter/SublimeLinter on GitHub](https://github.com/SublimeLinter/SublimeLinter)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sublimelinter-sublimelinter
