Run standard fsharp codes in watch mode
Branch: master3
Clone or download
Latest commit e431bd8 Jan 24, 2019


Run standard fsharp codes in watch mode

Play around

vscode only


For a quick play around Try

From source code interation test

  • git clone
  • cd FcsWatch.Tests
  • tag single test in FcsWatchTests.fs ftestCase "base interaction test"
  • dotnet run
  • modify fs files in any of TestProject,TestLib2,TestLib1
  • Set breakpoint in any of TestProject,TestLib2,TestLib1
  • F5 Debug Launch TestProject
  • modify fs files in any of TestProject,TestLib2,TestLib1
  • (Optional) add new fs file in any of TestProject,TestLib2,TestLib1
  • Relaunch Debugger

Get started

  1. Install fake5
  2. Replace build.fsx with below codes
#r "paket:
nuget Atrous.Core.Utils
nuget Fake.Core.Target
nuget FcsWatch //"

#load "./.fake/build.fsx/intellisense.fsx"

// start build
open Fake.Core
open Fake.IO
open Microsoft.FSharp.Compiler.SourceCodeServices
open FcsWatch.FakeHelper
open Atrous.Core.Utils.FakeHelper

let root = Path.getDirectory "./"
Target.create "FcsWatch" (fun _ ->  
    let projectFile = Path.getFullName "YourProject/YourProject.fsproj"
    dotnet root "build" [projectFile]
    let checker = FSharpChecker.Create()
    /// or runFcsWatcherWith for more customizations
    runFcsWatcher checker projectFile

Target.create "Default" ignore

Target.runOrDefault "Default"
  1. fake build -t "FcsWatch"
  2. Change fs files in YourProject and save it

Launch debugging in vscode

You can also launch debugging when running in watch mode

        "name": "launch TestProject",
        "type": "coreclr",
        "request": "launch",
        "preLaunchTask": "emitCompilerTmp",
        "program": "${workspaceFolder}/YourProject/bin/Debug/targetFramwork/YourProject.exe",
    /// send a http request to copy dlls in obj to bin
        "label": "emitCompilerTmp",
        "command": "curl",
        "args": [
        "presentation": {
            "reveal": "silent"

When you are debugging files,watch mode still take effect

Multiple reference projects

It is supported if you pass the entry project argument to it

Release Notes

more features: Please open Release_Notes detail

Plugin mode

e.g.: excelDna sample vscode launch.json setting

      "name": "Attach Excel",
      "type": "clr",
      "request": "attach",
      "preLaunchTask": "emitCompilerTmp",
      "processId": 14876

build.fsx setting

    /// trigger when file changed was detected 
    /// and (re)load debugger (after emit cache) 
    let installPlugin() =
        dotnet projectDir "msbuild" ["/t:ExcelDnaBuild;ExcelDnaPack"]
        addIn.Installed <- true
        Trace.trace "installed plugin"

    /// trigger when file changed was detected 
    /// and (re)load debugger (before emit cache) 
    let unInstall() =
        addIn.Installed <- false
        Trace.trace "unInstalled plugin"

    /// trigger when (re)load debugger (after installPlugin()) 
    let calculate() =
        Trace.trace "calculate worksheet"

    let plugin = 
        { Load = installPlugin 
          Unload = unInstall 
          Calculate = calculate
          /// Thread sleed to wait debugger attached.
          /// Trigger when file changed was not detected 
          /// and reload debugger 
          DebuggerAttachTimeDelay = 1000 }

    runFcsWatcherWith (fun config ->
        { config with 
            Logger = Logger.Normal
            DevelopmentTarget = DevelopmentTarget.Plugin plugin
    ) checker projectFile


why not use dotnet watch:

  1. dotnet watch reference all dlls every time (which will take at least 3000ms?) (while fcs hold dlls in runtime cache)
  2. not easy to debug when you are using dotnet watch