XParsec 1.0.0

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

<div align="center"> <h1 align="center"> <img alt="XParsec logo" src="docs/images/logo.svg" title="Logo" align="center"/> XParsec </h1> </div> <br/>

Documentation NuGet Version

XParsec is a parser combinator library for F#, with several important differences from FParsec:

  • Generalization over collection and token types

With XParsec all common contiguous collections string 'T array ResizeArray<'T> ImmutableArray<'T> and ReadOnlyMemory<'T> can be parsed with essentially the same code.

  • Pure F# implementation

F# is a great .NET language, and with the Fable compiler, a powerful JavaScript language too. XParsec's pure F# implementation provides a robust, easy to use parsing library for Fable target languages.

  • More Performant

XParsec uses newer F# & .NET features like [<InlineIfLambda>], Span<'T>, and struct unions to compete with imperative parsing libraries while remaining terse and easy to reason about. Parsing a single large JSON file takes roughly half the time of FParsec with ~1/6 the allocations.

Method Mean Error StdDev Gen0 Gen1 Gen2 Allocated
XParsecJson 30.61 ms 0.196 ms 0.164 ms 718.7500 625.0000 - 35.61 MB
FParsecJson 61.09 ms 0.267 ms 0.208 ms 4555.5556 777.7778 222.2222 208.37 MB
  • Simplified operator precedence parsing
  • No line number tracking by default. A separate line ending parser is available for generating detailed error messages.
  • <|>, choice, and choiceL always backtrack. There is no attempt combinator because every alternative already behaves like one. See Migrating from FParsec below.

Detailed Error Messages

The quick brown fox jumps over the lazy dog.
    ^ At index 4 (Ln 1, Col 5)
All choices failed.
├───Expected 'a'
└───All choices failed.
    ├───Unexpected 'q'
    └───Expected 'c'

Real-world usage

XParsec is capable of parsing extremely complex grammars, including F# itself. I'm documenting building a complete F# language parser with XParsec in an ongoing blog series, starting with the prologue.

Migrating from FParsec

XParsec is API-shaped to be familiar to FParsec users, but a few semantics are deliberately different. Two are worth calling out:

  • <|>, choice, and choiceL always backtrack. FParsec's alternative combinators only continue to the next branch if the previous branch failed without consuming input; you wrap branches in attempt to force backtracking after partial consumption. XParsec's alternatives save the reader position before running each branch and restore it on any failure. There is no attempt combinator — drop attempt calls when migrating; every alternative already behaves like one. The save is a struct copy, so the always-backtrack default is cheap.
  • pzero produces a structural Empty error. Aggregating combinators (<|>, choice, manyTill, …) filter Empty siblings before constructing nested errors, so pzero <|> p propagates only p's error rather than wrapping a blank stub. The default formatter renders nothing for Empty.

If you need "fail in place when input was consumed" behaviour for a specific alternative, use notFollowedBy/<?> to gate or relabel rather than reaching for attempt.

Running Tests

.NET

dotnet test

Fable JS

npm run test
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on XParsec:

Package Downloads
Partas.Tools.SepochSemver

An opinionated spec extension and parser of Semver with an optional EPOCH and Scope prefix.

Partas.Tools.ConventionalCommits

Conventional Commits v1.0.0 spec commit message parser.

Fidelity.Toml

A fully TOML 1.0.0 compliant parser and serializer for F#, built with XParsec. BCL-minimal design for future self-hosting.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 42 5/9/2026
0.4.1 128 4/19/2026
0.4.0 205 3/28/2026
0.3.1 755 1/15/2026
0.3.0 259 1/1/2026
0.2.5 639 12/9/2025
0.2.4 384 11/23/2025
0.2.3 209 10/12/2025
0.2.2 324 8/27/2025
0.2.1 2,075 8/4/2025
0.2.0 1,092 7/3/2025
0.1.0 340 4/20/2025
0.0.3 257 4/6/2025
0.0.2 174 4/5/2025