CLI tool
dotnet/fsharp avatar
dotnet/fsharp

Inside dotnet/fsharp: the compiler, the core library and the build that needs a matching SDK

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio.

4,351 stars886 forksF#MIT

At a glance

What is it?
This repository is the F# compiler, FSharp.Core and the Visual Studio tooling, written in F# itself. It matters most to contributors and to anyone who consumes FSharp.Compiler.Service, because its package releases are deliberately locked to SDK versions.
Who is it for?
Adopt this repository if you intend to work on the F# compiler, FSharp.Core or the editor tooling, or if your product embeds FSharp.Compiler.Service, whose packages move only when the SDK moves. Do not adopt it as a route to the language itself: the last push was on 2026-11-02, and ordinary users pick F# up through the .NET SDK rather than this tree.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly F#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • dotnet/fsharp4,351 ★ · +30
Star history
Repository2026-07-292026-11-14
dotnet/fsharp4.3k4.4k

30 Stars in the last 108 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A compiler bootstrapped with the SDK it will replace

The first thing this repository asks of you is a specific SDK, not a general .NET install. The exact version sits in global.json at the repository root, and the README points contributors to the .NET SDK download page for it. Everything else in the tree depends on that pin: the compilation of the compiler, the core library and the Visual Studio extension all happen under that one SDK version. Development runs on any OS that .NET supports, so the platform is not the constraint, the version is.

That single file shapes the whole contributor experience. Read global.json before anything else in the checkout.

Two solutions, and the larger one drags in Visual Studio

After a build completes, you open one of two solution files. FSharp.slnx is the compiler, core library and tests. VisualFSharp.slnx is described in the README as larger, because it adds the Visual Studio tools and the infrastructure behind them. Choosing wrongly is not fatal, but it costs load time and, on the Windows path, it decides whether the VS component is in your loop at all.

The Windows path differs from the Unix path in one way that matters. On Windows the build depends on an installation of Visual Studio, unless you pass a flag to skip it. That flag exists precisely for the case where you are working on the compiler and have no need for the IDE integration.

Building on Windows, macOS and Linux

On Windows the build is a command file, and the Visual Studio bypass is a single switch:

shell
build.cmd -noVisualStudio

On Linux or macOS the equivalent entry point is the shell script:

bash
./build.sh

Both scripts do the same job: compile from source so you can work against a local compiler rather than the one shipped in your SDK. A devcontainer and a .vsconfig are present in the tree, and the README notes that in practice you only need build.cmd or build.sh. DEVGUIDE.md holds the configuration detail for cases where you do need something more specific, and TESTGUIDE.md explains how to run individual test suites rather than the whole set at once.

FSharp.Compiler.Service packages ride the SDK they shipped with

The README makes an unusual admission about packaging: official NuGet packages of FSharp.Compiler.Service and FSharp.Core are synced with the SDK, and it gives the reason, which is that the projects want to be in sync. So the compiler service number is not chosen independently. It follows the SDK it came out of, which suits anyone who wants consistency and gets in the way of anyone wanting a newer compiler service without changing SDKs.

Nightly builds behave differently. Every successful insertion publishes to Azure feeds, and the README documents per-build feeds for the 7.0.40x and 8.0.10x series, each pointing at a dotnet7 or dotnet8 packaging feed. Adding one to a NuGet.config looks like this:

xml
<add key="fsharp-prerelease" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />

If you consume the compiler service rather than build it, that distinction is the whole decision: you either ride the SDK you already have, or you wire a nightly feed into your restore.

main moves first, dev17.x holds what ships in an IDE

The branch layout explains why contributions sometimes take a while to reach a shipping IDE. main is where nearly all contributions go, is buildable and installable in the latest public Visual Studio, and is used to build the nightly VSIX. It may carry updated F# features and logic that no shipping IDE has yet.

The branch named release/dev17.x tracks one point version of Visual Studio. It takes features and fixes from main up to a branch point, then applies selective cherry-picks, and it can hold changes that depend on things arriving in the corresponding Visual Studio. Those changes integrate back into main once that Visual Studio ships. A third branch, release/dev15.9, is held for long-term servicing of Visual Studio 2017 update 15.9.x, and the README is blunt about it: servicing is not expected.

Language change goes through three repositories, not this one

Adding a language feature here is the slowest path. The README lays out a three-step route: ideas start in the F# language suggestions repository, get approved in principle, become an RFC in the F# language design repository, and only then get implemented and tested in this repository. Two separate repositories sit between a suggestion and a line of code in src/.

That sequencing is the honest cost of working on the language rather than the compiler. For a bug in the implementation, or a test, or an editor feature, this repository is the right place. For syntax, a proposal is the route, and the RFC stage is where the technical specification is argued over before any implementation begins. Docs live separately again: the compiler documentation in docs/index.md is published as the F# Compiler Guide, and user-facing language documentation is sourced in the dotnet/docs repository.

Where a C# or OCaml team fits, and where it does not

The two questions engineers actually ask about this project are about fit. F# differs from C# in shape: it is expression oriented, and the F# language design process that governs changes here has its own suggestions repository and its own RFC repository. Nothing in this repository tries to track C# surface syntax. Anyone coming from C# who wants a familiar object model with the same syntax is asking for a different tool.

Against OCaml the difference is one of delivery. OCaml arrives as a language with its own toolchain and package manager; the F# compiler here ships inside the .NET SDK and is versioned in lockstep with it, per the README's own note about staying in sync. FSharp.Core and the compiler service come from the same build. If your organisation already standardises on the .NET SDK, that coupling is an advantage. If you need a compiler that moves independently of your SDK, you work around it with a nightly feed.

One asymmetry is easy to skim past. The build scripts are not symmetric across platforms, and neither are the branches. A Linux contributor runs ./build.sh and opens FSharp.slnx, so the Visual Studio tools never enter the loop, while the Visual Studio tools live in VisualFSharp.slnx, which the README offers only on the Windows path. The repository asks for the same .NET SDK everywhere and then hands you a different working set depending on the operating system.

Editorial conclusion

Adopt this repository if you intend to work on the F# compiler, FSharp.Core or the editor tooling, or if your product embeds FSharp.Compiler.Service, whose packages move only when the SDK moves. Do not adopt it as a route to the language itself: the last push was on 2026-11-02, and ordinary users pick F# up through the .NET SDK rather than this tree. Verify first that the SDK version pinned in global.json installs cleanly on your machine, because the README names that file as the source of the exact SDK version.

Frequently asked questions

Is F# similar to C#?

Not in surface syntax. F# is an expression oriented language with its own design process, tracked through the F# language suggestions repository and a separate RFC repository, and this repository does not try to mirror C# syntax.

How does F# differ from OCaml?

F# ships inside the .NET SDK: the README states that official NuGet releases of FSharp.Compiler.Service and FSharp.Core are synced with SDK releases on purpose. OCaml arrives with its own toolchain instead, so the F# compiler version follows your SDK version unless you use a nightly Azure feed.

What does fsharp core contain?

FSharp.Core is the F# core library, built from src/ in this repository alongside the compiler. It is released to NuGet in step with the SDK rather than on its own schedule.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dotnet-fsharp.svg)](https://hysenlabs.com/projects/dotnet-fsharp)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/dotnet-fsharp.svg)](https://hysenlabs.com/projects/dotnet-fsharp)

Was this useful?