FSharp.Data is primarily maintained through agentic development under human guidance. Maintainers review and discuss proposed work, then direct coding agents to make the complete change, including implementation, tests, documentation, samples, and other affected files.
We generally prefer contributions as GitHub issues rather than pull requests. Use an issue to report a bug, request a feature, suggest a documentation improvement, or propose another change. Search for an existing report first and add useful context there instead of creating a duplicate.
A useful issue explains the problem or desired outcome, why the change would be valuable, and steps to reproduce a bug with relevant version and platform details. Examples, logs, API sketches, proposed changes, patches, and links to forks or branches are welcome. Maintainers may refine the scope with you and then assign the issue to an agent to implement and validate the complete change.
Repo Assist is an automated AI assistant that runs regularly in this repository. It may triage or respond to issues, investigate bugs, suggest improvements, and attempt implementations as draft pull requests. Its comments and pull requests identify it as automated, and its work remains subject to human review. Repo Assist does not merge pull requests or make final maintenance decisions.
Maintainers can also invoke Repo Assist with /repo-assist <instructions> to perform a specific
agentic task, such as investigating an issue, preparing a fix, adding tests, or updating
documentation. These directed tasks follow the same review process as its scheduled work.
Every pull request must have a matching issue that has been discussed with the maintainers. Open the issue before investing substantial effort, especially for new features, public API changes, or broad refactoring, and link the pull request to it.
Submitting a pull request does not guarantee that its commits will be merged. Maintainers may close the pull request and use the issue as the basis for an agent-produced implementation instead. The original report, analysis, and proposed code remain valuable inputs to that work.
If a pull request is the agreed approach, keep it focused on one issue, follow the existing project conventions, add deterministic tests for behavior changes, update documentation when applicable, and run the relevant build, test, and formatting checks described in AGENTS.md.
Type providers consist of two components:
-
Runtime is the part of the type provider that is actually used when the compiled F# code that uses the provider runs. This assembly also has the non type-provider components of FSharp.Data: the CSV, HTML and JSON parsers, and the HTTP utilities.
-
Design time is the part that is used when editing F# code that uses type provider in your favourite editor or when compiling code. For example, in the CSV provider, this component does the type inference and generates types (that are mapped to runtime components by the compiler).
We need runtime components for .NET Standard 2.0 (netstandard2.0). We also need a design time component, to be able to host the type providers in .NET Core-based tooling.
The core runtime components are the following projects. No type providers are activated if you reference these:
- FSharp.Data.Http
- FSharp.Data.Csv.Core
- FSharp.Data.Html.Core
- FSharp.Data.Json.Core
- FSharp.Data.Xml.Core
The enhanced runtime component that mentions the associated the design-time component is in the following project:
- FSharp.Data
The design-time component is the following project:
- FSharp.Data.DesignTime
Several of the FSharp.Data type providers have similar structure - the CSV, JSON, XML and HTML
providers all infer the types from structure of a sample input. In addition, they all
have a runtime component (CSV parser, HTML parser, JSON parser, and wrapper for XDocument type in .NET).
So, how is a typical type provider implemented? First of all, there are some shared
files - in Common and Library subdirectories of the projects. These contain common
runtime components (such as parsers, HTTP helpers, etc.)
Next, there are some common design-time components. These can be found in Providers
folder (in the 2 design time projects) and contain the ProvidedTypes helpers from the
F# team, StructureInference.fs (which implements type inference for structured data)
and a couple of other helpers.
A type provider, such as JSON provider, is then located in a single folder with a number of files, typically like this:
-
JsonRuntime.fs- the only runtime component. Contains JSON parser and other objects that are called by code generated by the type provider. -
JsonInference.fs- design-time component that infers the structure using the common API inStructureInference.fs. -
JsonGenerator.fs- implements code that generates provided types, adds properties and methods etc. This uses the information inferred by inference and it generates calls to the runtime components. -
JsonProvider.fs- entry point that defines static properties of the type provider, registers the provided types etc.
The WorldBank provider is different. It doesn't need inference, but it still distinguishes between runtime and design-time components, so you'll find at least two files (and possibly some additional helpers).
To debug the type generation, the best way is to change FSharp.Data.DesignTime project to a Console application and hit the Run command in the IDE, setting the breakpoints where you need them.
This will invoke all the type providers manually without locking the files in Visual Studio / Xamarin Studio.
You'll also see in the console output the complete dump of the generated types and expressions.
This is also the process used for the signature tests.
Docs and samples are in the docs directory. To update docs on your own machine, run the following command:
dotnet fsdocs watchYou can now edit documentation and the file watcher will pick up changes, regenerate the docs, and serve them up locally for you to view in a browser.
Docs updates are pushed to the website every time a pull request is merged.