Header menu logo fantomas

Getting Started

Fantomas should be installed as a .NET tool.
It is recommended to install it as a local tool and stick to a certain version per repository.


Create a .NET tool manifest to install tools locally. You can skip this step if you wish to install Fantomas globally.

dotnet new tool-manifest

Install the command line tool with:

dotnet tool install fantomas

or install the tool globally with

dotnet tool install -g fantomas


For the overview how to use the tool, you can type the command

dotnet fantomas --help
Learn more about Fantomas:       https://fsprojects.github.io/fantomas/docs
Join our Discord community:      https://discord.gg/Cpq9vf8BJH

USAGE: dotnet fantomas [--help] [--force] [--profile] [--out <string>] [--check]
                       [--daemon] [--version] [--verbosity <string>]


    <string>...           Input paths: can be multiple folders or files with
                          *.fs,*.fsi,*.fsx,*.ml,*.mli extension.


    --force               Print the output even if it is not valid F# code. For
                          debugging purposes only.
    --profile             Print performance profiling information.
    --out <string>        Give a valid path for files/folders. Files should
                          have .fs, .fsx, .fsi, .ml or .mli extension only.
                          Multiple files/folders are not supported.
    --check               Don't format files, just check if they have changed.
                          Exits with 0 if it's formatted correctly, with 1 if
                          some files need formatting and 99 if there was an
                          internal error
    --daemon              Daemon mode, launches an LSP-like server that can be
                          used by editor tooling.
    --version             Displays the version of Fantomas
    --verbosity, -v <string>
                          Set the verbosity level. Allowed values are n[ormal]
                          and d[etailed].
    --help                display this list of options.

You have to specify an input path and optionally an output path. The output path is prompted by --out e.g.

dotnet fantomas ./input/array.fs --out ./output/array.fs 

Both paths have to be files or folders at the same time. If they are folders, the structure of input folder will be reflected in the output one. The tool will explore the input folder recursively. If you omit the output path, Fantomas will overwrite the input files unless the content did not change.

Multiple paths

starting version 4.5

Multiple paths can be passed as last argument, these can be both files and folders.
This cannot be combined with the --out flag.

One interesting use-case of passing down multiple paths is that you can easily control the selection and filtering of paths from the current shell.

Consider the following PowerShell script:

# Filter all added and modified files in git
# A useful function to add to your $PROFILE
function Format-Changed(){
    $files = 
        git status --porcelain `
        | Where-Object { ($_.StartsWith(" M", "Ordinal") -or $_.StartsWith("AM", "Ordinal")) `
        -and (Test-FSharpExtension $_) } | ForEach-Object { $_.substring(3) }
    & "dotnet" "fantomas" $files

Or usage with find on Unix:

find my-project/ -type f -name "*.fs" -not -path "*obj*" | xargs dotnet fantomas --check
namespace System
namespace System.Diagnostics
val fantomasDll: string
namespace System.IO
type Path = static member ChangeExtension: path: string * extension: string -> string static member Combine: path1: string * path2: string -> string + 3 overloads static member EndsInDirectorySeparator: path: ReadOnlySpan<char> -> bool + 1 overload static member Exists: path: string -> bool static member GetDirectoryName: path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload static member GetExtension: path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload static member GetFileName: path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload static member GetFileNameWithoutExtension: path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload static member GetFullPath: path: string -> string + 1 overload static member GetInvalidFileNameChars: unit -> char array ...
<summary>Performs operations on <see cref="T:System.String" /> instances that contain file or directory path information. These operations are performed in a cross-platform manner.</summary>
System.IO.Path.Combine([<System.ParamArray>] paths: string array) : string
System.IO.Path.Combine(path1: string, path2: string) : string
System.IO.Path.Combine(path1: string, path2: string, path3: string) : string
System.IO.Path.Combine(path1: string, path2: string, path3: string, path4: string) : string
val output: string
val psi: ProcessStartInfo
Multiple items
type ProcessStartInfo = new: unit -> unit + 3 overloads member ArgumentList: Collection<string> member Arguments: string member CreateNoWindow: bool member Domain: string member Environment: IDictionary<string,string> member EnvironmentVariables: StringDictionary member ErrorDialog: bool member ErrorDialogParentHandle: nativeint member FileName: string ...
<summary>Specifies a set of values that are used when you start a process.</summary>

ProcessStartInfo() : ProcessStartInfo
ProcessStartInfo(fileName: string) : ProcessStartInfo
ProcessStartInfo(fileName: string, arguments: string) : ProcessStartInfo
ProcessStartInfo(fileName: string, arguments: System.Collections.Generic.IEnumerable<string>) : ProcessStartInfo
property ProcessStartInfo.RedirectStandardOutput: bool with get, set
<summary>Gets or sets a value that indicates whether the textual output of an application is written to the <see cref="P:System.Diagnostics.Process.StandardOutput" /> stream.</summary>
<returns><see langword="true" /> if output should be written to <see cref="P:System.Diagnostics.Process.StandardOutput" />; otherwise, <see langword="false" />. The default is <see langword="false" />.</returns>
property ProcessStartInfo.UseShellExecute: bool with get, set
<summary>Gets or sets a value indicating whether to use the operating system shell to start the process.</summary>
<exception cref="T:System.PlatformNotSupportedException">An attempt to set the value to <see langword="true" /> on Universal Windows Platform (UWP) apps occurs.</exception>
<returns><see langword="true" /> if the shell should be used when starting the process; <see langword="false" /> if the process should be created directly from the executable file. The default is <see langword="true" /> on .NET Framework apps and <see langword="false" /> on .NET Core apps.</returns>
val p: Process
Multiple items
type Process = inherit Component interface IDisposable new: unit -> unit member BeginErrorReadLine: unit -> unit member BeginOutputReadLine: unit -> unit member CancelErrorRead: unit -> unit member CancelOutputRead: unit -> unit member Close: unit -> unit member CloseMainWindow: unit -> bool member Kill: unit -> unit + 1 overload ...
<summary>Provides access to local and remote processes and enables you to start and stop local system processes.</summary>

Process() : Process
Process.Start(fileName: string) : Process
Process.Start(startInfo: ProcessStartInfo) : Process
Process.Start(fileName: string, arguments: System.Collections.Generic.IEnumerable<string>) : Process
Process.Start(fileName: string, arguments: string) : Process
Process.Start(fileName: string, userName: string, password: System.Security.SecureString, domain: string) : Process
Process.Start(fileName: string, arguments: string, userName: string, password: System.Security.SecureString, domain: string) : Process
val reader: System.IO.StreamReader
property Process.StandardOutput: System.IO.StreamReader with get
<summary>Gets a stream used to read the textual output of the application.</summary>
<exception cref="T:System.InvalidOperationException">The <see cref="P:System.Diagnostics.Process.StandardOutput" /> stream has not been defined for redirection; ensure <see cref="P:System.Diagnostics.ProcessStartInfo.RedirectStandardOutput" /> is set to <see langword="true" /> and <see cref="P:System.Diagnostics.ProcessStartInfo.UseShellExecute" /> is set to <see langword="false" />. -or- The <see cref="P:System.Diagnostics.Process.StandardOutput" /> stream has been opened for asynchronous read operations with <see cref="M:System.Diagnostics.Process.BeginOutputReadLine" />.</exception>
<returns>A <see cref="T:System.IO.StreamReader" /> that can be used to read the standard output stream of the application.</returns>
val result: string
System.IO.StreamReader.ReadToEnd() : string
Process.WaitForExit() : unit
Process.WaitForExit(timeout: System.TimeSpan) : bool
Process.WaitForExit(milliseconds: int) : bool
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
type 'T array = 'T array

Type something to start searching.