COMPARISON

FO.NET vs IronPDF: Technical Comparison Guide

When .NET developers look at PDF generation solutions, FO.NET stands out as a specialized tool for converting XSL-FO documents to PDF. However, its dependence on the outdated XSL-FO language, lack of HTML/CSS support, and discontinued maintenance status lead many teams to consider alternatives. IronPDF offers a modern solution using HTML/CSS web standards that most developers are already familiar with, featuring a Chromium rendering engine and regular monthly updates.

This comparison reviews both libraries across relevant technical aspects to assist professional developers and architects in making informed decisions for their .NET PDF needs.

Understanding FO.NET

FO.NET (also known as FoNet) is an open-source library designed for converting XSL Formatting Object (XSL-FO) documents into PDFs using C#. The library operates under the Apache 2.0 license and directly maps the XSL-FO language into PDF format.

FO.NET uses FonetDriver as its primary class, with the Make() factory method creating driver instances and Render() methods processing XSL-FO input streams to produce PDF output streams. Configuration happens within the XSL-FO markup itself using elements like fo:simple-page-master, fo:layout-master-set, and formatting attributes for margins, page sizes, and fonts.

A significant limitation is that FO.NET requires XSL-FO knowledge—an XML-based language that is a W3C specification from 2001 with no updates since 2006. The library does not support HTML or CSS and cannot directly render web pages. XSL-FO is largely considered obsolete in today's technology field, with less than 1% of developers having expertise in it compared to over 98% who know HTML/CSS.

The original CodePlex repository is defunct, and GitHub forks are no longer actively maintained. FO.NET has internal dependencies on System.Drawing that prevent it from working on Linux/macOS, limiting it to Windows-only deployment.

Understanding IronPDF

IronPDF is a .NET PDF library that uses HTML/CSS for document styling and layout, using web standards that are common in development. The library uses a Chromium rendering engine, providing full CSS3 support including Flexbox and Grid layouts, plus JavaScript execution.

IronPDF uses ChromePdfRenderer as its primary rendering class, with RenderingOptions providing programmatic configuration for page size, margins, headers, footers, and other PDF settings. The library supports direct URL rendering, HTML string rendering, and HTML file rendering, producing PdfDocument objects that can be saved, merged, secured, or further manipulated.

IronPDF is actively maintained with monthly releases, supports true cross-platform deployment (Windows, Linux, macOS), and provides thorough documentation and tutorials.

Architecture and Technology Comparison

The fundamental difference between these .NET PDF libraries lies in their input format and technology foundation.

AspectFO.NETIronPDF
Input FormatXSL-FO (obsolete XML)HTML/CSS (modern web standards)
Learning CurveSteep (XSL-FO expertise)Gentle (HTML/CSS knowledge)
MaintenanceAbandonedActively maintained monthly
Platform SupportWindows onlyTrue cross-platform
CSS SupportNoneFull CSS3 (Flexbox, Grid)
JavaScriptNoneFull JavaScript support
URL RenderingNot supportedBuilt-in
Modern FeaturesLimitedHeaders, footers, watermarks, security
DocumentationOutdatedComprehensive tutorials

FO.NET was designed when XSL-FO was expected to become a standard for document formatting. That didn't happen—HTML/CSS became the universal document format. Most XSL-FO resources are from 2005-2010, making it increasingly difficult to find current information or community support.

Code Comparison: Common PDF Operations

HTML to PDF Conversion

The most fundamental operation demonstrates the model difference between XSL-FO and HTML approaches.

FO.NET:

// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;

class Program
{
    static void Main()
    {
        // FoNet requires XSL-FO format, not HTML
        // First convert HTML to XSL-FO (manual process)
        string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
            <fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
                <fo:layout-master-set>
                    <fo:simple-page-master master-name='page'>
                        <fo:region-body/>
                    </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference='page'>
                    <fo:flow flow-name='xsl-region-body'>
                        <fo:block>Hello World</fo:block>
                    </fo:flow>
                </fo:page-sequence>
            </fo:root>";

        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("output.pdf", FileMode.Create));
    }
}
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;
using System.Xml;

class Program
{
    static void Main()
    {
        // FoNet requires XSL-FO format, not HTML
        // First convert HTML to XSL-FO (manual process)
        string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
            <fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
                <fo:layout-master-set>
                    <fo:simple-page-master master-name='page'>
                        <fo:region-body/>
                    </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference='page'>
                    <fo:flow flow-name='xsl-region-body'>
                        <fo:block>Hello World</fo:block>
                    </fo:flow>
                </fo:page-sequence>
            </fo:root>";

        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("output.pdf", FileMode.Create));
    }
}
$vbLabelText   $csharpLabel

IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

The contrast is clear. FO.NET requires verbose XSL-FO markup with XML namespace declarations, fo:root, fo:layout-master-set, fo:simple-page-master, fo:page-sequence, fo:flow, and fo:block elements—all before producing a simple "Hello World" text. The code comment explicitly notes: "FoNet requires XSL-FO format, not HTML."

IronPDF creates a renderer, passes standard HTML, renders to PDF, and saves—four simple lines using syntax developers already know.

For advanced HTML rendering options, explore the HTML to PDF conversion guide.

URL to PDF Conversion

Converting web pages to PDF reveals a critical capability gap.

FO.NET:

// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        // FoNet does not support URL rendering directly
        // Must manually download, convert HTML to XSL-FO, then render
        string url = "https://example.com";
        string html = new WebClient().DownloadString(url);

        // Manual conversion from HTML to XSL-FO required (complex)
        string xslFo = ConvertHtmlToXslFo(html); // Not built-in

        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("webpage.pdf", FileMode.Create));
    }

    static string ConvertHtmlToXslFo(string html)
    {
        // Custom implementation required
        throw new System.NotImplementedException();
    }
}
// NuGet: Install-Package Fonet
using Fonet;
using System.IO;
using System.Net;

class Program
{
    static void Main()
    {
        // FoNet does not support URL rendering directly
        // Must manually download, convert HTML to XSL-FO, then render
        string url = "https://example.com";
        string html = new WebClient().DownloadString(url);

        // Manual conversion from HTML to XSL-FO required (complex)
        string xslFo = ConvertHtmlToXslFo(html); // Not built-in

        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("webpage.pdf", FileMode.Create));
    }

    static string ConvertHtmlToXslFo(string html)
    {
        // Custom implementation required
        throw new System.NotImplementedException();
    }
}
$vbLabelText   $csharpLabel

IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

FO.NET explicitly does not support URL rendering. The code comments state: "FoNet does not support URL rendering directly" and "Manual conversion from HTML to XSL-FO required (complex)." The ConvertHtmlToXslFo() method throws NotImplementedException because this conversion is not built-in and would require custom implementation.

IronPDF provides native RenderUrlAsPdf() functionality that handles URL fetching, JavaScript execution, and rendering in a single method call—three lines of code versus a complex, unimplemented workflow.

Learn more about URL rendering in the URL to PDF documentation.

PDF with Custom Settings

Configuring page dimensions and margins demonstrates the configuration approach differences.

FO.NET:

// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;

class Program
{
    static void Main()
    {
        // FoNet settings are configured in XSL-FO markup
        string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
            <fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
                <fo:layout-master-set>
                    <fo:simple-page-master master-name='A4' 
                        page-height='297mm' page-width='210mm'
                        margin-top='20mm' margin-bottom='20mm'
                        margin-left='25mm' margin-right='25mm'>
                        <fo:region-body/>
                    </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference='A4'>
                    <fo:flow flow-name='xsl-region-body'>
                        <fo:block font-size='14pt'>Custom PDF</fo:block>
                    </fo:flow>
                </fo:page-sequence>
            </fo:root>";

        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("custom.pdf", FileMode.Create));
    }
}
// NuGet: Install-Package Fonet
using Fonet;
using Fonet.Render.Pdf;
using System.IO;

class Program
{
    static void Main()
    {
        // FoNet settings are configured in XSL-FO markup
        string xslFo = @"<?xml version='1.0' encoding='utf-8'?>
            <fo:root xmlns:fo='http://www.w3.org/1999/XSL/Format'>
                <fo:layout-master-set>
                    <fo:simple-page-master master-name='A4' 
                        page-height='297mm' page-width='210mm'
                        margin-top='20mm' margin-bottom='20mm'
                        margin-left='25mm' margin-right='25mm'>
                        <fo:region-body/>
                    </fo:simple-page-master>
                </fo:layout-master-set>
                <fo:page-sequence master-reference='A4'>
                    <fo:flow flow-name='xsl-region-body'>
                        <fo:block font-size='14pt'>Custom PDF</fo:block>
                    </fo:flow>
                </fo:page-sequence>
            </fo:root>";

        FonetDriver driver = FonetDriver.Make();
        driver.Render(new StringReader(xslFo), 
            new FileStream("custom.pdf", FileMode.Create));
    }
}
$vbLabelText   $csharpLabel

IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 20;
        renderer.RenderingOptions.MarginBottom = 20;
        renderer.RenderingOptions.MarginLeft = 25;
        renderer.RenderingOptions.MarginRight = 25;

        string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 20;
        renderer.RenderingOptions.MarginBottom = 20;
        renderer.RenderingOptions.MarginLeft = 25;
        renderer.RenderingOptions.MarginRight = 25;

        string html = "<h1 style='font-size:14pt'>Custom PDF</h1>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
$vbLabelText   $csharpLabel

The code comment in FO.NET explicitly states: "FoNet settings are configured in XSL-FO markup." Page size, margins, and formatting are embedded within the XML structure as attributes on fo:simple-page-master. This means configuration is intertwined with content in a verbose XML format.

IronPDF separates configuration from content using programmatic RenderingOptions properties. Settings like PaperSize, MarginTop, MarginBottom, MarginLeft, and MarginRight are set on the renderer object, while content remains clean HTML.

API Mapping Reference

For developers evaluating FO.NET migration or comparing capabilities, this mapping shows equivalent operations:

Core Class Mapping

FO.NETIronPDF
FonetDriver.Make()new ChromePdfRenderer()
driver.Render(inputStream, outputStream)renderer.RenderHtmlAsPdf(html)
driver.Render(inputFile, outputStream)renderer.RenderHtmlFileAsPdf(path)
driver.BaseDirectoryRenderingOptions.BaseUrl
driver.OnError += handlerTry/catch around render

XSL-FO to RenderingOptions Mapping

XSL-FO AttributeIronPDF RenderingOptions
page-height/page-widthPaperSize
margin-topMarginTop
margin-bottomMarginBottom
margin-leftMarginLeft
margin-rightMarginRight
reference-orientationPaperOrientation

XSL-FO Elements to HTML Mapping

XSL-FO ElementHTML Equivalent
<fo:root><html>
<fo:layout-master-set>CSS @page rule
<fo:simple-page-master>CSS @page
<fo:page-sequence><body> or <div>
<fo:flow><main> or <div>
<fo:static-content>HtmlHeaderFooter
<fo:block><p>, <div>, <h1>-<h6>
<fo:table><table>
<fo:list-block><ul>, <ol>
<fo:external-graphic><img>
<fo:page-number/>{page} placeholder

Feature Comparison Summary

FeatureFO.NETIronPDF
HTML to PDF❌ (requires manual XSL-FO conversion)
URL to PDF❌ (not supported)
XSL-FO to PDFN/A
CSS3 Support✅ (Flexbox, Grid)
JavaScript
Headers/FootersXSL-FO static-contentHTML-based
Page Numberingfo:page-number{page} placeholder
Cross-Platform❌ (Windows only)
Active Maintenance❌ (abandoned)✅ (monthly)

When Teams Consider Moving from FO.NET to IronPDF

Development teams evaluate transitioning from FO.NET to IronPDF for several reasons:

Obsolete Technology: XSL-FO is a W3C specification from 2001 that has seen no updates since 2006 and is largely considered obsolete. Most resources and documentation are from 2005-2010, making it increasingly difficult to find current information or hire developers with XSL-FO expertise.

Steep Learning Curve: XSL-FO requires learning complex XML-based markup with specialized formatting objects (fo:block, fo:table, fo:page-sequence, etc.). Less than 1% of developers know XSL-FO compared to over 98% who know HTML/CSS.

No HTML/CSS Support: FO.NET cannot render HTML or CSS—it requires manual conversion from HTML to XSL-FO markup, which is not built into the library. Teams with web content or HTML templates must implement custom conversion logic.

Abandoned Maintenance: The original CodePlex repository is defunct, and GitHub forks are no longer actively maintained. Security patches, bug fixes, and new features are not being developed.

Platform Limitations: FO.NET has internal dependencies on System.Drawing that prevent it from working on Linux/macOS, limiting deployment to Windows-only environments. Modern applications increasingly require cross-platform deployment.

Missing Modern Features: No JavaScript support, no CSS3 features (Flexbox, Grid), no modern web fonts, and no direct URL rendering capability.

Strengths and Considerations

FO.NET Strengths

  • Direct XSL-FO Conversion: Optimized specifically for XSL-FO to PDF conversion
  • Open Source: Apache 2.0 license—free to use, modify, and distribute
  • Precise Control: XSL-FO provides detailed control over document layout

FO.NET Considerations

  • Obsolete Technology: XSL-FO specification has no updates since 2006
  • Requires XSL-FO Knowledge: Less than 1% of developers have expertise
  • No HTML Support: Cannot render HTML or CSS content
  • Abandoned: No active maintenance or security updates
  • Windows Only: System.Drawing dependencies prevent cross-platform use
  • No URL Rendering: Cannot directly convert web pages
  • Limited Documentation: Resources are outdated

IronPDF Strengths

  • HTML/CSS Standard: Uses web technologies over 98% of developers already know
  • Modern Rendering: Chromium engine with full CSS3 and JavaScript support
  • Active Development: Monthly releases with new features and security patches
  • Cross-Platform: True support for Windows, Linux, and macOS
  • Direct URL Rendering: Native RenderUrlAsPdf() capability
  • Professional Features: Headers, footers, watermarks, security—all built-in
  • Comprehensive Resources: Extensive tutorials and documentation

IronPDF Considerations

  • Commercial License: Requires license for production use
  • Different Paradigm: XSL-FO templates need conversion to HTML

Conclusion

FO.NET and IronPDF represent fundamentally different approaches to PDF generation in .NET. FO.NET serves the niche use case of XSL-FO to PDF conversion, but its reliance on obsolete technology, abandoned maintenance, Windows-only limitation, and lack of HTML support make it increasingly difficult to justify for new projects.

IronPDF provides a modern approach using HTML/CSS web standards that aligns with current developer skills and technologies. The ability to directly render HTML, URLs, and use full CSS3 with a Chromium engine makes it suitable for contemporary PDF generation requirements.

As organizations plan for .NET 10, C# 14, and application development through 2026, the technology foundation matters. Teams maintaining legacy XSL-FO systems may continue using FO.NET, but the path forward for modern PDF generation clearly points toward HTML-based solutions like IronPDF that leverage existing web development expertise.

Start evaluating IronPDF with a free trial and explore the comprehensive documentation to assess fit for your specific requirements.