# Marksman: a language server for Markdown notes and wiki-links

> Marksman is an LSP server that brings completion, go-to-definition, references, rename and diagnostics to Markdown, including wiki-link style notes. It ships as a self-contained binary and works in any editor with an LSP client.

**artempyanykh/marksman** — Write Markdown with code assist and intelligence in the comfort of your favourite editor.

- Repository: https://github.com/artempyanykh/marksman
- Stars: 3,355 · Forks: 73
- Language: F#
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/artempyanykh-marksman

## What Marksman solves for people who write Markdown in bulk

Markdown has no compiler. A link to a file that was renamed six months ago stays in the document looking fine, and you find out when a reader clicks it. Marksman is a language server that closes part of that gap by treating a folder of Markdown as a project rather than a set of unrelated text files. The README describes it as a program that integrates with your editor to assist in writing and maintaining Markdown documents, using the LSP protocol to provide completion, goto definition, find references, rename refactoring and diagnostics.

The target user is fairly specific. Anyone writing a single README gains little. The value shows up when you have many interlinked documents: a Zettelkasten-style note collection, a documentation tree, or a personal wiki. The README explicitly calls out wiki-link style references that support Zettelkasten-like note taking, and names Roam Research as a point of reference while noting that Marksman is free, open source and integrated into your editor, though not as feature rich as Roam Research. That comparison is the author's own, and it sets expectations honestly.

The three link forms the server understands are Markdown inline links such as [inline link](/some-file.md#some-heading), reference-style links with a separate definition line, and wiki-links such as [[another-note]] or [[another-notes#heading]]. All three support completion, hover, and goto definition or references, and wiki-links additionally get diagnostics for broken references and duplicate or ambiguous headings.

## How the server tracks links across a folder of notes

Marksman is a regular language server, so the architecture is the familiar LSP split: the editor is the client, Marksman is a separate process the editor launches, and the two exchange JSON-RPC messages. The repository layout reflects that. There are separate top-level directories for Marksman itself, Tests, Benchmarks, and a LanguageServerProtocol directory, plus MarkdigPatches, which suggests the Markdown parsing is built on Markdig with local modifications. The project is written in F# and builds through a .NET solution file.

The part that matters for behaviour is how the server decides what belongs to the same project. The README's FAQ answers the most common complaint directly: if cross-file references and completions do not work, either create an empty .marksman.toml in the root folder of your project or initialize a repository, for example with git init. The linked features page is where the single-file and multi-file modes are described in full. In other words, the server needs a boundary to know which files can link to each other. Without one, it falls back to operating on the file in front of you.

That design has a consequence worth stating plainly. Marksman does not maintain a persistent index you configure and point at a database. The project root is the index scope, and the .marksman.toml file doubles as the marker for that root. The repository also contains a .marksman.toml at its own top level, which is consistent with the project using its own convention while developing.

## Installing Marksman and getting link completion working

The README does not inline the install steps. It points to an installation instructions page under docs/install.md, and the badges at the top of the README show the distribution channels the project advertises: Homebrew and Snapcraft. The README also states that Marksman works on macOS, Linux and Windows and is distributed as a self-contained binary for each operating system.

If you build from source instead, the Makefile at the repository root exposes the targets the maintainers use. The setup target restores .NET tools and build compiles the F# project:

```bash
make setup
make build
```

The run target starts the server, and it forwards extra arguments to the executable, so you can pass server subcommands through it:

```bash
make run server
```

The README's Vim example shows the argument shape explicitly: the server is invoked with the single argument server, alongside a name and the markdown filetype. That is the same argument any LSP client needs when it launches the binary.

For Emacs with Eglot, the README gives this configuration, which registers the marksman executable for markdown-mode and enables Eglot on that hook:

```lisp
(add-to-list 'eglot-server-programs '(markdown-mode . ("marksman")))
(add-hook 'markdown-mode-hook #'eglot-ensure)
```

After that, open a Markdown file inside a folder that has an empty .marksman.toml or is a git repository, type the opening of a wiki-link, and the completion list should offer note names from the project. If it does not, the root marker is the first thing to check, because that is the failure the README's FAQ addresses first.

## Editor integrations and what each one costs you

Marksman's editor support is uneven, and the README is candid about where configuration is required. Neovim has three routes: mason.nvim for automatic server installation, which the README notes requires mason-lspconfig.nvim, nvim-lspconfig, or CoC-marksman. Vim has two: ale, which the README says has built-in support, and the lsp plugin, which needs an explicit LspAddServer call in ~/.vim/after/ftplugin/markdown.vim. Emacs has LSP Mode with automatic server installation and an example use-package form, plus Eglot, which the README says requires configuration unless a pending upstream pull request is merged.

Some editors need nothing beyond the binary on your PATH. Helix supports Marksman out of the box, but you must add the marksman binary to PATH manually. Kakoune works with kakoune-lsp with no other configuration. Zed supports it through its integrated LSP support by listing marksman as an available language server for Markdown in the languages section of settings.json. Sublime Text and VSCode both have dedicated packages, and BBEdit can be configured following a linked discussion comment.

The pattern worth noticing: the editors with first-class packaging handle installation for you, and the ones that only speak raw LSP require you to place the binary and write a few lines of config. That is not a defect in Marksman so much as the state of LSP client configuration across editors. If you switch editors often, expect to redo the wiring each time.

## Where Marksman stops being the right tool

The clearest limitation is the project-root requirement. The README's own FAQ lists cross-file references and completions not working as the first question, and the answer is to create an empty .marksman.toml or initialize a repository. If your workflow is a stream of standalone Markdown files opened from a scratch directory, or files that live in many unrelated directories, you will not get the cross-file features that justify installing a language server at all. There is no configuration key documented in the README that changes this; the root marker is the mechanism.

A second boundary is scope. Marksman is a Markdown language server, not a note-taking application. It has no UI, no backlink panel of its own, no graph view. Whatever your editor's LSP client renders is what you get. The README's footnote comparing it to Roam Research says as much: Marksman is not as feature rich as that commercial product. If you want the application experience, a language server is the wrong shape of tool.

The README also points readers toward the Markdown Memo VSCode extension, noting it has some features missing in Marksman and the Marksman VSCode extension, while being VSCode specific. That is an unusual thing for a project to say about something adjacent to it, and it is a useful signal: if VSCode is your only editor, there is a competing extension that the maintainer considers more capable in places.

Finally, installation on macOS has a documented snag. The README's FAQ covers the message that marksman cannot be opened because Apple cannot check it for malicious software, and gives the workaround of running xattr -d com.apple.quarantine with the path to the binary. That is a Gatekeeper quarantine attribute, and it applies to the downloaded binary rather than to anything Marksman does at runtime.

## Marksman against Markdown Memo and Roam Research

The README names two alternatives itself, and they differ from Marksman in different directions. Markdown Memo is a VSCode extension, so it runs inside one editor and can use that editor's extension APIs. Marksman is a language server, so it runs as a separate process and works with any client that speaks LSP. The README frames the trade-off directly, saying Markdown Memo has some features that are missing in Marksman and the Marksman VSCode extension, but that Markdown Memo is VSCode specific while Marksman is a generic language server usable with Emacs, Vim, Neovim and others. If you use one editor and want the richest feature set inside it, the extension is the more direct answer. If you move between editors, or use something without a dedicated Marksman package, the server is the more portable choice.

Roam Research is the other reference point, and the difference is category rather than features. It is a commercial hosted application built around the Zettelkasten method, with its own interface. Marksman is a free, open source program that plugs into your editor. The README is explicit that Marksman is not as feature rich. Choosing between them is really choosing between an application you visit and a capability you install into tools you already use.

A third option the README does not discuss is doing nothing. For a small set of documents, grep and your editor's built-in file search cover broken links well enough, and neither requires a background process or a root marker file.

## Maintenance, licensing and what upgrading involves

The repository is not archived. The last push was on 2026-09-14, and the most recent release listed is dated 2026-02-08, with earlier releases on 2026-01-28 and 2025-12-13. Those dates indicate ongoing work, and the release cadence over that window is steady rather than constant.

The licence is MIT, which is permissive and places few obligations on how you redistribute or embed the software. That is a statement about the licence text, not legal advice; if you plan to bundle Marksman into a commercial product, read the LICENSE file in the repository and consult someone qualified.

Upgrade cost depends on how you installed it. Through Homebrew or Snap, upgrading is the package manager's job. If you build from source, the Makefile targets are the interface: make setup restores .NET tools, make build compiles, make test runs the test suite, and make check runs fantomas in check mode against the Marksman project. The repository also pins the SDK through global.json, so a source build depends on having a compatible .NET SDK available. Because Marksman is a self-contained binary, editor-side configuration rarely changes between versions, which keeps upgrades low-risk in practice.

## Conclusion

Adopt Marksman if you keep a folder of Markdown notes or docs and want link completion, go-to-definition and broken-link diagnostics inside an editor you already use, especially if you write wiki-links. Skip it if your Markdown lives as isolated single files with no shared root, since cross-file completion and references will not work without one. Before committing, verify two things: that your editor has a working LSP client for Markdown, and that an empty .marksman.toml at the root or an initialized repository makes cross-file features behave as you expect.

## FAQ

### How do I install Marksman?

The README directs you to docs/install.md for installation instructions and shows Homebrew and Snapcraft badges as distribution channels. It also states that Marksman works on macOS, Linux and Windows and is distributed as a self-contained binary for each OS.

### How do I use Marksman?

You install the binary, configure your editor's LSP client to launch it with the server argument, and then open Markdown files inside a project root. The server then provides completion, hover, goto definition and references for inline links, reference links and wiki-links.

### Why do cross-file references and completions not work in Marksman?

The README's FAQ says this happens when the server has no project root. Create an empty .marksman.toml in the root folder of your project, or initialize a repository such as with git init, and the multi-file features apply.

### Does Marksman work with Neovim and Emacs?

Yes. The README lists Neovim support through mason.nvim, nvim-lspconfig or CoC-marksman, and Emacs support through LSP Mode with automatic server installation or through Eglot with manual configuration.

### What does Marksman do about broken wiki-links?

The README states that Marksman provides diagnostics for wiki-links to detect broken references and duplicate or ambiguous headings. These appear through your editor's LSP diagnostics interface.

### What licence is Marksman released under?

The repository lists MIT as the licence, and a LICENSE file is present at the top level. The README itself does not discuss licensing terms.

## Sources

- [artempyanykh/marksman on GitHub](https://github.com/artempyanykh/marksman)
- [Issues](https://github.com/artempyanykh/marksman/issues)
- [License: MIT](https://github.com/artempyanykh/marksman/blob/main/LICENSE)
- [README](https://github.com/artempyanykh/marksman/blob/main/README.md)
- [Releases](https://github.com/artempyanykh/marksman/releases)

---

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