Fabulous.AST.Json 2.0.0-pre08

This is a prerelease version of Fabulous.AST.Json.
dotnet add package Fabulous.AST.Json --version 2.0.0-pre08
                    
NuGet\Install-Package Fabulous.AST.Json -Version 2.0.0-pre08
                    
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.Json" Version="2.0.0-pre08" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Fabulous.AST.Json" Version="2.0.0-pre08" />
                    
Directory.Packages.props
<PackageReference Include="Fabulous.AST.Json" />
                    
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.Json --version 2.0.0-pre08
                    
#r "nuget: Fabulous.AST.Json, 2.0.0-pre08"
                    
#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.Json@2.0.0-pre08
                    
#: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.Json&version=2.0.0-pre08&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Fabulous.AST.Json&version=2.0.0-pre08&prerelease
                    
Install as a Cake Tool

Fabulous.AST.Json

Generate F# types from JSON samples using the Fabulous.AST DSL.

Overview

Fabulous.AST.Json is a programmatic F# type generator that:

  • Takes a JSON sample as input
  • Infers F# record types, nested types, and type aliases
  • Outputs clean, Fantomas-formatted F# code

It is NOT:

  • A runtime JSON deserializer (use System.Text.Json or Newtonsoft.Json for that)
  • A Type Provider (types are generated as source code, not at compile-time)

Use cases:

  • Generating F# types from API response samples
  • Creating type-safe models from JSON schemas
  • Test fixtures and documentation
  • Custom code generation tooling

💡 Tip: For automatic build-time generation from JSON files, use Fabulous.AST.Build instead.

Installation

dotnet add package Fabulous.AST.Json

Requirements: .NET 8.0 or later

Tutorial

Step 1: Basic Type Generation

The simplest use case is generating a record type from a JSON object:

open Fabulous.AST
open Fabulous.AST.Json
open type Ast

let json = """{ "name": "Alice", "age": 30, "active": true }"""

let source =
    Oak() {
        AnonymousModule() {
            Json(json)
        }
    }
    |> Gen.mkOak
    |> Gen.run

printfn "%s" source

Output:

type Root = { name: string; age: int; active: bool }

Step 2: Custom Root Type Name

By default, the root type is named Root. Use .rootName() to customize it:

let json = """{ "id": 1, "email": "alice@example.com" }"""

let source =
    Oak() {
        AnonymousModule() {
            Json(json).rootName("User")
        }
    }
    |> Gen.mkOak
    |> Gen.run

Output:

type User = { id: int; email: string }

Step 3: Nested Objects

Nested JSON objects become nested record types:

let json = """
{
    "user": {
        "name": "Alice",
        "address": {
            "city": "London",
            "country": "UK"
        }
    }
}
"""

let source =
    Oak() {
        AnonymousModule() {
            Json(json).rootName("Response")
        }
    }
    |> Gen.mkOak
    |> Gen.run

Output:

type Address = { city: string; country: string }
type User = { name: string; address: Address }
type Response = { user: User }

Step 4: Arrays

Arrays generate an element type and a list alias:

let json = """
[
    { "id": 1, "name": "Item 1" },
    { "id": 2, "name": "Item 2" }
]
"""

let source =
    Oak() {
        AnonymousModule() {
            Json(json).rootName("Products")
        }
    }
    |> Gen.mkOak
    |> Gen.run

Output:

type ProductsItem = { id: int; name: string }
type Products = ProductsItem list

Step 5: Optional Fields

When analyzing arrays of objects, fields that are missing or null in some objects become option types:

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

let source =
    Oak() {
        AnonymousModule() {
            Json(json).rootName("Users")
        }
    }
    |> Gen.mkOak
    |> Gen.run

Output:

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

Step 6: Relaxed JSON Parsing

Handle JSON with comments and trailing commas:

let json = """
{
    // This is a comment
    "id": 1,
    "name": "Test",  // trailing comma
}
"""

let source =
    Oak() {
        AnonymousModule() {
            Json(json)
                .documentAllowTrailingCommas(true)
                .documentCommentHandling(System.Text.Json.JsonCommentHandling.Skip)
        }
    }
    |> Gen.mkOak
    |> Gen.run

Step 7: Case-Insensitive Property Names

When JSON has inconsistent casing, use case-insensitive matching:

let json = """
[
    { "ID": 1, "Name": "First" },
    { "id": 2, "name": "Second" }
]
"""

let source =
    Oak() {
        AnonymousModule() {
            Json(json).nodePropertyNameCaseInsensitive(true)
        }
    }
    |> Gen.mkOak
    |> Gen.run

Step 8: Adding to a Namespace or Module

Wrap generated types in a namespace:

let json = """{ "id": 1, "name": "Alice" }"""

let source =
    Oak() {
        Namespace("MyApp.Models") {
            Json(json).rootName("User")
        }
    }
    |> Gen.mkOak
    |> Gen.run

Output:

namespace MyApp.Models

type User = { id: int; name: string }

Or in a module:

let source =
    Oak() {
        Module("MyApp.Models") {
            Json(json).rootName("User")
        }
    }
    |> Gen.mkOak
    |> Gen.run

Output:

module MyApp.Models

type User = { id: int; name: string }

Type Inference Rules

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

Special Field Name Handling

Leading Digits

JSON fields starting with digits are prefixed with _:

{ "2faEnabled": true, "3rdPartyId": "abc" }

Generates:

type Root = { _2faEnabled: bool; _3rdPartyId: string }

F# Reserved Keywords

JSON fields that are F# keywords are escaped with double backticks:

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

Generates:

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

API Reference

Available Modifiers

Modifier Description
.rootName(string) Set the name of the root type (default: "Root")
.documentOptions(JsonDocumentOptions) Provide JsonDocumentOptions for parsing
.documentAllowTrailingCommas(bool) Allow trailing commas in JSON
.documentCommentHandling(JsonCommentHandling) Handle JSON comments
.documentMaxDepth(int) Maximum nesting depth
.serializerOptions(JsonSerializerOptions) Seed document options from a serializer config
.nodePropertyNameCaseInsensitive(bool) Case-insensitive property matching
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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 41 6/2/2026
2.0.0-pre07 53 5/30/2026
2.0.0-pre06 90 1/9/2026
2.0.0-pre05 229 12/19/2025
2.0.0-pre04 255 12/15/2025
2.0.0-pre03 157 12/13/2025
2.0.0-pre02 110 12/12/2025
2.0.0-pre01 101 12/12/2025

### Fixed
- JSON field names containing backticks now replace them with underscores instead of producing an invalid nested-backtick identifier (#195)