# .NET compatibility

> Learn about supported .NET Framework versions (net462, net472, net48) and Unity compatibility for Fern-generated SDKs.

Fern-generated .NET SDKs support modern .NET versions, .NET Framework versions, and Unity.

Because these SDKs are built with modern C# features, you'll need the following even when targeting older .NET Framework targets:

* A modern compiler (Visual Studio 2022 or .NET SDK)
* The appropriate .NET Framework Developer Pack or reference assemblies

## Supported frameworks

Fern .NET SDKs support [all officially supported .NET versions](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-framework), except for net35.

| Framework            | Target Framework Moniker (TFM) |
| -------------------- | ------------------------------ |
| .NET 9               | net9.0                         |
| .NET 8               | net8.0                         |
| .NET Framework 4.8.1 | net481                         |
| .NET Framework 4.8   | net48                          |
| .NET Framework 4.7.2 | net472                         |
| .NET Framework 4.7.1 | net471                         |
| .NET Framework 4.7   | net47                          |
| .NET Framework 4.6.2 | net462                         |

<Note>
  The C# language version is determined by your compiler, while the target framework determines which runtime and base class library APIs are available. Fern SDKs use modern C# features but compile to older framework versions.
</Note>

<AccordionGroup>
  <Accordion title="IDE compatibility">
    All major IDEs support Fern-generated SDKs when targeting `net462`, `net472`, and `net48` versions:

    * **Visual Studio 2022** (recommended) - Works out of the box. Set `<LangVersion>` in your project and install the appropriate [developer pack](#developer-packs).
    * **Visual Studio 2019** - Supports C# 9 natively. For newer C# versions, add the `Microsoft.Net.Compilers.Toolset` package.
    * **Rider** - Uses Roslyn. Set `<LangVersion>` and ensure reference assemblies are available.
    * **VS Code** - Works via OmniSharp and .NET SDK builds.
    * **Unity** - Uses Unity's own C# compiler. See [Using SDKs with Unity](#using-sdks-with-unity).

    <Info>
      You can "bring your own compiler" with the `Microsoft.Net.Compilers.Toolset` package on any environment.
    </Info>
  </Accordion>

  <Accordion title="Compiler compatibility">
    Use the **Roslyn compiler** (`csc`) that comes with Visual Studio 2022+ or the .NET SDK. Set your C# version via `<LangVersion>` to `latest`, `preview`, or a specific version (minimum `9`).

    Fern's .NET SDK doesn't support the legacy Mono compiler (`mcs`, `gmcs`) or the pre-Roslyn `csc.exe` compiler. Use Roslyn even when building on Mono.

    <Info title="Building on Mono">
      Use the .NET SDK (`dotnet`) with the `Microsoft.NETFramework.ReferenceAssemblies` package to supply `net48` references on non-Windows. Use Roslyn via `dotnet build` or Mono's MSBuild.

      ```bash title="macOS/Linux"
      dotnet build -c Release
      ```
    </Info>
  </Accordion>

  <Accordion title="Developer packs">
    * [.NET Framework 4.6.2 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net462)
    * [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472)
    * [.NET Framework 4.8 Developer Pack](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net48)
  </Accordion>
</AccordionGroup>

## Using SDKs with Unity

Unity controls its own C# compiler and .NET profile, which affects how you use Fern's .NET SDK.

<AccordionGroup>
  <Accordion title="C# language version">
    Unity compiles projects using Roslyn, typically supporting C# 9 (varies by Unity version). You can't force Unity to use a newer C# compiler by changing your package because Unity controls the compiler inside the Editor.
  </Accordion>

  <Accordion title="API compatibility level">
    Configure this in Unity: `Edit → Project Settings → Player → Other Settings → Api Compatibility Level`

    * **.NET Standard 2.1** (recommended for cross-platform plugins)
    * **.NET Framework 4.x** (Unity's "4.x equivalent" profile)
  </Accordion>

  <Accordion title="Required assemblies">
    Unity doesn't support NuGet packages, so you must manually download and add these assemblies to your Unity project:

    | Assembly                               | NuGet Package                                                                                                         |
    | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
    | Microsoft.Bcl.AsyncInterfaces          | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces/10.0.0-preview.6.25358.103) |
    | OneOf                                  | [3.0.271](https://www.nuget.org/packages/OneOf/3.0.271)                                                               |
    | OneOf.Extended                         | [3.0.271](https://www.nuget.org/packages/OneOf.Extended/3.0.271)                                                      |
    | System.Buffers                         | [4.6.1](https://www.nuget.org/packages/System.Buffers/4.6.1)                                                          |
    | System.IO.Pipelines                    | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/System.IO.Pipelines/10.0.0-preview.6.25358.103)           |
    | System.Memory                          | [4.6.3](https://www.nuget.org/packages/System.Memory/4.6.3)                                                           |
    | System.Runtime.CompilerServices.Unsafe | [6.1.2](https://www.nuget.org/packages/System.Runtime.CompilerServices.Unsafe/6.1.2)                                  |
    | System.Text.Encodings.Web              | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/System.Text.Encodings.Web/10.0.0-preview.6.25358.103)     |
    | System.Text.Json                       | [10.0.0-preview.6.25358.103](https://www.nuget.org/packages/System.Text.Json/10.0.0-preview.6.25358.103)              |
    | System.Threading.Tasks.Extensions      | [4.6.3](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/4.6.3)                                       |
    | portable.system.datetimeonly           | [9.0.0](https://www.nuget.org/packages/portable.system.datetimeonly/9.0.0)                                            |
  </Accordion>
</AccordionGroup>

## Project configuration examples

Use SDK-style projects where possible, as they provide modern compilers and simpler multi-targeting. If you have a classic project format, consider converting to SDK-style. The [legacy projects section](#legacy-projects) covers legacy setups that can't be converted.

<Note title="Building on macOS/Linux">
  When building for `net48` on macOS/Linux, you won't have the Windows targeting packs. Add the reference assemblies package:

  ```xml title="YourProject.csproj"
  <ItemGroup>
    <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="all" />
  </ItemGroup>
  ```

  This provides the `net48` reference assemblies so Roslyn can compile for `net48` on any platform. You'll still need Mono or Wine to execute the result.
</Note>

<AccordionGroup>
  <Accordion title="SDK-style projects (recommended)">
    Targeting `net48` with modern C#

    <Steps>
      <Step title="Configure your project">
        <Info title="Prerequisite (Windows)">
          Install the [.NET Framework 4.8 Developer Pack](#developer-packs) so the `net48` reference assemblies are available to the compiler.
        </Info>

        ```xml title="YourProject.csproj"
        <Project Sdk="Microsoft.NET.Sdk">
          <PropertyGroup>
            <!-- Target .NET Framework 4.8 -->
            <TargetFramework>net48</TargetFramework>

            <!-- Use a modern C# version -->
            <LangVersion>latest</LangVersion>

            <!-- Optional, but recommended for better warnings -->
            <Nullable>enable</Nullable>
          </PropertyGroup>
        </Project>
        ```
      </Step>

      <Step title="Build your project">
        ```bash
        dotnet build -c Release
        ```
      </Step>

      <Step title="Multi-target (optional)">
        To support multiple frameworks, use `<TargetFrameworks>`:

        {/* <!-- vale off --> */}

        ```xml title="YourProject.csproj"
        <TargetFrameworks>net48;net8.0</TargetFrameworks>
        ```

        {/* <!-- vale on --> */}
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="Legacy projects">
    For older MSBuild/Visual Studio versions, Visual Studio 2019, or legacy `packages.config` setups, add a modern Roslyn toolset and target the old framework.

    <Steps>
      <Step title="Install target packs">
        Install the appropriate [.NET Framework Developer Pack](#developer-packs) so Visual Studio can find the reference assemblies.
      </Step>

      <Step title="Set language version">
        ```xml title="YourProject.csproj"
        <PropertyGroup>
        <!-- Unlock modern C# -->
        <LangVersion>latest</LangVersion>
        </PropertyGroup>
        ```

        Or use a specific version: `9`, `10`, `11`, `12`, or `preview`.
      </Step>

      <Step title="Add modern compiler">
        ```xml title="YourProject.csproj"
         <ItemGroup>
         <PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="x.y.z">
             <!-- Keep it private: -->
             <PrivateAssets>all</PrivateAssets>
         </PackageReference>
         </ItemGroup>
        ```

        This ensures your build uses a modern `csc.exe` even if your IDE/MSBuild is older.
      </Step>
    </Steps>
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Type or namespace IsExternalInit not found">
    Add a small shim in your project or reference a helper package.
  </Accordion>

  <Accordion title="Reference assemblies for .NETFramework,Version=v4.8 were not found">
    * Windows: install the [.NET Framework 4.8 Developer Pack](#developer-packs).
    * Cross-platform/CI: add `Microsoft.NETFramework.ReferenceAssemblies` to the project (as `PrivateAssets=all`).
  </Accordion>

  <Accordion title="VS 2019 can't parse newer syntax">
    Add `Microsoft.Net.Compilers.Toolset` to the project, or move to VS 2022+.
  </Accordion>

  <Accordion title="CS0619: Constructors of types with required members are not supported">
    This error occurs when using the `required` keyword with older Visual Studio versions. Follow the instructions at [Legacy projects](#legacy-projects) to add a modern compiler.

    <Note>
      Some versions of Visual Studio may show this error in the IDE but compile the project successfully when using the package-provided compiler.
    </Note>
  </Accordion>
</AccordionGroup>