Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Provides support for the F# language in Emacs. Includes the following features:

  • Syntax highlighting and indentation
  • Support for F# Interactive
  • Via Eglot LSP-client integration:

LSP mode

The current version of fsharp-mode installs fsautocomplete.exe automatically via eglot-fsharp.el (part of this mono repo, eglot-fsharp on melpa) or lsp-mode (untested).

fsharp-mode is tested with Emacs 27.1+ and NET Core 6 (LTS)



fsharp-mode is available on MELPA and can be installed using the built-in package manager.

If you’re not already using MELPA, add the following to your init.el:

;;; Initialize MELPA
(require 'package)
(add-to-list 'package-archives '("melpa" . ""))
(unless package-archive-contents (package-refresh-contents))

;;; Install fsharp-mode
(unless (package-installed-p 'fsharp-mode)
  (package-install 'fsharp-mode))

(require 'fsharp-mode)

If you are a user of use-package you can instead do

(use-package fsharp-mode
  :defer t
  :ensure t)

From source

I recommend to use Cask. Add this to your Cask file:

(depends-on "fsharp-mode" :git "")

Eglot integration

The eglot-fsharp integration is not part of fsharp-mode on melpa.

It is available via the seperate package eglot-fsharp on melpa.

Add to your config:

(require 'eglot-fsharp)

and execute M-x eglot

With eglot running use `xref-find-definitions` (bound to M-. pr. default) to go to definition. Completions are accessable via. `completion-at-point` (or a completion backend ex. company-mode


fsharp-mode has support for Emacs build-in project management via project.el


Compiler and REPL paths

The F# compiler and interpreter should be set to good defaults for your OS as long as the relevant executables can be found on your PATH or in other standard locations. If you have a non-standard setup you may need to configure these paths manually.

On Windows:

(setq inferior-fsharp-program "c:\\Path\\To\\Fsi.exe")

On Unix-like systems, you must use the –readline- flag to ensure F# Interactive will work correctly with Emacs. Typically fsi and fsc are invoked through the shell scripts fsharpi and fsharpc:

(setq inferior-fsharp-program "path/to/fsharpi --readline-")

Key Bindings

If you are new to Emacs, you might want to use the menu (call menu-bar-mode if you don’t see it). However, it’s usually faster to learn a few useful bindings:

Key bindingDescription
C-c C-rEvaluate region
C-c C-fLoad current buffer into toplevel
C-c C-eEvaluate current toplevel phrase
C-M-xEvaluate current toplevel phrase
C-M-hMark current toplevel phrase
C-c C-sShow interactive buffer
C-c C-cCompile with fsc
C-c xRun the executable
C-c C-aOpen alternate file (.fsi or .fs)
C-c lShift region to left
C-c rShift region to right
C-c <up>Move cursor to the beginning of the block
C-c C-d, M-.Jump to definition of symbol at point
C-c C-b, =M-,=Return to where point was before jump.

To interrupt the interactive mode, use C-c C-c. This is useful if your code does an infinite loop or a very long computation.

If you want to shift the region by 2 spaces, use: M-2 C-c r

In the interactive buffer, use ==M-RET= to send the code without explicitly adding the ;; thing.


In order to change tab size it is possible to put this in emacs profile:

(setq-default fsharp-indent-offset 2)

Because the F# language is sensitive to indentation, you might wan’t to highlight indentation:

(add-hook 'fsharp-mode-hook 'highlight-indentation-mode)


fsharp-mode is still under development, so you may encounter some issues. Please report them so we can improve things! Open an issue on Github.

No autocompletion in FSX files

The root cause is documented in this Ionide issue: 4.2.0 - No auto complete or typechecking in FSX files

As a workaround can add a reference to the facade netstandard assembly (path is platform/SDK-dependent).

On Arch Linux using dotnet sdk lts add this to your fsx file:

#r "/opt/dotnet/sdk/2.1.801/ref/netstandard.dll"

Project file issues

If your project file does not seem to be being parsed correctly, so that you have missing references or other incorrect intellisense results, it is possible to obtain a detailed log of LSP events in this buffers:

  • *EGLOT (PROJECT/fsharp-mode) stderr*
  • *EGLOT (PROJECT/fsharp-mode) output*
  • *EGLOT (PROJECT/fsharp-mode) events*


This project is maintained by the F# Software Foundation, with the repository hosted on GitHub.

Pull requests are welcome. Please run the test-suite with make test before submitting a pull request.


The maintainers of this repository appointed by the F# Core Engineering Group are:

Previous maintainers: