Fabulous.AST.Build 2.0.0-pre01

This is a prerelease version of Fabulous.AST.Build.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Fabulous.AST.Build --version 2.0.0-pre01
                    
NuGet\Install-Package Fabulous.AST.Build -Version 2.0.0-pre01
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Fabulous.AST.Build" Version="2.0.0-pre01">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Fabulous.AST.Build" Version="2.0.0-pre01" />
                    
Directory.Packages.props
<PackageReference Include="Fabulous.AST.Build">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Fabulous.AST.Build --version 2.0.0-pre01
                    
#r "nuget: Fabulous.AST.Build, 2.0.0-pre01"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Fabulous.AST.Build@2.0.0-pre01
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Fabulous.AST.Build&version=2.0.0-pre01&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Fabulous.AST.Build&version=2.0.0-pre01&prerelease
                    
Install as a Cake Tool

Fabulous.AST.Build

Automatically generate F# types from JSON files at build time.

Overview

Fabulous.AST.Build is an MSBuild task that:

  • Watches JSON files in your project
  • Automatically generates F# record types during build
  • Supports incremental builds (only regenerates when JSON changes)
  • Integrates seamlessly with MSBuild and .NET CLI

Use cases:

  • Generate F# types from API response samples
  • Keep type definitions in sync with JSON schemas
  • Automate type generation in CI/CD pipelines

💡 Tip: For programmatic control over generation, use Fabulous.AST.Json directly.

Installation

dotnet add package Fabulous.AST.Build

Requirements: .NET 8.0 or later

Tutorial

Step 1: Create a JSON Schema File

Create a folder for your JSON schemas and add a sample file.

schemas/user.json:

{
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com",
    "isActive": true
}

Step 2: Configure Your Project

Add the FabulousAstJson item to your .fsproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Fabulous.AST.Build" Version="1.0.0" />
  </ItemGroup>

  
  <ItemGroup>
    <FabulousAstJson Include="schemas/user.json" />
  </ItemGroup>

  
  <ItemGroup>
    <Compile Include="Generated/user.Generated.fs" />
  </ItemGroup>
</Project>

Step 3: Build Your Project

dotnet build

This generates Generated/user.Generated.fs:

// Auto-generated from schemas/user.json
// Hash: abc123...
// Do not edit manually - changes will be overwritten

type User = {
    id: int
    name: string
    email: string
    isActive: bool
}

Step 4: Custom Root Type Name

By default, the root type name is derived from the filename. Override it with RootName:

<ItemGroup>
  <FabulousAstJson Include="schemas/api-response.json" RootName="ApiResponse" />
</ItemGroup>

Step 5: Add a Namespace

Wrap generated types in a namespace:

<ItemGroup>
  <FabulousAstJson Include="schemas/user.json"
                   RootName="User"
                   Namespace="MyApp.Models" />
</ItemGroup>

Output:

namespace MyApp.Models

type User = {
    id: int
    name: string
    email: string
    isActive: bool
}

Step 6: Use a Module Instead

Use ModuleName for a module wrapper:

<ItemGroup>
  <FabulousAstJson Include="schemas/user.json"
                   RootName="User"
                   ModuleName="MyApp.Models" />
</ItemGroup>

Output:

module MyApp.Models

type User = {
    id: int
    name: string
    email: string
    isActive: bool
}

Step 7: Multiple JSON Files

Process multiple schemas with different configurations:

<ItemGroup>
  <FabulousAstJson Include="schemas/user.json"
                   RootName="User"
                   Namespace="MyApp.Models" />
  <FabulousAstJson Include="schemas/product.json"
                   RootName="Product"
                   Namespace="MyApp.Models" />
  <FabulousAstJson Include="schemas/order.json"
                   RootName="CustomerOrder"
                   Namespace="MyApp.Orders" />
</ItemGroup>

<ItemGroup>
  <Compile Include="Generated/user.Generated.fs" />
  <Compile Include="Generated/product.Generated.fs" />
  <Compile Include="Generated/order.Generated.fs" />
</ItemGroup>

Step 8: Custom Output Directory

Change where generated files are placed:

<PropertyGroup>
  <FabulousAstJsonOutputDir>Types/</FabulousAstJsonOutputDir>
</PropertyGroup>

Step 9: Glob Patterns

Process all JSON files in a directory:

<ItemGroup>
  <FabulousAstJson Include="schemas/**/*.json" />
</ItemGroup>

Step 10: Custom Output Filename

Override the default {filename}.Generated.fs pattern:

<ItemGroup>
  <FabulousAstJson Include="schemas/user.json"
                   OutputFileName="UserTypes.fs" />
</ItemGroup>

Configuration Reference

Project Properties

Property Default Description
FabulousAstJsonOutputDir $(MSBuildProjectDirectory)\Generated\ Output directory for generated files
EnableFabulousAstJsonGeneration true Enable/disable generation (useful for CI)

Item Metadata

Metadata Default Description
RootName Root Name of the root type
Namespace (empty) Namespace to wrap types in
ModuleName (empty) Module to wrap types in (alternative to Namespace)
OutputFileName {InputName}.Generated.fs Custom output filename

Type Inference

The generator infers F# types from JSON values:

JSON Value F# Type
"string" string
123 int
9999999999 int64
123.45 float
true/false bool
null obj
[...] ElementType list
{...} Record type

Arrays Become List Types

Input (users.json):

[
    { "id": 1, "name": "Alice" },
    { "id": 2, "name": "Bob" }
]

Output:

type UsersItem = { id: int; name: string }
type Users = UsersItem list

Nested Objects Become Nested Types

Input (company.json):

{
    "name": "Acme Corp",
    "address": {
        "street": "123 Main St",
        "city": "London"
    }
}

Output:

type Address = { street: string; city: string }
type Company = { name: string; address: Address }

Optional Fields

Fields missing or null in some array objects become option types:

Input:

[
    { "id": 1, "name": "Alice", "nickname": "Ali" },
    { "id": 2, "name": "Bob" }
]

Output:

type RootItem = { id: int; name: string; nickname: string option }
type Root = RootItem list

Special Field Name Handling

Leading Digits

JSON fields starting with digits are prefixed with _:

{ "2faEnabled": true }

Generates:

type Root = { _2faEnabled: bool }

Reserved Keywords

F# keywords are escaped with double backticks:

{ "type": "admin", "class": "premium" }

Generates:

type Root = { ``type``: string; ``class``: string }

Incremental Builds

The task uses content hashing for smart rebuilds:

  • Files are only regenerated when JSON content changes
  • Configuration changes (RootName, Namespace, etc.) trigger regeneration
  • Generated files include a hash comment for verification

Troubleshooting

Generated File Not Updating

  1. Ensure the file is included as FabulousAstJson:

    <FabulousAstJson Include="path/to/file.json" />
    
  2. Ensure the generated file is in Compile:

    <Compile Include="Generated/file.Generated.fs" />
    
  3. Try a clean rebuild:

    dotnet clean && dotnet build
    

Task Assembly Not Found

If you see "Skipping generation because task assembly not found":

  1. Ensure you've restored packages: dotnet restore
  2. For local development, build Fabulous.AST.Build first

Disable Generation

Disable generation for CI or specific builds:

<PropertyGroup>
  <EnableFabulousAstJsonGeneration>false</EnableFabulousAstJsonGeneration>
</PropertyGroup>

Or via command line:

dotnet build -p:EnableFabulousAstJsonGeneration=false
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0-pre08 44 6/2/2026
2.0.0-pre07 60 5/30/2026
2.0.0-pre06 88 1/9/2026
2.0.0-pre05 214 12/19/2025
2.0.0-pre04 244 12/15/2025
2.0.0-pre03 143 12/13/2025
2.0.0-pre02 101 12/12/2025
2.0.0-pre01 88 12/12/2025

### Breaking Changes
- Widget builders now return unified base types instead of specific node types
- Raw SyntaxOak nodes must now be wrapped with EscapeHatch when yielding into collections
- Removed obsolete per-node modifiers

### Added
- Unified modifier extensions for widget types
- New EscapeHatch widget for wrapping raw SyntaxOak nodes
- New single-clause overloads for Match and Try expressions
- Parallel test execution enabled

### Changed
- Refactored widget systems to use shared attribute sets
- Internal widget key handlers now wrap nodes appropriately

### Fixed
- Widget key generation fixes