<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: IronSoftware</title>
    <description>The latest articles on DEV Community by IronSoftware (@ironsoftware).</description>
    <link>https://dev.to/ironsoftware</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F714737%2F30e70529-1628-476f-9a14-3b157c0f5c82.png</url>
      <title>DEV Community: IronSoftware</title>
      <link>https://dev.to/ironsoftware</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ironsoftware"/>
    <language>en</language>
    <item>
      <title>QuestPDF's $1M Cap: What Happens When You Outgrow It</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Mon, 08 Jun 2026 18:08:23 +0000</pubDate>
      <link>https://dev.to/ironsoftware/questpdfs-1m-cap-what-happens-when-you-outgrow-it-4el3</link>
      <guid>https://dev.to/ironsoftware/questpdfs-1m-cap-what-happens-when-you-outgrow-it-4el3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Disclosure: I'm on the team at Iron Software, which makes IronPDF.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The board-meeting moment
&lt;/h2&gt;

&lt;p&gt;There is a particular meeting that happens at growing SaaS companies, usually in the second half of a year that has gone better than the founders expected. Revenue is on track to cross $1M. The board deck is polished. And somewhere on slide eleven, a finance lead mentions that one of the company's core dependencies is a PDF library called QuestPDF, and that the Community License the engineering team adopted four years ago at the seed stage no longer fits the company that has emerged.&lt;/p&gt;

&lt;p&gt;This lays out the math you can run yourself rather than telling you which library to buy.&lt;/p&gt;

&lt;p&gt;Many teams reach the moment described above. The architectural decision they are about to revisit is one they made under different conditions: smaller team, no revenue, optimistic timeline. The library they chose was, in many cases, &lt;a href="https://www.questpdf.com/" rel="noopener noreferrer"&gt;QuestPDF&lt;/a&gt;. The conversation is happening not because QuestPDF did anything wrong. It is happening because the company grew.&lt;/p&gt;

&lt;p&gt;That is a good problem to have. It is also a problem with a number on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What QuestPDF is, and why teams keep choosing it
&lt;/h2&gt;

&lt;p&gt;Before the licensing math, the technical reality. QuestPDF deserves the credit it gets.&lt;/p&gt;

&lt;p&gt;The library &lt;a href="https://www.nuget.org/packages/QuestPDF" rel="noopener noreferrer"&gt;released version 2026.2.4 in March 2026&lt;/a&gt;, continuing a release cadence that has been remarkably consistent over multiple years. Total NuGet downloads sit above 21 million. The GitHub repository has more than 14,000 stars and an open-issue backlog that, while non-trivial, is being worked. By the standards of .NET PDF tooling, where some "free" libraries have not seen a meaningful commit in half a decade, QuestPDF is one of the most actively maintained options in its category.&lt;/p&gt;

&lt;p&gt;The fluent API is the part most engineers fall in love with. It reads almost like a templating language inside C#. Defining a page, adding a header, composing a table, controlling page breaks: each operation is a chained method call. There is no XAML, no HTML rendering pipeline, no headless browser. The library runs as managed .NET code on whatever runtime your application targets, including current LTS releases such as .NET 8 (supported through November 2026) and .NET 10 (supported through November 2028, per &lt;a href="https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core" rel="noopener noreferrer"&gt;Microsoft's official policy&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A sample of the kind of code an engineer writes against it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QuestPDF.Fluent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QuestPDF.Helpers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;QuestPDF.Infrastructure&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;QuestPDF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LicenseType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Community&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PageSizes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Margin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Centimetre&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Q3 Customer Statement"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;FontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Bold&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Prepared by Acme Corp, automated billing pipeline."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;PaddingTop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated at: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"u"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Footer&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;AlignCenter&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Span&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Page "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CurrentPageNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Span&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" of "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TotalPages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GeneratePdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"statement.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anyone who has tried to drive a PDF generator with imperative coordinates and cursor positions can feel the difference. Code like this is reviewable, testable, and something a backend engineer who is not a PDF specialist can pick up in an afternoon and ship by the end of the week.&lt;/p&gt;

&lt;p&gt;That accessibility is the real reason QuestPDF caught on. The .NET ecosystem has had PDF libraries for two decades, but until QuestPDF, it did not have a free one whose API felt designed by someone who actually likes writing C#. The library's &lt;a href="https://www.questpdf.com/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; is also unusually good for an open-source project: complete, organized, with worked examples for the layout primitives most teams will need.&lt;/p&gt;

&lt;p&gt;QuestPDF is genuinely good. If your annual gross revenue is under $1M USD, QuestPDF is a defensible default and arguably the strongest free option in the .NET PDF space. The Community MIT License lets you ship it in a closed-source commercial product without ambiguity. The maintainer cadence is real. The API is good. There is no asterisk on this paragraph.&lt;/p&gt;

&lt;p&gt;The asterisk lives on the next page of the same document.&lt;/p&gt;

&lt;h2&gt;
  
  
  The licensing model, in plain English
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/QuestPDF/QuestPDF/blob/main/LICENSE.md" rel="noopener noreferrer"&gt;QuestPDF's published licensing model&lt;/a&gt; has three tiers. The thresholds and prices below are sourced from the project's own license documentation and pricing page as of May 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 1: Community MIT License (free).&lt;/strong&gt; Available to open-source projects, charities, and educational use; transitive dependency consumption (you depend on a library that depends on QuestPDF); and companies with annual gross revenue under $1M USD.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 2: Professional License ($999, perpetual, plus local tax, per QuestPDF's &lt;a href="https://www.questpdf.com/license/" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt;).&lt;/strong&gt; Required when your company has crossed the $1M revenue threshold and has up to 10 developers using QuestPDF. The fee is one-time; the version you license remains valid forever, with one year of updates included and optional annual renewal at the same price for continued updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 3: Enterprise License ($2,999, perpetual, plus local tax).&lt;/strong&gt; Required when your company has crossed the $1M threshold and has more than 10 developers using QuestPDF (organization-wide, no per-seat counting). Same perpetual structure as Professional.&lt;/p&gt;

&lt;p&gt;A note on the pricing model: this is a perpetual license, not a subscription. The version you pay for never stops working, even if you decline renewal. Most growing teams will renew anyway, because they want the security patches and feature updates that ship in subsequent releases, but the renewal is for &lt;em&gt;updates&lt;/em&gt;, not for the right to keep running the library at all. Throughout the rest of this article, when we model "$999/year" or "$2,999/year" we mean the renewal cadence most teams will adopt, not a subscription that switches off if missed.&lt;/p&gt;

&lt;p&gt;Now we have enough to model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hidden threshold: why QuestPDF isn't truly free for growing companies
&lt;/h2&gt;

&lt;p&gt;The "Community" framing on QuestPDF's MIT tier is accurate as the maintainer has documented it, and the documentation is the cleanest in the .NET PDF ecosystem on the question. The framing is also, structurally, a soft trap for any company whose trajectory is "small now, growing." The license terms themselves are published openly; the trap lies in the cognitive shape of how teams adopt the library.&lt;/p&gt;

&lt;p&gt;Three properties of QuestPDF's commercial gate are worth surfacing explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The threshold is self-attested.&lt;/strong&gt; QuestPDF's &lt;a href="https://www.questpdf.com/license/guide.html" rel="noopener noreferrer"&gt;license guide&lt;/a&gt; names the figure ($1M USD in annual gross revenue), names the currency, and ties the upgrade obligation to crossing that figure. There is no audit clause, no automated revenue probe, no trigger event the maintainer enforces from outside. The honor system is the system. That sounds permissive, and at the engineering level it is. At the legal level it means a company that crosses the threshold and does not upgrade is operating a commercial library outside its license terms, and the absence of an audit does not change that fact when the question reaches the company's legal department, an acquirer's due diligence, or a customer's vendor-risk review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The threshold is binary, not graduated.&lt;/strong&gt; There is no "between $1M and $10M" tier where the obligation is partial. A company at $999,999 in annual gross revenue owes nothing. A company at $1,000,001 owes the Professional or Enterprise fee in full. This is a perfectly defensible commercial design, but it means there is no early-warning phase: the obligation arrives on the day the financial reports cross the line, and most engineering teams hear about it after the fact, when finance is already preparing year-end statements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The threshold is tied to the company, not to the project.&lt;/strong&gt; Companies sometimes assume the $1M figure applies to revenue from the specific product using QuestPDF. It doesn't. The license measures total annual gross revenue of the licensee. A company whose QuestPDF-using product generates $50K but whose other lines of business produce $5M is over the threshold for QuestPDF licensing purposes.&lt;/p&gt;

&lt;p&gt;The combined effect of these three properties is that "free" in QuestPDF's Community tier means "free until your company outgrows the tier, after which it is paid retroactively from the moment of crossing." For sub-threshold companies, this changes nothing. For companies on a growth curve, this is the fact the State C migration scenario below exists to model.&lt;/p&gt;

&lt;p&gt;None of the above is a complaint about QuestPDF's commercial model. The model is reasonable and the threshold is generous by industry standards. The point is that the word "free" carries a temporal qualifier most adoption discussions do not name out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  The TCO model
&lt;/h2&gt;

&lt;p&gt;Here is the question every engineering leader at a growing company should be able to answer in a sentence: what does the next five years of PDF generation cost?&lt;/p&gt;

&lt;p&gt;For QuestPDF, the calculation has three states.&lt;/p&gt;

&lt;h3&gt;
  
  
  State A: Sub-threshold (revenue under $1M)
&lt;/h3&gt;

&lt;p&gt;Year-1 cost: $0. Year-2 cost: $0. Integration time: whatever you would spend on any library; call it a week or two of one engineer.&lt;/p&gt;

&lt;p&gt;This is genuinely free. The company that stays under $1M in annual gross revenue indefinitely owes QuestPDF nothing, ever. For lifestyle businesses, internal tools at non-revenue-generating organizations, side projects, and pre-revenue startups, this is the right answer. Use QuestPDF.&lt;/p&gt;

&lt;h3&gt;
  
  
  State B: Cross the threshold, license commercially
&lt;/h3&gt;

&lt;p&gt;Year you cross $1M: license becomes mandatory. Up to 10 devs: $999/year. Beyond 10: $2,999/year. Five-year exposure for a small-team company: $4,995. Five-year exposure for an enterprise-license company: $14,995.&lt;/p&gt;

&lt;p&gt;These are real numbers, but they are not scary numbers by enterprise-software standards. The Professional License at $999/year is roughly a mid-tier monitoring SaaS subscription. The Enterprise License at $2,999/year is below the noise floor for most engineering org budgets.&lt;/p&gt;

&lt;p&gt;If your company crosses the revenue threshold and your engineering culture is comfortable with a quiet annual line item, this is the rational path. Pay the license. Keep using the library you already use.&lt;/p&gt;

&lt;h3&gt;
  
  
  State C: Cross the threshold, migrate away
&lt;/h3&gt;

&lt;p&gt;This is the most expensive path, and a common one.&lt;/p&gt;

&lt;p&gt;The pattern: a company adopted QuestPDF at the seed stage. Three years later, revenue is approaching $1M. Someone in finance flags the licensing terms during a vendor audit. The engineering team's first instinct is to evaluate alternatives rather than sign a license, partly cost-optimization reflex, partly accumulated frustration with one or two QuestPDF-shaped corners in the codebase, partly because nobody likes being told they have to buy something they used to get free.&lt;/p&gt;

&lt;p&gt;The migration cost is where the model gets interesting. PDF generation is rarely an isolated module. By the time a company crosses the revenue threshold, the library is woven into report generation, customer statements, invoice rendering, contract output, signed audit trails, regulatory filings. A typical cross-section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;12 to 25 distinct PDF output paths in the codebase.&lt;/li&gt;
&lt;li&gt;200 to 600 lines of fluent-API layout code per path, on average.&lt;/li&gt;
&lt;li&gt;Test coverage tied to specific rendering output.&lt;/li&gt;
&lt;li&gt;Visual-regression tests with checked-in reference PDFs.&lt;/li&gt;
&lt;li&gt;Cross-team ownership: a generation library is rarely owned by one squad.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A realistic migration estimate for a company in this state: &lt;strong&gt;two to four engineer-months for the migration itself, plus one to two engineer-months for QA and visual regression&lt;/strong&gt;. At a fully-loaded cost of around $15,000 per engineer-month (conservative for a US-based mid-level engineer), that is &lt;strong&gt;$45,000 to $90,000 in real spend&lt;/strong&gt;, plus opportunity cost on roadmap features that did not get built during the migration window.&lt;/p&gt;

&lt;p&gt;Compare that to a Professional License: $999 a year for ten years before the migration math breaks even. The Enterprise License: about fifteen years.&lt;/p&gt;

&lt;p&gt;Migration only makes financial sense if you are moving &lt;em&gt;to&lt;/em&gt; something that solves a problem the licensing fee does not, or if your migration target was always going to be necessary anyway because of feature requirements QuestPDF does not cover: HTML-to-PDF rendering, digital signatures, PDF/A archival output, accessibility tagging, OCR integration. For those workflows, the license fee is not the deciding number. The feature gap is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision is not about quality
&lt;/h2&gt;

&lt;p&gt;Nothing here says QuestPDF is bad. QuestPDF is technically excellent, the maintainer's commercial model is reasonable, and the price points are fair for what is offered.&lt;/p&gt;

&lt;p&gt;The decision is about &lt;em&gt;fit&lt;/em&gt;: what curve your company is on, what features you need, and how much engineering time you are willing to spend on a migration that buys nothing your users will see.&lt;/p&gt;

&lt;p&gt;For the company under $1M in revenue, whose PDF needs are layout-focused and whose roadmap does not include the features QuestPDF has chosen not to build, the answer is QuestPDF. That answer is not even close. There is no commercial library at the same price.&lt;/p&gt;

&lt;p&gt;For the company growing into the $1M boundary, whose PDF surface area is large and whose feature roadmap includes any of the items on the list above, the question worth asking before adopting any free PDF library is the one this piece opened with: what does the board meeting in year three look like?&lt;/p&gt;

&lt;p&gt;If the answer makes you reach for a calculator, you have already done the analysis. The numbers will tell you the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  When your input is HTML, not C
&lt;/h2&gt;

&lt;p&gt;QuestPDF builds documents from a C# layout API and &lt;strong&gt;deliberately does not render HTML&lt;/strong&gt;. That is a clean model when the document originates in code, and an awkward one when the source of truth is an HTML or Razor template produced by a design team, an email system, or an existing web view, because reproducing that layout means rebuilding it by hand. Teams in that position, along with companies that have crossed QuestPDF's $1M revenue line and would rather buy a perpetual license with support than re-architect, usually want an HTML-first renderer. A commercial library can provide that. IronPDF, for example, takes &lt;a href="https://ironpdf.com/how-to/html-string-to-pdf/" rel="noopener noreferrer"&gt;an HTML string straight to PDF&lt;/a&gt; and &lt;a href="https://ironpdf.com/how-to/razor-to-pdf-blazor-server/" rel="noopener noreferrer"&gt;renders Razor and Blazor components&lt;/a&gt; directly, keeping the template as the source of truth instead of porting it into layout code.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Has your team crossed QuestPDF's $1M line yet? Did you license, migrate, or rearchitect, and how did the numbers come out?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ironpdf.com/start-free/trial/" rel="noopener noreferrer"&gt;Try IronPDF free for 30 days, no credit card, no watermark: &lt;code&gt;dotnet add package IronPdf&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>startup</category>
      <category>pdf</category>
    </item>
    <item>
      <title>iText in .NET: 3 Legitimate Paths Before You dotnet add</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Mon, 08 Jun 2026 17:53:39 +0000</pubDate>
      <link>https://dev.to/ironsoftware/itext-in-net-3-legitimate-paths-before-you-dotnet-add-1411</link>
      <guid>https://dev.to/ironsoftware/itext-in-net-3-legitimate-paths-before-you-dotnet-add-1411</guid>
      <description>&lt;h2&gt;
  
  
  The moment of adoption
&lt;/h2&gt;

&lt;p&gt;Picture the most ordinary version of this decision. A senior .NET developer, mid-sprint, needs PDF generation for a customer feature. They open a terminal, type &lt;code&gt;dotnet add package itext7&lt;/code&gt;, watch NuGet resolve the dependency, and move on. No license dialog. No compliance prompt. No conversation with legal. The package installs, the code compiles, the feature ships. The license terms, a substantive document with substantive obligations, were technically agreed to at the moment of &lt;code&gt;dotnet restore&lt;/code&gt;, but the act of agreeing was structurally invisible.&lt;/p&gt;

&lt;p&gt;The point here is the difference between adopting a library and choosing one, rather than which library is better. For iText, those are not the same act, and the difference matters enough to be worth a deliberate look.&lt;/p&gt;

&lt;p&gt;This article offers a framework. iText's licensing is publicly documented, technically clean, and defensible on the maintainer's terms. There are three legitimate paths a .NET team can take with it, and the goal is to make each path a chosen one rather than a discovered one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What iText is, and what it has earned
&lt;/h2&gt;

&lt;p&gt;Before any license analysis, the technical reality. A library nobody wants to use does not generate licensing conversations.&lt;/p&gt;

&lt;p&gt;iText has been in continuous development since 1999, and is one of a small number of PDF SDKs whose feature coverage maps to substantially the full ISO PDF specification rather than a commercially convenient subset. The .NET port (&lt;code&gt;itext&lt;/code&gt; on NuGet) reached version &lt;a href="https://www.nuget.org/packages/itext/" rel="noopener noreferrer"&gt;9.6.0 in April 2026&lt;/a&gt;, with a public cadence that ships multiple minor versions per year. iText is owned by &lt;a href="https://apryse.com/" rel="noopener noreferrer"&gt;Apryse&lt;/a&gt;, which acquired the iText Group in &lt;a href="https://apryse.com/blog/news/pdftron-acquires-itext" rel="noopener noreferrer"&gt;April 2022&lt;/a&gt; and rebranded from PDFTron in February 2023. The transition did not interrupt the engineering trajectory; the codebase has stayed healthy across two decades and a change of ownership.&lt;/p&gt;

&lt;p&gt;What makes iText technically credible, and what most adopters are reaching for even if they could not articulate it at install time, is the depth of standards coverage. PDF/A archival profiles (A-1 through A-4) for record-retention compliance. PDF/UA accessibility tagging for regulated disclosures. ISO-32000-2 (PDF 2.0) features. Full digital-signature workflows including PAdES levels and PKCS11 hardware-token signing. Post-quantum signing primitives in the &lt;a href="https://kb.itextpdf.com/itext/release-itext-core-9-5-0" rel="noopener noreferrer"&gt;9.5 release&lt;/a&gt;. Brotli-compressed streams, AES-256 encryption, XFA forms, page-level redaction with proper content-stream rewriting (genuinely hard to get right), OCR via the pdfOCR add-on, and a low-level object model that exposes essentially every node of the PDF tree.&lt;/p&gt;

&lt;p&gt;That feature surface is uncommon. Regulated workflows in finance, life sciences, and the public sector require PDF/A archival output, digital signatures with timestamping, PDF/UA tagging, and audit-trail formats that map to specific ISO standards. The .NET ecosystem has many PDF libraries; the count whose feature breadth covers the full regulated-industry standards landscape is small, and iText sits at the top of it. When a team picks iText for a regulated-document workflow, the choice is rational on the technical merits, often the most rational technical choice available.&lt;/p&gt;

&lt;p&gt;The maintainer's track record reinforces this. The &lt;a href="https://kb.itextpdf.com/itext/releases" rel="noopener noreferrer"&gt;iText 9 release timeline&lt;/a&gt; shows steady minor releases, with iText Core 9.6.0 the most recent at the time of writing. iText 8 reaches end-of-life in October 2026 per the &lt;a href="https://kb.itextpdf.com/itext/release-itext-core-9-1" rel="noopener noreferrer"&gt;iText Core 9.1 announcement&lt;/a&gt;, giving teams a clear migration runway. Release notes read like the changelog of a library taken seriously: appropriate bug-fix density, deprecation cycles communicated in advance, ISO standards work tracked publicly. The post-acquisition Apryse era has not slowed the cadence. By the standards of long-lived open-source projects, iText sits in the top decile on maintainership consistency.&lt;/p&gt;

&lt;p&gt;The dual-license structure is itself a virtue worth naming. iText publishes the AGPL terms on its own site in plain English, explains the obligations in the maintainer's voice, and offers a clearly delineated commercial alternative. The posture is explicit, openly stated, and free of legalese, and it is consistently presented across iText's website, NuGet metadata, and source repositories. A team that wants to know what they are agreeing to can know in fifteen minutes of reading.&lt;/p&gt;

&lt;p&gt;Legitimate use cases for iText AGPL are real and substantial. Open-source projects whose own license is AGPL-compatible can adopt iText with the obligations posing no marginal cost; the product is already open. Academic and reproducible-research workflows align naturally with source disclosure. Internal-only enterprise tools that are not network-deployed to external users sit outside §13's network-interaction trigger. Government and public-sector deployments where source transparency is itself a goal can choose AGPL deliberately. SaaS products explicitly built on AGPL-compatible terms are viable too; some companies treat source disclosure as a product feature rather than a constraint. None of these are workarounds; they are the use cases the maintainer designed the AGPL distribution to serve.&lt;/p&gt;

&lt;p&gt;The commercial tier, in turn, is a reasonable professionally-supported path for teams whose deployment model does not align with AGPL. Customers receive warranted intellectual property, professional support and maintenance per the &lt;a href="https://itextpdf.com/how-buy" rel="noopener noreferrer"&gt;How to buy&lt;/a&gt; page, release from the AGPL obligations, and a contractual relationship with a commercial entity. The maintainer's business model is to monetize commercial use through this tier, and that model is defensible: it funds the engineering depth that produces the standards coverage. Without commercial revenue, the breadth of the open-source distribution would not exist on this scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The license, in iText's own words
&lt;/h2&gt;

&lt;p&gt;iText is published under a &lt;a href="https://itextpdf.com/how-buy" rel="noopener noreferrer"&gt;dual-license model&lt;/a&gt;. The free distribution is licensed under the &lt;a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noopener noreferrer"&gt;GNU Affero General Public License version 3&lt;/a&gt;. The paid distribution is licensed under one of Apryse's commercial agreements: a Volume-based subscription priced on the quantity of PDF files processed, or an OEM Distribution license with custom terms. Both ship the same technical capability; the difference is the licensing terms.&lt;/p&gt;

&lt;p&gt;iText's &lt;a href="https://itextpdf.com/how-buy/AGPLv3-license" rel="noopener noreferrer"&gt;AGPL documentation page&lt;/a&gt; describes the obligations in the maintainer's voice. Three statements, quoted verbatim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"you must prominently mention iText and include the iText copyright and AGPL license in output file metadata, and also retain the producer line in every PDF that is created or manipulated using iText."&lt;/p&gt;

&lt;p&gt;"You may not deploy it on a network without disclosing the full source code of your own applications under the AGPL license. You must distribute all source code, including your own product and web-based applications."&lt;/p&gt;

&lt;p&gt;"It's a legal violation to use iText Core/Community and our open source add-ons in a non-AGPL environment."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those statements come from the maintainer, not from a critic. The structural implication: iText's vendor explicitly characterizes use of the free distribution inside a closed-source product as outside the license's intended scope. Apryse intends the AGPL distribution as the deliberate-AGPL path and the commercial distribution as the closed-source-product path. Both are legitimate; the choice is the adopter's.&lt;/p&gt;

&lt;p&gt;The legal mechanism behind the network-disclosure obligation is AGPL §13, quoted in full from the &lt;a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noopener noreferrer"&gt;Free Software Foundation's canonical text&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;§13 is what makes AGPL different from GPL. Standard GPL is triggered by &lt;em&gt;distribution&lt;/em&gt; of the binary. AGPL adds a trigger for &lt;em&gt;network interaction&lt;/em&gt;: a SaaS company that runs AGPL code on its own servers and never ships the binary is still inside §13's scope the moment a user interacts with the application over a network. The maintainer's plain-English summary is the same obligation expressed in product terms.&lt;/p&gt;

&lt;p&gt;The implications are non-obvious to casual readers. A .NET team accustomed to MIT and Apache 2.0 dependencies, where the full set of obligations is "preserve the copyright notice," may model iText's license slot in a manifest as similar in shape. It is structurally different. That difference is what deserves the deliberate look.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AGPL trap and what it costs closed-source teams
&lt;/h2&gt;

&lt;p&gt;The AGPL framing in the maintainer's own documentation is the second move in a two-step history that most teams installing &lt;code&gt;dotnet add package itext7&lt;/code&gt; have not heard. The first move happened on December 1, 2009. Up to that date, iText shipped under the &lt;a href="https://en.wikipedia.org/wiki/IText" rel="noopener noreferrer"&gt;MPL/LGPL dual-license&lt;/a&gt;, a permissive arrangement that placed iText in the same risk category as MIT or Apache 2.0 dependencies. iText 2.1.7 was the &lt;a href="https://kb.itextpdf.com/it5kb/can-itext-2-1-7-itextsharp-4-1-6-or-earlier-be-use" rel="noopener noreferrer"&gt;last release under those terms&lt;/a&gt;. iText 5 and everything after it shipped under AGPL v3.&lt;/p&gt;

&lt;p&gt;That switch is the moment "iText is free" stopped being a complete sentence. Every team running iText 5, 7, 8, or 9 in a closed-source product is now operating under a copyleft license whose §13 network-interaction clause is structurally incompatible with the SaaS deployment model most .NET teams default to. The maintainer's commercial license is the documented escape hatch. The trap, as it is often experienced, comes from the installation that bypassed the license entirely rather than from the license itself.&lt;/p&gt;

&lt;p&gt;The pattern repeats often enough to be predictable. A team prototypes with iText AGPL. The prototype ships. Two years later, a SOC 2 reviewer, an acquisition due-diligence team, or an enterprise customer's security questionnaire flags iText in the SBOM and asks whether the company holds a commercial license. The answer is no, because nobody ever bought one. The team's three options at that moment are the same as Apryse intends: open-source the entire codebase (rarely feasible), purchase a commercial subscription on terms negotiated under time pressure, or migrate to a different library at the cost of weeks of engineering time the roadmap did not budget for.&lt;/p&gt;

&lt;p&gt;There is nothing dishonest about iText's posture. The license terms are published clearly, the maintainer explains them in their own voice, and the AGPL distribution is itself a legitimate offering for teams whose deployment model fits. The trap is structural, not editorial. It exists because &lt;code&gt;dotnet add package itext7&lt;/code&gt; does not read a license file aloud, and because the version of "free" most developers carry in their head is closer to MIT than to AGPL. For closed-source commercial teams, the practical answer is to treat iText as a paid library by default and to engage Apryse sales before adoption rather than after the audit.&lt;/p&gt;

&lt;p&gt;This is the case where "not recommended for commercial use" needs the qualifier "not recommended for closed-source commercial use without a commercial license." iText is unambiguously safe for AGPL-compatible projects and unambiguously expensive (in license fees, migration cost, or compliance exposure) for everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the commercial path actually looks like
&lt;/h2&gt;

&lt;p&gt;Apryse does not publish a price card; the &lt;a href="https://itextpdf.com/how-buy" rel="noopener noreferrer"&gt;How to buy&lt;/a&gt; page directs interested customers to sales for both commercial offerings. The &lt;strong&gt;Volume-based subscription&lt;/strong&gt; scales cost with usage, "based on the quantity of PDF files processed" per the maintainer's description. The transition from perpetual to subscription pricing happened on &lt;a href="https://itextpdf.com/blog/itext-news/itext-transitions-subscription-based-commercial-licenses" rel="noopener noreferrer"&gt;April 2, 2020&lt;/a&gt;, so any pricing comparison from before that date no longer applies. The &lt;strong&gt;OEM Distribution license&lt;/strong&gt; is for vendors who embed iText in a shipped product; pricing is fully bespoke. Both tiers release the customer from AGPL obligations and provide professional support and maintenance.&lt;/p&gt;

&lt;p&gt;The point about pricing is structural: cost-modeling for iText commercial requires a sales conversation. That is not a defect; it is consistent with a usage-shaped commercial model. It does mean the cost of Path B (below) cannot be modeled from public sources alone. A team considering iText commercial should engage Apryse sales early, scope the deployment honestly, and obtain a quote reflecting their actual usage profile before treating commercial-iText as a known-cost option. Engaging early in this context means what it means with any usage-priced enterprise vendor: an initial discovery conversation is normally free and does not commit either side to anything; an honest scope discussion of expected document volumes, deployment footprint, and any standards-coverage features the workload depends on costs nothing beyond the meeting time; and the resulting written quote is something the team can take into the build-vs-buy review without obligation. None of those steps commits a team to licensing; they exist so the team can model Path B accurately before the decision is in front of the budget owner.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three legitimate paths
&lt;/h2&gt;

&lt;p&gt;For a .NET team standing at the moment of &lt;code&gt;dotnet add package itext7&lt;/code&gt;, three paths are legitimate, and the right one depends on the team's situation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path A: Adopt iText AGPL deliberately
&lt;/h3&gt;

&lt;p&gt;For teams whose deployment context aligns with AGPL's obligations: open-source projects whose own license is AGPL-compatible, academic and reproducible-science workflows, internal-only enterprise tools that never expose iText-using code to external network users, government and public-sector projects where source disclosure aligns with mission, and SaaS products explicitly built on AGPL-compatible terms.&lt;/p&gt;

&lt;p&gt;Criterion: the team has read AGPL §13, confirmed with counsel that the deployment model meets the obligations, and is choosing AGPL because it fits, not because it was the default at install time. Cost: ongoing engineering discipline around attribution and source-disclosure obligations. Benefit: zero license fee for a feature surface that would otherwise be expensive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path B: Adopt iText commercial
&lt;/h3&gt;

&lt;p&gt;For teams who need iText's specific feature set (PDF/A breadth, PAdES signing, PDF/UA tagging, advanced redaction, OCR) inside a closed-source commercial product. The commercial license is the professionally-supported channel for using iText in a closed-source context.&lt;/p&gt;

&lt;p&gt;Criterion: the team needs coverage that iText offers and a non-iText alternative does not (or does not at acceptable engineering cost), and the deployment model is closed-source commercial. Cost: the commercial subscription, scaling with usage. Benefit: full feature surface with warranted IP, professional support, and a contractual counterparty for procurement. For SaaS deployments at scale, the line item is real and grows with the business; the implication is to engage sales early and model the cost honestly against the value the feature surface delivers, before the team has architected itself into a position where switching libraries would be expensive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path C: Use a different library
&lt;/h3&gt;

&lt;p&gt;For teams whose required feature set does not justify the iText commercial cost, or whose licensing posture is permissive-only (MIT, Apache 2.0) by policy. The .NET PDF ecosystem includes multiple legitimate alternatives across MIT-licensed open-source, permissively-licensed commercial, and free-for-commercial-use options. Path C means deliberately choosing a library whose license posture matches the team's deployment model when neither iText path fits, without prescribing a single product.&lt;/p&gt;

&lt;p&gt;Criterion: the feature set the team actually needs is achievable on a non-iText library at acceptable engineering investment, and the team's licensing posture is misaligned with AGPL. Cost: the engineering work to evaluate alternatives and possibly accept a feature gap. Benefit: a license slot in the dependency manifest that does not require a sales conversation or an AGPL §13 reading to defend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;The moment we opened with (a developer typing &lt;code&gt;dotnet add package itext7&lt;/code&gt;, NuGet resolving, the feature shipping) deserves a deliberate answer from your team, not a default one. iText is a technically excellent library with a clearly documented dual-license structure, and either path within iText is legitimate when chosen on its merits: AGPL with intent, or commercial with contract. So is the third path, of using a different library when neither iText path fits. What is not legitimate is the unchosen path: an AGPL dependency inside a closed-source commercial product, adopted as a side-effect of &lt;code&gt;dotnet add&lt;/code&gt; and never modeled against the obligations the maintainer has documented in plain English on its own website. That posture is the one this framework exists to make harder to fall into by default.&lt;/p&gt;

&lt;p&gt;The deliberate read takes an afternoon. The implications of skipping it can compound for years.&lt;/p&gt;

&lt;h2&gt;
  
  
  If AGPL doesn't fit: a commercial alternative
&lt;/h2&gt;

&lt;p&gt;iText is free under AGPL v3, and &lt;strong&gt;that license is the catch&lt;/strong&gt;. Ship it inside a closed-source product or a hosted service and the network-use clause obliges you to either release your source or buy iText's commercial license. A solo developer or small SaaS that cannot open-source its codebase, and an enterprise that needs contractual indemnity rather than a copyleft obligation, both run into that wall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;IronPDF, a commercial library, covers the same advanced surface (forms, signatures, PDF/A) under a one-off license with no copyleft, so a closed-source release raises no AGPL question.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It can &lt;a href="https://ironpdf.com/how-to/signing/" rel="noopener noreferrer"&gt;apply digital signatures&lt;/a&gt; and the rest of that surface from licensed code that never triggers source disclosure. A commercial-library workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Install: dotnet add package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// A commercial key: no copyleft, no AGPL source-disclosure obligation&lt;/span&gt;
&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-TRIAL-OR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Closed-source and compliant&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"document.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Pro: a permissive commercial license with no copyleft, where iText's free tier is AGPL.&lt;/li&gt;
&lt;li&gt;Pro: a free 30-day trial, no credit card, and no watermark while you evaluate.&lt;/li&gt;
&lt;li&gt;Con: a paid license from first use, where iText's AGPL distribution is free for open-source projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If AGPL exposure is the blocker, the trial key arrives by email with no card so you can validate a closed-source build first. For AGPL-compatible or open-source projects, iText remains the deeper, standards-complete choice.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you been caught by iText's AGPL terms in a closed-source product, or did you adopt it deliberately? How did the license question play out for your team?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;License terms, version numbers, and quoted text in this article were verified against publicly available sources in May 2026; AGPL §13 is quoted from the &lt;a href="https://www.gnu.org/licenses/agpl-3.0.en.html" rel="noopener noreferrer"&gt;Free Software Foundation's canonical license text&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ironpdf.com/start-free/trial/" rel="noopener noreferrer"&gt;Try IronPDF free for 30 days, no credit card, no watermark: &lt;code&gt;dotnet add package IronPdf&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Migrating from ComPDFKit to IronPDF: From Install to Ship</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Fri, 05 Jun 2026 17:22:39 +0000</pubDate>
      <link>https://dev.to/ironsoftware/migrating-from-compdfkit-to-ironpdf-from-install-to-ship-5e42</link>
      <guid>https://dev.to/ironsoftware/migrating-from-compdfkit-to-ironpdf-from-install-to-ship-5e42</guid>
      <description>&lt;p&gt;Performance numbers are the first thing people reach for when justifying a library migration to management. They're also the easiest to misrepresent. A benchmark that doesn't match your workload is worse than no benchmark at all.&lt;/p&gt;

&lt;p&gt;This article takes a benchmark-aware approach to migrating from &lt;strong&gt;ComPDFKit&lt;/strong&gt; to &lt;strong&gt;IronPDF&lt;/strong&gt;. That means: showing you how to measure what actually matters in your use case, providing before/after code for the operations most teams care about, and flagging where the libraries differ in architecture in ways that will affect throughput under real load. No synthetic numbers that don't apply to your environment.&lt;/p&gt;

&lt;p&gt;You'll leave with working migration code, an API mapping table, and a repeatable benchmark harness you can run against your own workloads, because the only relevant performance number is the one measured with your data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;Teams using ComPDFKit on .NET typically adopted it for PDF viewing, annotation, or interactive document scenarios. Server-side batch generation and HTML-to-PDF are where friction tends to appear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML-to-PDF workloads.&lt;/strong&gt; ComPDFKit's .NET SDK does not include a native HTML/CSS rendering engine. The vendor's documented path for HTML conversion is a separate cloud Conversion API. If browser-quality HTML rendering is a core requirement, an in-process Chromium renderer is a structurally different fit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-side batch generation.&lt;/strong&gt; Libraries optimized for interactive viewers have different performance characteristics at scale than batch generators. Measure your workload specifically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform server deployment.&lt;/strong&gt; ComPDFKit ships SDKs for Windows, Linux, and macOS, but cross-platform server scenarios still benefit from confirming the deployment story matches your target environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NuGet package management.&lt;/strong&gt; Native binary distribution outside of NuGet adds CI/CD pipeline complexity. IronPDF's runtime binaries are pulled through NuGet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API surface for common operations.&lt;/strong&gt; Merge, watermark, and encrypt require more setup steps in a viewer-focused SDK than in a generation-focused one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;.NET version compatibility.&lt;/strong&gt; IronPDF supports .NET Framework 4.6.2+, .NET Core 3.1+, and .NET 5/6/7/8/9. Confirm your ComPDFKit package matches your target framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory footprint under load.&lt;/strong&gt; Viewer-optimized libraries sometimes carry rendering state that adds overhead in stateless server contexts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License model alignment.&lt;/strong&gt; Confirm ComPDFKit licensing terms cover server/SaaS use against the vendor's current pricing page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Async/parallel generation.&lt;/strong&gt; IronPDF exposes &lt;code&gt;RenderHtmlAsPdfAsync&lt;/code&gt; and supports parallel rendering through renderer reuse; confirm the equivalent guidance for ComPDFKit's &lt;code&gt;CPDFDocument&lt;/code&gt; lifecycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure/cloud deployment.&lt;/strong&gt; IronPDF documents Azure App Service, AWS Lambda, and Docker deployment paths.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;ComPDFKit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Focus&lt;/td&gt;
&lt;td&gt;PDF viewer, annotation, forms, editing&lt;/td&gt;
&lt;td&gt;HTML-to-PDF, edit, merge, security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;Per-app or per-platform&lt;/td&gt;
&lt;td&gt;Per-developer or royalty-free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Style&lt;/td&gt;
&lt;td&gt;SDK-style, C++ influenced, verbose&lt;/td&gt;
&lt;td&gt;High-level renderer + document model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;Steep for server-side; designed for UI integration&lt;/td&gt;
&lt;td&gt;Gradual for HTML; renderer-first mental model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML Rendering&lt;/td&gt;
&lt;td&gt;No native HTML/CSS engine in the .NET SDK&lt;/td&gt;
&lt;td&gt;Chromium-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page Indexing&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory Cleanup&lt;/td&gt;
&lt;td&gt;Manual &lt;code&gt;Release()&lt;/code&gt; calls&lt;/td&gt;
&lt;td&gt;Automatic (GC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ComPDFKit.PDFDocument&lt;/code&gt;, &lt;code&gt;ComPDFKit.PDFPage&lt;/code&gt;, etc.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML string to PDF&lt;/td&gt;
&lt;td&gt;Low to Medium&lt;/td&gt;
&lt;td&gt;New capability vs ComPDFKit's manual layout path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML file to PDF&lt;/td&gt;
&lt;td&gt;Low to Medium&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;API model differs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split PDFs&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CopyPages&lt;/code&gt; ranges in IronPDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermark&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CPDFWatermark&lt;/code&gt; vs IronPDF &lt;code&gt;ApplyWatermark&lt;/code&gt; HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password protection&lt;/td&gt;
&lt;td&gt;Low to Medium&lt;/td&gt;
&lt;td&gt;Both support; property names differ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Annotation migration&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;ComPDFKit annotation model is rich; test parity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form field editing&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;IronPDF exposes &lt;code&gt;pdf.Form.SetFieldValue&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server-side batch&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Architecture change; test throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Async / parallel&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;IronPDF supports &lt;code&gt;Async&lt;/code&gt; variants and &lt;code&gt;Parallel.ForEach&lt;/code&gt; patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Business Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Interactive PDF viewer/editor application&lt;/td&gt;
&lt;td&gt;Evaluate carefully. ComPDFKit is designed for this; IronPDF is not a UI viewer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server-side HTML-to-PDF batch generation&lt;/td&gt;
&lt;td&gt;IronPDF's Chromium renderer is a better fit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API-driven PDF operations (merge, stamp, encrypt)&lt;/td&gt;
&lt;td&gt;Both work; IronPDF API is more concise for these ops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mixed viewer + server generation&lt;/td&gt;
&lt;td&gt;May need both libraries. Evaluate consolidation cost&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start: Set Up a Measurement Baseline
&lt;/h2&gt;

&lt;p&gt;Before removing ComPDFKit, capture timing data for your most frequent operations. This gives you apples-to-apples comparison after migration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Diagnostics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Benchmark harness -- run against your actual workload before migration&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PdfBenchmark&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Run your most common ComPDFKit operation here&lt;/span&gt;
            &lt;span class="c1"&gt;// Example: ConvertHtmlToPdf("sample.html", $"out_{i}.pdf")&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;avgMs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"ComPDFKit average: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;avgMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;F1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ms per operation (&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; iterations)"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Total: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ms"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this benchmark. Record the numbers. Then run the equivalent IronPDF benchmark after migration. The delta in your environment is the only number that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Find ComPDFKit references in your codebase:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all ComPDFKit imports&lt;/span&gt;
rg &lt;span class="s2"&gt;"using ComPDFKit"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs &lt;span class="nt"&gt;-l&lt;/span&gt;

&lt;span class="c"&gt;# Find SDK initialization patterns&lt;/span&gt;
rg &lt;span class="s2"&gt;"CPDFSDKVerifier|LicenseVerify"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs

&lt;span class="c"&gt;# Find document operations&lt;/span&gt;
rg &lt;span class="s2"&gt;"CPDFDocument|CPDFPage|CPDFAnnotation"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install IronPDF:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add IronPDF (keep ComPDFKit while running parallel benchmarks)&lt;/span&gt;
dotnet add package IronPdf
dotnet restore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ComPDFKit license verification -- must run before document operations&lt;/span&gt;
        &lt;span class="n"&gt;CPDFSDKVerifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LicenseVerify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://ironpdf.com/how-to/license-keys/&lt;/span&gt;
&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFAnnotation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.Import&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Basic HTML-to-PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ComPDFKit's .NET SDK has no native HTML/CSS renderer. To approximate&lt;/span&gt;
&lt;span class="c1"&gt;// HTML output you would either lay out text and images manually via the&lt;/span&gt;
&lt;span class="c1"&gt;// page editor, or call ComPDFKit's separate cloud Conversion API&lt;/span&gt;
&lt;span class="c1"&gt;// (https://api.compdf.com/api-libraries) as a different SKU.&lt;/span&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CPDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;595&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;842&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Manual page editor operations would go here to place text/images.&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteToFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Done"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ComPDFKit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ComPDFKit.PDFDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core document operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ComPDFKit.PDFPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Page-level operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ComPDFKit.PDFAnnotation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Annotations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ComPDFKit.PDFWatermark&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Watermarks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ComPDFKit.Import&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Import/conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ComPDFKit&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPDFDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PDF document object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPDFPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Page reference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPDFSDKVerifier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.License&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SDK/license initialization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPDFWatermark&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ApplyWatermark(html)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Watermark application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual layout / cloud Conversion API&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML-to-PDF rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ComPDFKit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load from file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CPDFDocument.InitWithFilePath(path)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile(path)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from stream&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CPDFDocument.InitWithStream(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromStream(stream)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from bytes&lt;/td&gt;
&lt;td&gt;Via stream&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromBinaryData(bytes)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create from HTML&lt;/td&gt;
&lt;td&gt;Not natively supported&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save to file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.WriteToFilePath(path)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.SaveAs(path)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save to bytes&lt;/td&gt;
&lt;td&gt;Via stream&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.BinaryData&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ComPDFKit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.PageAtIndex(n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[n]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.RemovePage(n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RemovePages(n)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.InsertPage(i, w, h, "")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Via merge / &lt;code&gt;CopyPages&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rotate page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;page.SetRotation(angle)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.Pages[i].Rotation = ...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract pages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.ExtractPages(range)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge/Split
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ComPDFKit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc1.ImportPagesAtIndex(doc2, range, index)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract pages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.ExtractPages(range)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ComPDFKit's .NET SDK does not provide HTML/CSS rendering. Two practical&lt;/span&gt;
&lt;span class="c1"&gt;// options: lay out text and images manually with the page editor, or use&lt;/span&gt;
&lt;span class="c1"&gt;// the separate cloud Conversion API at https://api.compdf.com/api-libraries.&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// License verification -- must precede document operations&lt;/span&gt;
        &lt;span class="n"&gt;CPDFSDKVerifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LicenseVerify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CPDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;595&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;842&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// blank A4 page&lt;/span&gt;

        &lt;span class="c1"&gt;// Manual editor-based text placement would happen here.&lt;/span&gt;
        &lt;span class="c1"&gt;// For HTML input, ComPDFKit recommends their cloud Conversion API.&lt;/span&gt;

        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteToFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Chromium-based rendering -- handles modern CSS&lt;/span&gt;
        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/html-string-to-pdf/&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"&amp;lt;html&amp;gt;
            &amp;lt;body style='font-family:Arial; padding:40px'&amp;gt;
                &amp;lt;h1 style='color:#1D4ED8'&amp;gt;Invoice #3810&amp;lt;/h1&amp;gt;
                &amp;lt;table border='1' style='width:100%'&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Item&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Amount&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Service A&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$800&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Service B&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$400&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.Import&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CPDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InitWithFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CPDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InitWithFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Append all pages from document2 to the end of document1&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$"0-&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;document1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ImportPagesAtIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;document1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteToFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;document2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/merge-or-split-pdfs/&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part3.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf3&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Merged &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; pages to merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFWatermark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CPDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InitWithFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// CPDFDocument.InitWatermark returns a CPDFWatermark, which is then&lt;/span&gt;
        &lt;span class="c1"&gt;// configured and committed with CreateWatermark().&lt;/span&gt;
        &lt;span class="n"&gt;CPDFWatermark&lt;/span&gt; &lt;span class="n"&gt;watermark&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InitWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;C_Watermark_Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WATERMARK_TYPE_TEXT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Helvetica"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFontSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetTextRGBColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetOpacity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;76&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 0..255 (76 ~ 30%)&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetVertalign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C_Watermark_Vertalign&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WATERMARK_VERTALIGN_CENTER&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetHorizalign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C_Watermark_Horizalign&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WATERMARK_HORIZALIGN_CENTER&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetPages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"0-&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFront&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;watermark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateWatermark&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteToFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/watermark/&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1 style='color:rgba(255,0,0,0.3);'&amp;gt;CONFIDENTIAL&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;verticalAlignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Middle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;horizontalAlignment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked PDF saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ComPDFKit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ComPDFKit.PDFDocument&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CPDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InitWithFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// CPDFPermissionsInfo configures the permission bitmask; Encrypt()&lt;/span&gt;
        &lt;span class="c1"&gt;// applies both passwords and permissions in a single call.&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CPDFPermissionsInfo&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;AllowsCopying&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;AllowsPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;AllowsDocumentChanges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"owner456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;permission&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteToFilePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/pdf-permissions-passwords/&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullPrintRights&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Password protected PDF saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Benchmark Harness: Measure Before You Decide
&lt;/h2&gt;

&lt;p&gt;Run this after migration and compare against your ComPDFKit baseline numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Diagnostics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IronPdfBenchmark&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Reuse renderer -- important for fair throughput measurement&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Sequential benchmark&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Sequential HTML-to-PDF (&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; iterations)..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="c1"&gt;// Don't save to disk -- measures render time only&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;seqAvg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Sequential avg: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;seqAvg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;F1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ms/render"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Parallel benchmark&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"\nParallel HTML-to-PDF (&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; iterations, 4-way)..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// https://ironpdf.com/examples/parallel/&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;GetHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="p"&gt;}));&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;parAvg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Parallel avg: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parAvg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;F1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ms/render effective"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$@"&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;body style='font-family:Arial'&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;            &amp;lt;h1&amp;gt;Document #&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;            &amp;lt;p&amp;gt;Generated at &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare &lt;code&gt;seqAvg&lt;/code&gt; and &lt;code&gt;parAvg&lt;/code&gt; against your ComPDFKit baseline measurements.&lt;/p&gt;




&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SDK Initialization vs License Key
&lt;/h3&gt;

&lt;p&gt;ComPDFKit uses an SDK initialization step (&lt;code&gt;CPDFSDKVerifier.LicenseVerify(...)&lt;/code&gt;) that must run before any document operation. IronPDF's license is a static string set once. The initialization model is simpler but the pattern in web applications differs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Startup.cs / Program.cs -- set once, early&lt;/span&gt;
&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IRONPDF_KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't set the license key inside hot paths or per-request code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Memory Cleanup
&lt;/h3&gt;

&lt;p&gt;ComPDFKit requires &lt;code&gt;document.Release()&lt;/code&gt; for every &lt;code&gt;CPDFDocument&lt;/code&gt; instance (and &lt;code&gt;Release()&lt;/code&gt; on &lt;code&gt;CPDFPage&lt;/code&gt; / &lt;code&gt;CPDFTextPage&lt;/code&gt; handles you walk). Missing one leaks the underlying native object. IronPDF objects are managed; &lt;code&gt;using&lt;/code&gt; is optional but works with &lt;code&gt;PdfDocument&lt;/code&gt;. Remove every &lt;code&gt;Release()&lt;/code&gt; call when migrating.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page Indexing
&lt;/h3&gt;

&lt;p&gt;Both libraries use 0-based page indexing, so loops that walk pages from 0 to &lt;code&gt;PageCount - 1&lt;/code&gt; carry over unchanged. The difference is access shape: &lt;code&gt;document.PageAtIndex(n)&lt;/code&gt; in ComPDFKit becomes &lt;code&gt;pdf.Pages[n]&lt;/code&gt; in IronPDF.&lt;/p&gt;

&lt;h3&gt;
  
  
  Annotation Round-Trips
&lt;/h3&gt;

&lt;p&gt;If your application creates annotations and expects them to survive PDF round-trips (save, reload, verify), test annotation persistence with IronPDF before committing to the migration. Annotation formats are standardized in PDF, but library implementations differ in which annotation types and properties they preserve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Chromium Renderer Process
&lt;/h3&gt;

&lt;p&gt;IronPDF spawns a Chromium renderer process. This process startup is the largest latency contributor for the first render. Reusing &lt;code&gt;ChromePdfRenderer&lt;/code&gt; across requests amortizes this cost. In a web application, register it as a singleton.&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory Under Load
&lt;/h3&gt;

&lt;p&gt;Run a memory profile under your target concurrent load. The Chromium renderer's memory behavior under concurrent requests is different from an in-process renderer. Test at your expected peak concurrency, not just sequentially.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disk vs Memory Output
&lt;/h3&gt;

&lt;p&gt;If your downstream process consumes the PDF as bytes (upload to S3, email attachment), avoid writing to disk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// No disk write&lt;/span&gt;

&lt;span class="c1"&gt;// Or stream directly&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;a href="https://ironpdf.com/how-to/pdf-memory-stream/" rel="noopener noreferrer"&gt;memory stream docs&lt;/a&gt; for patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Async Parallel Workloads
&lt;/h3&gt;

&lt;p&gt;See &lt;a href="https://ironpdf.com/how-to/async/" rel="noopener noreferrer"&gt;async rendering docs&lt;/a&gt; and &lt;a href="https://ironpdf.com/examples/parallel/" rel="noopener noreferrer"&gt;parallel examples&lt;/a&gt; for patterns that scale under load. The benchmark harness above gives you a starting measurement point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Run benchmark harness against ComPDFKit. Record baseline numbers&lt;/li&gt;
&lt;li&gt;[ ] Run &lt;code&gt;rg "ComPDFKit|CPDFDocument" --type cs -l&lt;/code&gt; to find affected files&lt;/li&gt;
&lt;li&gt;[ ] Identify all &lt;code&gt;CPDFSDKVerifier.LicenseVerify(...)&lt;/code&gt; and &lt;code&gt;Release()&lt;/code&gt; calls&lt;/li&gt;
&lt;li&gt;[ ] Check annotation usage. Test IronPDF annotation parity&lt;/li&gt;
&lt;li&gt;[ ] Check form field editing. IronPDF exposes &lt;code&gt;pdf.Form.SetFieldValue&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Confirm .NET target version compatibility with IronPDF&lt;/li&gt;
&lt;li&gt;[ ] Test IronPDF in parallel with ComPDFKit before removing ComPDFKit&lt;/li&gt;
&lt;li&gt;[ ] Identify any 32-bit / platform-specific project configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Add &lt;code&gt;IronPdf&lt;/code&gt; NuGet package&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;CPDFSDKVerifier.LicenseVerify(...)&lt;/code&gt; with &lt;code&gt;IronPdf.License.LicenseKey = "..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Remove all &lt;code&gt;.Release()&lt;/code&gt; calls on &lt;code&gt;CPDFDocument&lt;/code&gt;, &lt;code&gt;CPDFPage&lt;/code&gt;, &lt;code&gt;CPDFTextPage&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;using ComPDFKit.*&lt;/code&gt; with &lt;code&gt;using IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;CPDFDocument.InitWithFilePath()&lt;/code&gt; with &lt;code&gt;PdfDocument.FromFile()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;WriteToFilePath()&lt;/code&gt; with &lt;code&gt;SaveAs()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace manual layout / cloud Conversion calls with &lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;ImportPagesAtIndex&lt;/code&gt; merges with &lt;code&gt;PdfDocument.Merge()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;InitWatermark&lt;/code&gt; + &lt;code&gt;CPDFWatermark&lt;/code&gt; with &lt;code&gt;pdf.ApplyWatermark(html)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;document.Encrypt(...)&lt;/code&gt; with &lt;code&gt;SecuritySettings&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;document.RemovePage(i)&lt;/code&gt; with &lt;code&gt;pdf.RemovePages(i)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Run IronPDF benchmark harness. Compare to ComPDFKit baseline&lt;/li&gt;
&lt;li&gt;[ ] Visual comparison: HTML-to-PDF output quality and CSS rendering&lt;/li&gt;
&lt;li&gt;[ ] Memory profile under target peak concurrency&lt;/li&gt;
&lt;li&gt;[ ] Annotation round-trip verification (create, save, reload)&lt;/li&gt;
&lt;li&gt;[ ] Password protection opens with correct credentials&lt;/li&gt;
&lt;li&gt;[ ] Merge page count and order verification&lt;/li&gt;
&lt;li&gt;[ ] Linux/cloud deployment test if applicable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove ComPDFKit NuGet packages (&lt;code&gt;ComPDFKit.NetCore&lt;/code&gt; / &lt;code&gt;ComPDFKit.NetFramework&lt;/code&gt;) and any native SDK files from build&lt;/li&gt;
&lt;li&gt;[ ] Update CI/CD build agent configuration&lt;/li&gt;
&lt;li&gt;[ ] Update IronPDF benchmark comparison doc for future reference&lt;/li&gt;
&lt;li&gt;[ ] Update internal documentation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  That's the Migration
&lt;/h2&gt;

&lt;p&gt;The migration from ComPDFKit to IronPDF is most straightforward when your use case is server-side generation, specifically HTML-to-PDF, merge, stamp, and encrypt. The rougher edges are annotation workflows and any code that depended on ComPDFKit's native rendering pipeline directly.&lt;/p&gt;

&lt;p&gt;The benchmark harness matters here more than in most migrations because the performance characteristics of a Chromium-backed renderer versus a native PDF SDK are architecturally different. Don't assume. Measure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question for the comments:&lt;/strong&gt; What's the largest throughput you've achieved with a .NET PDF renderer in production, and how did you get there? Renderer pooling, async batching, pre-warmed processes? Curious about real-world approaches.&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test before committing.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>BitMiracle Docotic.Pdf to IronPDF: The Honest Walkthrough</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Fri, 05 Jun 2026 17:22:05 +0000</pubDate>
      <link>https://dev.to/ironsoftware/bitmiracle-docoticpdf-to-ironpdf-the-honest-walkthrough-4279</link>
      <guid>https://dev.to/ironsoftware/bitmiracle-docoticpdf-to-ironpdf-the-honest-walkthrough-4279</guid>
      <description>&lt;p&gt;Docotic.Pdf is a genuinely well-engineered library. The API is clean, the NuGet package is lean, and it handles PDF parsing and programmatic construction reliably across platforms. The migration decision rarely comes from Docotic.Pdf breaking. It comes from how its HTML-to-PDF story is packaged.&lt;/p&gt;

&lt;p&gt;The most common trigger: someone adds a feature that requires rendering a complex HTML template to PDF. Docotic.Pdf supports HTML rendering, but only via the separate &lt;code&gt;BitMiracle.Docotic.Pdf.HtmlToPdf&lt;/code&gt; add-on, which exposes an async-only &lt;code&gt;HtmlConverter&lt;/code&gt; that downloads its own Chromium on first use. Teams that started on Docotic for parsing or programmatic construction often end up dragging the add-on into the dependency tree just to render one invoice template, and once that's in, the licensing and packaging story starts looking like a candidate for consolidation onto a single renderer-first library.&lt;/p&gt;

&lt;p&gt;This article covers the troubleshooting patterns and API mapping for migrating from BitMiracle Docotic.Pdf to &lt;strong&gt;IronPDF&lt;/strong&gt;. The migration is relatively low-drama because both are managed .NET libraries with no COM dependencies. The complexity concentrates in two places: the different mental model (Docotic's document construction plus a separate add-on for HTML vs IronPDF's unified renderer + document model), and any text extraction or annotation code that relies on Docotic's parse-side API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;Neutral triggers teams run into:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML-to-PDF requires an add-on.&lt;/strong&gt; Docotic.Pdf's HTML rendering lives in the separate &lt;code&gt;BitMiracle.Docotic.Pdf.HtmlToPdf&lt;/code&gt; package. That add-on uses an async-only &lt;code&gt;HtmlConverter&lt;/code&gt; and downloads its own Chromium on first use, so the dependency tree grows when you need HTML support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS rendering fidelity.&lt;/strong&gt; Programmatic document construction in Docotic doesn't match what a designer produces in HTML/CSS. IronPDF's Chromium renderer closes this gap for HTML-based workflows without a separate add-on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template maintenance burden.&lt;/strong&gt; Programmatic PDF construction (positioning text objects, drawing borders) requires developer changes for every layout update. HTML templates can be maintained by non-developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Font handling complexity.&lt;/strong&gt; Docotic requires explicit font loading and glyph management on the canvas side. IronPDF's Chromium renderer handles font resolution as a browser would.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment simplicity.&lt;/strong&gt; Both are managed .NET, but IronPDF's all-in-one approach (render + edit + security) reduces the number of libraries and add-on packages in the dependency tree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Async / parallel patterns.&lt;/strong&gt; Both libraries support concurrent use; evaluate under your specific load patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API surface for new developers.&lt;/strong&gt; &lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf(html)&lt;/code&gt; is a shorter onboarding path than document construction for HTML-heavy workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF/A output workflow.&lt;/strong&gt; Both support PDF/A; test against your target compliance profile to compare output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License changes.&lt;/strong&gt; Evaluate current Docotic.Pdf pricing at bitmiracle.com for your usage scenario, including any per-add-on costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consolidation.&lt;/strong&gt; Teams combining parsing (Docotic) and rendering (HtmlToPdf add-on or something else) sometimes consolidate to one library.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;BitMiracle Docotic.Pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Focus&lt;/td&gt;
&lt;td&gt;Parse, edit, construct, extract; HTML via add-on&lt;/td&gt;
&lt;td&gt;HTML-to-PDF, edit, merge, security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;Free with watermark; commercial license&lt;/td&gt;
&lt;td&gt;Per-developer or royalty-free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Style&lt;/td&gt;
&lt;td&gt;Document object model, explicit construction&lt;/td&gt;
&lt;td&gt;High-level renderer + document model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;Gradual for parsing; steep for programmatic layout&lt;/td&gt;
&lt;td&gt;Gradual for HTML; moderate for parse ops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML Rendering&lt;/td&gt;
&lt;td&gt;Via &lt;code&gt;BitMiracle.Docotic.Pdf.HtmlToPdf&lt;/code&gt; add-on (Chromium)&lt;/td&gt;
&lt;td&gt;Chromium-based, built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page Indexing&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread Safety&lt;/td&gt;
&lt;td&gt;Reuse &lt;code&gt;HtmlConverter&lt;/code&gt;; audit concurrent document access&lt;/td&gt;
&lt;td&gt;Renderer reusable; see IronPDF parallel examples&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;BitMiracle.Docotic.Pdf&lt;/code&gt; (HtmlConverter lives here too)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML string to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both support it; IronPDF is built-in, Docotic uses the HtmlToPdf add-on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML file to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both support; Docotic uses &lt;code&gt;Append(path)&lt;/code&gt;, IronPDF uses &lt;code&gt;PdfDocument.Merge&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split/extract pages&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Docotic copies pages page-by-page; IronPDF uses &lt;code&gt;CopyPages&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text watermark&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Docotic drawing model vs IronPDF stamper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image watermark&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Coordinate model differs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password protection&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both support owner/user passwords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text extraction&lt;/td&gt;
&lt;td&gt;Medium-High&lt;/td&gt;
&lt;td&gt;Docotic's text model is detailed (per-word bounds); audit IronPDF parity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Annotation handling&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Docotic annotations API is rich; audit IronPDF coverage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form field editing&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Both have form APIs; method signatures differ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF/A output&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Test against your validator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Business Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primarily programmatic PDF construction, no HTML&lt;/td&gt;
&lt;td&gt;Evaluate whether Docotic's model serves you; migration cost may exceed benefit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML templates requiring browser-quality CSS&lt;/td&gt;
&lt;td&gt;IronPDF's built-in Chromium renderer removes the add-on requirement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy text extraction and parse workflows&lt;/td&gt;
&lt;td&gt;Audit IronPDF's extraction API against your Docotic usage before committing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mixed HTML + parse requirements&lt;/td&gt;
&lt;td&gt;IronPDF can handle both; test extraction output quality&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET Framework 4.6.2+, .NET Core 3.1+, or .NET 5/6/7/8/9 (IronPDF supports the full modern range)&lt;/li&gt;
&lt;li&gt;IronPDF license key (&lt;a href="https://ironpdf.com/how-to/license-keys/" rel="noopener noreferrer"&gt;license setup&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Baseline PDF outputs captured for visual regression&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Find all Docotic.Pdf references:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all files with Docotic imports&lt;/span&gt;
rg &lt;span class="s2"&gt;"using BitMiracle"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs &lt;span class="nt"&gt;-l&lt;/span&gt;

&lt;span class="c"&gt;# Find all PdfDocument usages (Docotic's main class)&lt;/span&gt;
rg &lt;span class="s2"&gt;"PdfDocument"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs

&lt;span class="c"&gt;# Find text extraction calls&lt;/span&gt;
rg &lt;span class="s2"&gt;"GetText|GetWords|TextData"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs

&lt;span class="c"&gt;# Find annotation references&lt;/span&gt;
rg &lt;span class="s2"&gt;"Annotations|PdfAnnotation"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs

&lt;span class="c"&gt;# Find drawing / graphics operations&lt;/span&gt;
rg &lt;span class="s2"&gt;"PdfCanvas|DrawString|DrawLine|HtmlConverter"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remove Docotic, add IronPDF:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet remove package BitMiracle.Docotic.Pdf
dotnet remove package BitMiracle.Docotic.Pdf.HtmlToPdf
dotnet add package IronPdf
dotnet restore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PowerShell: &lt;code&gt;Uninstall-Package BitMiracle.Docotic.Pdf&lt;/code&gt; (plus the HtmlToPdf add-on if installed) then &lt;code&gt;Install-Package IronPdf&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Docotic.Pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Docotic uses a license string set before any API call&lt;/span&gt;
&lt;span class="n"&gt;PdfInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicenseKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://ironpdf.com/how-to/license-keys/&lt;/span&gt;
&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// HtmlConverter (from the HtmlToPdf add-on) also lives in BitMiracle.Docotic.Pdf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Basic PDF Operation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Docotic, opening a PDF and extracting text):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;PdfInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicenseKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// https://ironpdf.com/how-to/extract-text-and-images/&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExtractAllText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Docotic.Pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BitMiracle.Docotic.Pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core namespace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;BitMiracle.Docotic.Pdf&lt;/code&gt; (HtmlConverter from HtmlToPdf add-on)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;IronPdf&lt;/code&gt; (&lt;code&gt;ChromePdfRenderer&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;HTML rendering is built into IronPDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BitMiracle.Docotic.Pdf.Layout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Layout via HTML/CSS in IronPDF&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Docotic.Pdf Class&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same name; different API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Page object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HtmlConverter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML-to-PDF entry point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfCanvas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No direct equivalent&lt;/td&gt;
&lt;td&gt;IronPDF uses HTML/CSS or stamper model for drawing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfInfo.SetLicenseKey()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.License.LicenseKey&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;License setup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Docotic.Pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load from file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new PdfDocument("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from stream&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Load(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromStream(stream)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create from HTML&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;await converter.CreatePdfFromStringAsync(html)&lt;/code&gt; (add-on)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from bytes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Load(byteArray)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromBinaryData(byteArray)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Docotic.Pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get page&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;doc.Pages[n]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[n]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.RemovePage(n)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RemovePages(n)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page size&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;page.Width&lt;/code&gt;, &lt;code&gt;page.Height&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[n].Width&lt;/code&gt;, &lt;code&gt;pdf.Pages[n].Height&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge/Split
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Docotic.Pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf1.Append("file2.pdf")&lt;/code&gt; (path / Stream / byte[])&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract pages&lt;/td&gt;
&lt;td&gt;Copy pages page-by-page into a new &lt;code&gt;PdfDocument&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt; or &lt;code&gt;pdf.CopyPages(indices)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Docotic with the HtmlToPdf add-on):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PdfInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicenseKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// HtmlConverter is async-only and downloads Chromium on first use&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;HtmlConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HtmlConversionOptions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PdfPaperSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"&amp;lt;html&amp;gt;
            &amp;lt;body style='font-family:Arial; padding:40px'&amp;gt;
                &amp;lt;h1 style='color:#2563EB'&amp;gt;Invoice #2071&amp;lt;/h1&amp;gt;
                &amp;lt;p&amp;gt;Amount: &amp;lt;strong&amp;gt;$1,200.00&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
                &amp;lt;p&amp;gt;Due: 2025-12-01&amp;lt;/p&amp;gt;
            &amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreatePdfFromStringAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF, built-in renderer, no add-on):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/html-string-to-pdf/&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfPaperSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// HTML template — can be maintained separately from code&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"&amp;lt;html&amp;gt;
            &amp;lt;body style='font-family:Arial; padding:40px'&amp;gt;
                &amp;lt;h1 style='color:#2563EB'&amp;gt;Invoice #2071&amp;lt;/h1&amp;gt;
                &amp;lt;p&amp;gt;Amount: &amp;lt;strong&amp;gt;$1,200.00&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
                &amp;lt;p&amp;gt;Due: 2025-12-01&amp;lt;/p&amp;gt;
            &amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Docotic.Pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PdfInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicenseKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// PdfDocument.Append accepts a file path, Stream, or byte[] --&lt;/span&gt;
        &lt;span class="c1"&gt;// not another PdfDocument instance.&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part3.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged to merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/merge-or-split-pdfs/&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part3.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged to merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Docotic.Pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PdfInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicenseKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;canvas&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Canvas&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// Save/restore graphics state around the watermark&lt;/span&gt;
            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetTransparency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 30% opacity&lt;/span&gt;

            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FontSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FillColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfRgbColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Rotate around the page center, then draw the watermark text&lt;/span&gt;
            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DrawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RestoreState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked PDF saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/stamp-text-image/&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stamper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextStamper&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;FontSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Opacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Rotation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Middle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Center&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Applies to all pages by default&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyStamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stamper&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked PDF saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Docotic.Pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;BitMiracle.Docotic.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PdfInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicenseKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Docotic exposes encryption through a single Encrypt() call&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;permissions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printing&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;
                          &lt;span class="n"&gt;PdfPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentExtraction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ownerPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"owner456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;userPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;encryptionAlgorithm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PdfEncryptionAlgorithm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Aes256&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Password protected PDF saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/pdf-permissions-passwords/&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullPrintRights&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserCopyPasteContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Password protected PDF saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Text Extraction Differences
&lt;/h3&gt;

&lt;p&gt;Docotic.Pdf has a detailed text model. It exposes per-word bounds via &lt;code&gt;page.GetWords()&lt;/code&gt;, with &lt;code&gt;chunk.Bounds.Left&lt;/code&gt; and &lt;code&gt;chunk.Bounds.Top&lt;/code&gt; for positional data. IronPDF's text extraction returns the text content with less detail on positional data. If your code depends on character- or word-level positioning (e.g., table detection, column parsing), test IronPDF's output carefully before committing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Docotic -- detailed word data with bounds&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetWords&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at (&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bounds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bounds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Top&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// IronPDF -- text content&lt;/span&gt;
&lt;span class="c1"&gt;// https://ironpdf.com/how-to/extract-text-and-images/&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;allText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExtractAllText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;pageText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExtractTextFromPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"--- Page &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ---\n&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pageText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need positional data after migration, review the current IronPDF text extraction API at &lt;a href="https://ironpdf.com/how-to/extract-text-and-images/" rel="noopener noreferrer"&gt;https://ironpdf.com/how-to/extract-text-and-images/&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Annotation API Differences
&lt;/h3&gt;

&lt;p&gt;Docotic.Pdf's annotation model is explicit. You create &lt;code&gt;PdfAnnotation&lt;/code&gt; objects on &lt;code&gt;page.Annotations&lt;/code&gt; with coordinates and properties. IronPDF has annotation support, but the API shape differs. Teams with heavy annotation workflows should test annotation round-trips (create, save, reload, verify) before migrating.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://ironpdf.com/how-to/annotations/" rel="noopener noreferrer"&gt;IronPDF annotations docs&lt;/a&gt; for current API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page Indexing
&lt;/h3&gt;

&lt;p&gt;Both Docotic.Pdf and IronPDF use 0-based page indexing. This makes the page index migration simpler than moving from 1-based libraries, but still audit all page index references. Off-by-one errors are silent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Canvas vs Stamper
&lt;/h3&gt;

&lt;p&gt;Docotic's &lt;code&gt;PdfCanvas&lt;/code&gt; is a drawing context. You position everything with coordinates and explicit graphics state. IronPDF's stamper model is alignment-based with offsets. If you have precise coordinate requirements for stamps or overlays, check the stamper's &lt;code&gt;IsStampedOnAllPages&lt;/code&gt;, &lt;code&gt;HorizontalOffset&lt;/code&gt;, and &lt;code&gt;VerticalOffset&lt;/code&gt; properties. For highly precise positioning, IronPDF's HTML-stamp approach (stamping a rendered HTML element) often gives finer control than the basic stamper API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Native Dependencies
&lt;/h3&gt;

&lt;p&gt;Docotic.Pdf core is fully managed and has no native interop requirements. Docotic's HtmlToPdf add-on downloads its own Chromium and brings the same browser-process model that IronPDF uses. IronPDF's Chromium renderer requires the standard Linux system libraries (libnss3, libatk-bridge2.0-0, libdrm2, etc.) on Linux deployments. If your existing Docotic workload is parse-only with no HtmlToPdf add-on, the Linux dependency footprint will grow after the migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Renderer Reuse
&lt;/h3&gt;

&lt;p&gt;If you're adding HTML-to-PDF as a new capability during this migration, reuse &lt;code&gt;ChromePdfRenderer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Register in DI container as singleton in ASP.NET Core&lt;/span&gt;
&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Or reuse at class level&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Memory Patterns
&lt;/h3&gt;

&lt;p&gt;Docotic.Pdf documents are &lt;code&gt;IDisposable&lt;/code&gt;. IronPDF &lt;code&gt;PdfDocument&lt;/code&gt; is also &lt;code&gt;IDisposable&lt;/code&gt;. The migration shouldn't change disposal discipline if your existing code uses &lt;code&gt;using&lt;/code&gt; consistently. Audit for any &lt;code&gt;PdfDocument&lt;/code&gt; instances created without &lt;code&gt;using&lt;/code&gt; or explicit &lt;code&gt;.Dispose()&lt;/code&gt; calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallel Workloads
&lt;/h3&gt;

&lt;p&gt;If you generate PDFs in parallel, review IronPDF's concurrent rendering behavior at &lt;a href="https://ironpdf.com/examples/parallel/" rel="noopener noreferrer"&gt;parallel examples&lt;/a&gt;. The Chromium renderer process is separate from the managed layer — concurrent requests share the renderer process differently than Docotic's in-process drawing API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Run &lt;code&gt;rg "using BitMiracle" --type cs -l&lt;/code&gt; to find all affected files&lt;/li&gt;
&lt;li&gt;[ ] Capture baseline PDF outputs for visual regression comparison&lt;/li&gt;
&lt;li&gt;[ ] Identify all &lt;code&gt;PdfCanvas&lt;/code&gt; drawing operations (will need refactoring to HTML or stamper)&lt;/li&gt;
&lt;li&gt;[ ] Note whether the HtmlToPdf add-on (&lt;code&gt;HtmlConverter&lt;/code&gt;) is in use. That code maps to &lt;code&gt;ChromePdfRenderer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Inventory annotation-heavy code. Audit IronPDF annotation API parity&lt;/li&gt;
&lt;li&gt;[ ] Check form field editing usage. Audit IronPDF form API&lt;/li&gt;
&lt;li&gt;[ ] Note any character-level or per-word text extraction dependencies (&lt;code&gt;page.GetWords()&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Confirm target .NET version supports IronPDF (4.6.2+, Core 3.1+, .NET 5/6/7/8/9)&lt;/li&gt;
&lt;li&gt;[ ] Test IronPDF output in parallel with Docotic before removing Docotic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;BitMiracle.Docotic.Pdf&lt;/code&gt; (and &lt;code&gt;.HtmlToPdf&lt;/code&gt; add-on) NuGet with &lt;code&gt;IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PdfInfo.SetLicenseKey()&lt;/code&gt; with &lt;code&gt;IronPdf.License.LicenseKey = "..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;using BitMiracle.Docotic.Pdf&lt;/code&gt; with &lt;code&gt;using IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;new PdfDocument("file.pdf")&lt;/code&gt; with &lt;code&gt;PdfDocument.FromFile("file.pdf")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;HtmlConverter.CreateAsync()&lt;/code&gt; + &lt;code&gt;CreatePdfFromStringAsync&lt;/code&gt; with &lt;code&gt;new ChromePdfRenderer().RenderHtmlAsPdf(...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace programmatic layout with HTML templates where feasible&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PdfCanvas&lt;/code&gt; drawing with &lt;code&gt;TextStamper&lt;/code&gt;, &lt;code&gt;ImageStamper&lt;/code&gt;, or HTML&lt;/li&gt;
&lt;li&gt;[ ] Replace Docotic merge (&lt;code&gt;pdf1.Append("file.pdf")&lt;/code&gt;) with &lt;code&gt;PdfDocument.Merge(pdf1, pdf2, ...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;doc.Encrypt(...)&lt;/code&gt; with &lt;code&gt;pdf.SecuritySettings&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;doc.GetText()&lt;/code&gt; / &lt;code&gt;page.GetText()&lt;/code&gt; with &lt;code&gt;pdf.ExtractAllText()&lt;/code&gt; / &lt;code&gt;pdf.ExtractTextFromPage(i)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Update annotation handling to IronPDF API. Audit coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Visual comparison: programmatic layouts vs HTML-rendered equivalents&lt;/li&gt;
&lt;li&gt;[ ] Text extraction output. Compare per-word data if positional data is needed&lt;/li&gt;
&lt;li&gt;[ ] Annotation round-trip: create, save, reload, verify&lt;/li&gt;
&lt;li&gt;[ ] Password protection: open with user password, confirm owner restrictions&lt;/li&gt;
&lt;li&gt;[ ] Merge page count and order verification&lt;/li&gt;
&lt;li&gt;[ ] Test on Linux if target environment. Verify Chromium system library requirements&lt;/li&gt;
&lt;li&gt;[ ] Load test concurrent rendering if parallel workloads exist&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove &lt;code&gt;BitMiracle.Docotic.Pdf&lt;/code&gt; and &lt;code&gt;BitMiracle.Docotic.Pdf.HtmlToPdf&lt;/code&gt; from all project files&lt;/li&gt;
&lt;li&gt;[ ] Update Docker images for Linux deployment with IronPDF Chromium dependencies&lt;/li&gt;
&lt;li&gt;[ ] Update internal documentation on PDF generation approach&lt;/li&gt;
&lt;li&gt;[ ] Archive Docotic license for audit purposes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  One Last Thing
&lt;/h2&gt;

&lt;p&gt;The Docotic.Pdf to IronPDF migration is generally straightforward for the common operations: loading, merging, and password protection. The complexity concentrates in annotation workflows and text extraction. If either is central to your use case, run a spike against the IronPDF API before committing to the migration path.&lt;/p&gt;

&lt;p&gt;The real win for most teams isn't the API swap. It's collapsing the parse library plus the HtmlToPdf add-on plus the licensing for both into a single package that renders HTML like a browser. That removes the programmatic layout code no one wants to maintain, and it removes the add-on coordination that nobody enjoys auditing either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question for the comments:&lt;/strong&gt; For teams that moved from a parse-focused PDF library (Docotic, iText, etc.) to a renderer-first library. How did you handle the text extraction use cases that didn't port cleanly? Did you keep the parse library alongside the renderer, or find a different approach?&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test before committing.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>Moving from Aspose.PDF to IronPDF: What Changes</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Fri, 05 Jun 2026 17:21:14 +0000</pubDate>
      <link>https://dev.to/ironsoftware/moving-from-asposepdf-to-ironpdf-what-changes-11a1</link>
      <guid>https://dev.to/ironsoftware/moving-from-asposepdf-to-ironpdf-what-changes-11a1</guid>
      <description>&lt;p&gt;The migration story rarely starts with a decision meeting.&lt;/p&gt;

&lt;p&gt;It starts with a build pipeline failing at 2 AM, or a sprint retrospective where someone says "the PDF rendering is wrong again on Linux," or a licensing renewal email that lands in the wrong inbox at the wrong budget quarter. Teams don't abandon libraries they chose deliberately. They eventually reach a point where the cost of staying exceeds the cost of switching.&lt;/p&gt;

&lt;p&gt;This article walks through what a migration from &lt;strong&gt;Aspose.PDF&lt;/strong&gt; to &lt;strong&gt;IronPDF&lt;/strong&gt; actually looks like in C# code. You'll leave with working before/after snippets, a full API mapping table, and a printable migration checklist. You don't have to adopt IronPDF at the end. The migration patterns, grep commands, and checklist apply to any PDF library transition.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;Both Aspose.PDF and IronPDF are serious libraries with active maintenance. This isn't about one being broken. It's about the specific friction teams run into depending on their use case and deployment context.&lt;/p&gt;

&lt;p&gt;Neutral migration triggers teams commonly cite:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML rendering fidelity.&lt;/strong&gt; Aspose.PDF uses a proprietary HTML renderer, not a browser engine. Teams running complex CSS (Flexbox, Grid, custom fonts, &lt;code&gt;@page&lt;/code&gt; rules) often encounter layout drift that requires workarounds. IronPDF uses an embedded Chromium renderer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux/container deployment complexity.&lt;/strong&gt; Aspose.PDF on Linux requires additional configuration. IronPDF also requires native dependencies on Linux; neither is zero-effort, but the dependency surface differs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API verbosity.&lt;/strong&gt; Aspose.PDF's document construction API is explicit and detailed. That's a feature if you need fine-grained control, a friction point if you're mostly converting HTML to PDF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License model changes.&lt;/strong&gt; Both vendors have updated licensing in recent years. If your renewal timing is off, it creates a forcing function.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Namespace sprawl.&lt;/strong&gt; Aspose.PDF has many sub-namespaces. Teams with large codebases find &lt;code&gt;using&lt;/code&gt; statements accumulate quickly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;async/await surface.&lt;/strong&gt; Async PDF generation in Aspose requires some care around how operations are structured. IronPDF exposes first-class &lt;code&gt;RenderHtmlAsPdfAsync&lt;/code&gt; methods for non-blocking conversion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NuGet package size.&lt;/strong&gt; Aspose.PDF is a large package. In size-constrained environments (Lambda, small containers) this matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team familiarity.&lt;/strong&gt; A new hire familiar with Chromium-based rendering tools has a shorter ramp on IronPDF's mental model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF/A and compliance workflows.&lt;/strong&gt; Both support PDF/A; the specific versions and validation behavior differ. Test against your target compliance profile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support response patterns.&lt;/strong&gt; Teams with strict SLA requirements on library support evaluate vendor responsiveness differently.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Aspose.PDF&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Focus&lt;/td&gt;
&lt;td&gt;Parse, render, edit, forms, reporting&lt;/td&gt;
&lt;td&gt;HTML-to-PDF, edit, merge, security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;Per-developer or site license&lt;/td&gt;
&lt;td&gt;Per-developer or royalty-free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Style&lt;/td&gt;
&lt;td&gt;Explicit document object model&lt;/td&gt;
&lt;td&gt;High-level renderer + document model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;Steep for HTML; gradual for doc construction&lt;/td&gt;
&lt;td&gt;Gradual for HTML; steeper for low-level ops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML Rendering&lt;/td&gt;
&lt;td&gt;Proprietary renderer&lt;/td&gt;
&lt;td&gt;Chromium-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page Indexing&lt;/td&gt;
&lt;td&gt;1-based&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread Safety&lt;/td&gt;
&lt;td&gt;Per-document instance&lt;/td&gt;
&lt;td&gt;Renderer is reusable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Aspose.Pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML string to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Direct API swap; test CSS output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML file to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Path handling differs slightly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both have single-call merge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split PDFs&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Page selection API differs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermark (text)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Stamping model differs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermark (image)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Coordinate systems differ. Re-check positioning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password protection&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both support owner/user passwords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form field manipulation&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Aspose forms API is richer; common cases map cleanly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF/A compliance&lt;/td&gt;
&lt;td&gt;Medium-High&lt;/td&gt;
&lt;td&gt;Test output against your validator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Both expose signing APIs; signature placement differs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text extraction&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Both support; output formatting may differ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Business Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primarily HTML-to-PDF, modern CSS, containerized&lt;/td&gt;
&lt;td&gt;IronPDF likely reduces CSS workarounds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy programmatic doc construction (tables, graphs)&lt;/td&gt;
&lt;td&gt;Evaluate both; Aspose's doc model is mature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strict PDF/A-2b or PDF/A-3 compliance required&lt;/td&gt;
&lt;td&gt;Test both against your validator before committing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mixed team, some devs unfamiliar with PDF APIs&lt;/td&gt;
&lt;td&gt;IronPDF's surface is smaller to learn for common tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET Framework 4.6.2+, .NET Core 3.1+, or .NET 5/6/7/8/9 (IronPDF supports these)&lt;/li&gt;
&lt;li&gt;NuGet access or offline package feed&lt;/li&gt;
&lt;li&gt;An IronPDF license key (trial available; see &lt;a href="https://ironpdf.com/how-to/license-keys/" rel="noopener noreferrer"&gt;license setup docs&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;A test suite or manual test cases covering your current PDF outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Find all Aspose.PDF references in your codebase:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all using statements&lt;/span&gt;
rg &lt;span class="s2"&gt;"using Aspose"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs &lt;span class="nt"&gt;-l&lt;/span&gt;

&lt;span class="c"&gt;# Find all Aspose type references&lt;/span&gt;
rg &lt;span class="s2"&gt;"Aspose&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;Pdf"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs

&lt;span class="c"&gt;# Find all Document instantiations (Aspose pattern)&lt;/span&gt;
rg &lt;span class="s2"&gt;"new Document&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs

&lt;span class="c"&gt;# Find license-setting calls&lt;/span&gt;
rg &lt;span class="s2"&gt;"Aspose.*License"&lt;/span&gt; &lt;span class="nt"&gt;--type&lt;/span&gt; cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remove Aspose, install IronPDF:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove Aspose.PDF&lt;/span&gt;
dotnet remove package Aspose.PDF

&lt;span class="c"&gt;# Install IronPDF&lt;/span&gt;
dotnet add package IronPdf

&lt;span class="c"&gt;# Restore&lt;/span&gt;
dotnet restore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PowerShell (Package Manager Console): &lt;code&gt;Uninstall-Package Aspose.PDF&lt;/code&gt; then &lt;code&gt;Install-Package IronPdf&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Aspose):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Aspose license is set via a file or stream&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;License&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Aspose.PDF.lic"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// path to your license file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Set license key before any IronPDF calls&lt;/span&gt;
&lt;span class="c1"&gt;// See: https://ironpdf.com/how-to/license-keys/&lt;/span&gt;
&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf.Facades&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most common operations live in the root &lt;code&gt;IronPdf&lt;/code&gt; namespace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Basic HTML-to-PDF Conversion
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Aspose):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Aspose HTML load options control rendering behavior&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HtmlLoadOptions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Hello&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the &lt;a href="https://ironpdf.com/how-to/html-string-to-pdf/" rel="noopener noreferrer"&gt;HTML string to PDF docs&lt;/a&gt; for rendering options.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspose.PDF&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Aspose.Pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core namespace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Aspose.Pdf.Text&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Text ops on same PdfDocument&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Aspose.Pdf.Facades&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Facades pattern not used in IronPDF&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspose.PDF Class&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Document&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Represents a loaded/generated PDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HtmlLoadOptions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderOptions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Controls HTML rendering behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Page&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Single page reference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;License&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.License&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Static license configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Aspose.PDF&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load from file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new Document("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from stream&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new Document(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromStream(stream)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML string&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new Document(html, new HtmlLoadOptions())&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new Document(htmlPath, new HtmlLoadOptions())&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderHtmlFileAsPdf(path)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Aspose.PDF&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.Pages.Count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get page&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;doc.Pages[1]&lt;/code&gt; (1-based)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[0]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.Pages.Delete(1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RemovePages(0)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rotate page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;page.Rotate = Rotation.on90&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;See IronPDF rendering options docs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge/Split Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Aspose.PDF&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Document.Concatenate(file1, file2, output)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract pages&lt;/td&gt;
&lt;td&gt;Page copy via loop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Aspose.PDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Set license before any Aspose call&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;License&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Aspose.PDF.lic"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Aspose uses HtmlLoadOptions to control rendering&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HtmlLoadOptions&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// BasePath needed if HTML references external assets&lt;/span&gt;
            &lt;span class="n"&gt;BasePath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://example.com/"&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"&amp;lt;html&amp;gt;
            &amp;lt;body style='font-family:Arial'&amp;gt;
                &amp;lt;h1 style='color:#2563EB'&amp;gt;Invoice #1042&amp;lt;/h1&amp;gt;
                &amp;lt;p&amp;gt;Due: 2025-12-01&amp;lt;/p&amp;gt;
            &amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Aspose loads HTML as if it were a file via stream&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// License setup — https://ironpdf.com/how-to/license-keys/&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Chromium renders HTML — CSS, Flexbox, custom fonts work as in browser&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"&amp;lt;html&amp;gt;
            &amp;lt;body style='font-family:Arial'&amp;gt;
                &amp;lt;h1 style='color:#2563EB'&amp;gt;Invoice #1042&amp;lt;/h1&amp;gt;
                &amp;lt;p&amp;gt;Due: 2025-12-01&amp;lt;/p&amp;gt;
            &amp;lt;/body&amp;gt;
        &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Aspose.PDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf.Facades&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;License&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Aspose.PDF.lic"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// PdfFileEditor is used for merge operations in Aspose.Pdf.Facades&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfFileEditor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;inputFiles&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"part3.pdf"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputFile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Concatenate writes directly to disk&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Concatenate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputFiles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outputFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merge failed. Check Aspose logs."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged to merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Load each PDF — https://ironpdf.com/how-to/merge-or-split-pdfs/&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part3.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Static merge returns a new PdfDocument&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged to merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Aspose.PDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;License&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Aspose.PDF.lic"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Aspose stamps each page individually via TextStamp&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TextStamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Opacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;RotateAngle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;TextState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextState&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;FontSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ForegroundColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Red&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// Apply to every page (Aspose pages are 1-based)&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddStamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked output saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// TextStamper — https://ironpdf.com/how-to/stamp-text-image/&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stamper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TextStamper&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;FontSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Opacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Rotation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VerticalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Middle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HorizontalAlignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Center&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyStamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stamper&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked output saved"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Aspose.PDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Aspose.Pdf.Facades&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;license&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;License&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;license&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Aspose.PDF.lic"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// PdfFileSecurity handles encryption in Aspose.Pdf.Facades&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfFileSecurity&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BindPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// DocumentPrivilege controls permissions&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;privilege&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DocumentPrivilege&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowAll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;privilege&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PrintingPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintingQuality&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// EncryptFile: userPassword, ownerPassword, privileges, keySize&lt;/span&gt;
        &lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EncryptFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"owner456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;privilege&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;KeySize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Encrypted to protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Security&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// https://ironpdf.com/how-to/pdf-permissions-passwords/&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Set permissions&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullPrintRights&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Encrypted to protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Page Indexing
&lt;/h3&gt;

&lt;p&gt;Aspose.PDF pages are &lt;strong&gt;1-based&lt;/strong&gt;. &lt;code&gt;doc.Pages[1]&lt;/code&gt; is the first page. IronPDF pages are &lt;strong&gt;0-based&lt;/strong&gt;. &lt;code&gt;pdf.Pages[0]&lt;/code&gt; is the first page. This is the most common off-by-one bug in migrations. Audit every page-index reference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Aspose (1-based)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  &lt;span class="c1"&gt;// correct&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  &lt;span class="c1"&gt;// throws or returns null&lt;/span&gt;

&lt;span class="c1"&gt;// IronPDF (0-based)&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;  &lt;span class="c1"&gt;// correct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exception Model
&lt;/h3&gt;

&lt;p&gt;Aspose.PDF returns status codes or throws &lt;code&gt;PdfException&lt;/code&gt;. IronPDF throws typed exceptions. Wrap your PDF calls during migration and log the exception type before wiring up production error handling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IronPdfNativeException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Native renderer error&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Render error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"General error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unit Conversion
&lt;/h3&gt;

&lt;p&gt;Aspose.PDF uses &lt;strong&gt;points&lt;/strong&gt; (1 inch = 72 points) for coordinates and dimensions by default. IronPDF's &lt;code&gt;ChromePdfRenderOptions&lt;/code&gt; margins are expressed in &lt;strong&gt;millimeters&lt;/strong&gt;. Audit any numeric coordinate or margin you carry over from Aspose code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// IronPDF margin example — values are in millimeters&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderOptions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// 25 mm&lt;/span&gt;
    &lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Renderer Reuse
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ChromePdfRenderer&lt;/code&gt; instance in IronPDF wraps a Chromium process. Creating one per request is expensive. Reuse it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Shared at class/service level — not per-request&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="nf"&gt;RenderInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;a href="https://ironpdf.com/examples/parallel/" rel="noopener noreferrer"&gt;parallel rendering examples&lt;/a&gt; for concurrent workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disposal Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PdfDocument&lt;/code&gt; implements &lt;code&gt;IDisposable&lt;/code&gt;. Always dispose or use &lt;code&gt;using&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Correct&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// pdf is disposed at end of block&lt;/span&gt;

&lt;span class="c1"&gt;// Avoid — holds native resources&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// never disposed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Edge Cases to Flag
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large HTML pages with lazy-loaded images.&lt;/strong&gt; The Chromium renderer needs JavaScript to settle. Use &lt;code&gt;RenderingOptions.WaitFor.RenderDelay(ms)&lt;/code&gt; or related wait settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonts on Linux.&lt;/strong&gt; If output fonts look wrong in containers, the system font set may be incomplete. Install &lt;code&gt;fontconfig&lt;/code&gt; and common fonts in your Docker image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory usage under load.&lt;/strong&gt; Aspose's renderer and IronPDF's Chromium process have different memory profiles. Load-test before assuming parity.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Inventory all files using &lt;code&gt;Aspose.Pdf&lt;/code&gt; namespaces (&lt;code&gt;rg "using Aspose" --type cs -l&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Capture baseline PDF outputs (screenshots or hash) for visual regression&lt;/li&gt;
&lt;li&gt;[ ] Document all Aspose.PDF version currently in use&lt;/li&gt;
&lt;li&gt;[ ] Identify any Aspose.Pdf.Facades usage (more involved to migrate)&lt;/li&gt;
&lt;li&gt;[ ] Check for PDF/A compliance requirements and test validator&lt;/li&gt;
&lt;li&gt;[ ] Review license keys and environments (dev, staging, prod)&lt;/li&gt;
&lt;li&gt;[ ] Identify async/concurrent rendering patterns in current code&lt;/li&gt;
&lt;li&gt;[ ] Confirm Linux/container system dependencies for IronPDF&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;Aspose.PDF&lt;/code&gt; NuGet with &lt;code&gt;IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;License.SetLicense(file)&lt;/code&gt; with &lt;code&gt;IronPdf.License.LicenseKey = "..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;using Aspose.Pdf&lt;/code&gt; with &lt;code&gt;using IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;new Document(html, new HtmlLoadOptions())&lt;/code&gt; with &lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;doc.Pages[n]&lt;/code&gt; (1-based) with &lt;code&gt;pdf.Pages[n-1]&lt;/code&gt; (0-based)&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PdfFileEditor.Concatenate()&lt;/code&gt; with &lt;code&gt;PdfDocument.Merge()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;TextStamp&lt;/code&gt; stamping loop with &lt;code&gt;pdf.ApplyStamp(stamper)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PdfFileSecurity.EncryptFile()&lt;/code&gt; with &lt;code&gt;SecuritySettings&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;[ ] Replace all &lt;code&gt;doc.Save(path)&lt;/code&gt; with &lt;code&gt;pdf.SaveAs(path)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Review and update any &lt;code&gt;catch (PdfException)&lt;/code&gt; to IronPDF exception types&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Visual comparison of HTML-to-PDF output (fonts, layout, colors)&lt;/li&gt;
&lt;li&gt;[ ] Test with complex CSS: Flexbox, Grid, &lt;code&gt;@page&lt;/code&gt; rules&lt;/li&gt;
&lt;li&gt;[ ] Verify watermark position on multi-page documents&lt;/li&gt;
&lt;li&gt;[ ] Confirm merged PDFs have correct page count and order&lt;/li&gt;
&lt;li&gt;[ ] Verify password protection opens with correct credentials&lt;/li&gt;
&lt;li&gt;[ ] Test on target deployment OS (Windows and Linux if applicable)&lt;/li&gt;
&lt;li&gt;[ ] Confirm no page-indexing off-by-one regressions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove Aspose.PDF NuGet and license files from repo&lt;/li&gt;
&lt;li&gt;[ ] Update CI/CD to install IronPDF system deps (Linux)&lt;/li&gt;
&lt;li&gt;[ ] Update internal documentation and runbooks&lt;/li&gt;
&lt;li&gt;[ ] Archive Aspose license files (for audit trail, not active use)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Migration between two actively-maintained PDF libraries is not a weekend project, but it's also not a multi-month ordeal for most codebases. The hardest parts are usually (1) complex form fields, (2) PDF/A compliance validation, and (3) visual regression testing on CSS-heavy HTML.&lt;/p&gt;

&lt;p&gt;The checklist above won't catch every edge case in your specific codebase, but it'll surface 90% of the issues before they reach staging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question for the comments:&lt;/strong&gt; If you've migrated between any two PDF libraries in .NET, not just these two, and what was the migration step that took the longest and why? Was it the API mapping, the visual regression testing, or something else entirely?&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test before committing.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>Migrating from Api2pdf to IronPDF: Less Setup, Same Output</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Fri, 05 Jun 2026 17:20:27 +0000</pubDate>
      <link>https://dev.to/ironsoftware/migrating-from-api2pdf-to-ironpdf-less-setup-same-output-28n7</link>
      <guid>https://dev.to/ironsoftware/migrating-from-api2pdf-to-ironpdf-less-setup-same-output-28n7</guid>
      <description>&lt;p&gt;You refreshed the dashboard and the number was right there: 214,000 API calls this month. Your application generates a PDF for every order confirmation, every shipping label, and every monthly statement. Each one is an HTTP POST to &lt;code&gt;v2.api2pdf.com&lt;/code&gt;, a wait for the response, a download of the generated file from a temporary URL, and a prayer that the 24-hour auto-delete does not fire before your async job picks it up.&lt;/p&gt;

&lt;p&gt;Api2pdf solves a real problem: it is genuinely hard to run wkhtmltopdf or headless Chrome on a managed hosting platform. But at 214,000 calls per month, you are paying for network latency, external service availability, and temporary file management that you would not need if the PDF engine ran inside your own process.&lt;/p&gt;

&lt;p&gt;This guide covers the migration from Api2pdf's REST API to &lt;a href="https://ironpdf.com" rel="noopener noreferrer"&gt;IronPDF&lt;/a&gt;'s in-process .NET library. This is not an API-to-API migration. It is an execution model change from SaaS to library. Eighty percent of this content helps you evaluate any in-process alternative. The remaining twenty percent is IronPDF-specific.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;Api2pdf removes the pain of hosting Chrome or wkhtmltopdf yourself. Here is why teams outgrow it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Latency per render.&lt;/strong&gt; Every PDF is an HTTP round-trip: POST HTML, wait for render, download file URL. For high-volume applications, this adds 1 to 5 seconds per PDF that an in-process library eliminates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary file URLs.&lt;/strong&gt; Api2pdf returns a URL to the generated file, not the file itself. Your application must download the PDF before the 24-hour expiry. This introduces a race condition and a failure mode that does not exist with in-process generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External dependency for a core function.&lt;/strong&gt; If Api2pdf's service goes down, your PDF generation stops. If your internet connection degrades, your PDF generation slows. For applications where PDFs are on the critical path (invoices, contracts, compliance docs), this is a risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data leaves your network.&lt;/strong&gt; Your HTML, which may contain customer names, addresses, and financial data, is sent to Api2pdf's servers for rendering. For regulated industries (healthcare, finance, legal), this data transit may require additional compliance review.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-call cost at scale.&lt;/strong&gt; Api2pdf's usage-based pricing is economical for low volume. At hundreds of thousands of calls per month, a one-time library license may be cheaper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No offline capability.&lt;/strong&gt; If your application needs to generate PDFs in disconnected environments (on-premise deployments, air-gapped networks), a REST API is not an option.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited post-processing.&lt;/strong&gt; Api2pdf handles generation and merge well, but more advanced manipulation (watermarking, page-level security settings, form filling) requires additional API calls or is not supported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;wkhtmltopdf deprecation risk.&lt;/strong&gt; Api2pdf offers wkhtmltopdf as a rendering option. wkhtmltopdf is based on a deprecated version of WebKit and has not received updates. Chrome is the better option, but not all Api2pdf integrations use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File size and timeout limits.&lt;/strong&gt; Cloud APIs have practical limits on request payload size and processing time. Very large or complex HTML documents may timeout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging opacity.&lt;/strong&gt; When a render fails or produces unexpected output, you cannot inspect the rendering engine's state. With an in-process library, you can step through with a debugger.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Api2pdf (REST API)&lt;/th&gt;
&lt;th&gt;IronPDF (.NET library)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cloud PDF generation via REST&lt;/td&gt;
&lt;td&gt;In-process PDF generation + manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usage-based per API call&lt;/td&gt;
&lt;td&gt;Per-developer, perpetual license&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTTP REST + client SDK&lt;/td&gt;
&lt;td&gt;Native .NET API, no network calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low, simple HTTP calls&lt;/td&gt;
&lt;td&gt;Low, simple .NET API calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML Rendering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Headless Chrome or wkhtmltopdf (remote)&lt;/td&gt;
&lt;td&gt;Chrome engine (in-process)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Page Indexing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;N/A (service handles internally)&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Thread Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;N/A (stateless API)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChromePdfRenderer&lt;/code&gt; stateless, safe to share&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Api2Pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF (Chrome)&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Direct replacement; IronPDF runs Chrome in-process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;RenderUrlAsPdf&lt;/code&gt; replaces the Chrome URL endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF (wkhtmltopdf)&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Replace with IronPDF Chrome renderer, better output quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PdfDocument.Merge()&lt;/code&gt; replaces the PdfSharp merge endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Office to PDF (LibreOffice)&lt;/td&gt;
&lt;td&gt;High / N/A&lt;/td&gt;
&lt;td&gt;No direct IronPDF equivalent. Use LibreOffice headless locally or a separate service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password protection&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;IronPDF &lt;code&gt;SecuritySettings&lt;/code&gt; replaces the password endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bookmarks&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;IronPDF exposes bookmark APIs on &lt;code&gt;PdfDocument&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barcode generation&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Not a PDF feature. Use a dedicated barcode library (e.g., IronBarcode, ZXing.NET)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File deletion (security)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Not needed. Files never leave your server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thumbnail generation&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;pdf.RasterizeToImageFiles(...)&lt;/code&gt; or &lt;code&gt;pdf.ToBitmap()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML to DOCX/XLSX&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Not an IronPDF feature. Use a dedicated library&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;High-volume HTML-to-PDF with latency concerns&lt;/td&gt;
&lt;td&gt;Migrate. In-process rendering eliminates network overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regulated industry with data residency requirements&lt;/td&gt;
&lt;td&gt;Migrate. HTML never leaves your infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low-volume, diverse format conversion (Office, email, images)&lt;/td&gt;
&lt;td&gt;Stay or partial migrate. Keep Api2pdf for Office conversion, use IronPDF for HTML-to-PDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Air-gapped or on-premise deployment&lt;/td&gt;
&lt;td&gt;Migrate. Api2pdf requires internet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Checklist: Pre-Migration Readiness&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Count your monthly Api2pdf API calls (check your dashboard)&lt;/li&gt;
&lt;li&gt;[ ] Categorize calls by endpoint: Chrome HTML, Chrome URL, wkhtmltopdf, LibreOffice, merge, password&lt;/li&gt;
&lt;li&gt;[ ] Identify any LibreOffice (Office to PDF) calls. These need a separate solution&lt;/li&gt;
&lt;li&gt;[ ] Check if your HTML contains sensitive data sent to Api2pdf's servers&lt;/li&gt;
&lt;li&gt;[ ] Verify your deployment supports running IronPDF (needs .NET 6+ or Framework 4.6.2+)&lt;/li&gt;
&lt;li&gt;[ ] Obtain an IronPDF trial key from &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;ironpdf.com/get-started/license-keys/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Find Api2pdf References
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all Api2pdf client usage&lt;/span&gt;
rg &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"Api2Pdf|api2pdf|ChromeHtmlToPdfRequest|WkhtmlHtmlToPdfRequest"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Count API call sites&lt;/span&gt;
rg &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;Chrome&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;Wkhtml&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;PdfSharp&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;|&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;LibreOffice&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Find configuration (API keys)&lt;/span&gt;
rg &lt;span class="s2"&gt;"Api2Pdf|api2pdf"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.json"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.config"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In PowerShell: &lt;code&gt;Get-ChildItem -Recurse -Filter *.cs | Select-String "Api2Pdf|api2pdf"&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Swap Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove Api2pdf&lt;/span&gt;
dotnet remove package Api2Pdf

&lt;span class="c"&gt;# Install IronPDF&lt;/span&gt;
dotnet add package IronPdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Api2pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Api2pdf — API key passed to constructor&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// API key from portal.api2pdf.com&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a2pClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your-api2pdf-api-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Every call after this hits the internet&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Api2pdf client ready."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// License key — no internet required for rendering&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"IronPDF licensed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLicensed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Everything runs locally from here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// watermarks, headers, footers&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Rendering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// render options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Basic HTML-to-PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Api2pdf, ~15 lines):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a2pClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your-api-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChromeHtmlToPdfRequest&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Invoice #1042&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;Amount: $5,200.00&amp;lt;/p&amp;gt;"&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;a2pClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HtmlToPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Result is a URL — you must download the file&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PDF available at: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Download before the 24-hour expiry&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdfBytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByteArrayAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdfBytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Downloaded and saved."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF, 8 lines):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Invoice #1042&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;Amount: $5,200.00&amp;lt;/p&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved locally. No download needed."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Checklist: What You Just Eliminated&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] HTTP round-trip to external API&lt;/li&gt;
&lt;li&gt;[x] Temporary file URL with 24-hour expiry&lt;/li&gt;
&lt;li&gt;[x] &lt;code&gt;HttpClient.GetByteArrayAsync&lt;/code&gt; download step&lt;/li&gt;
&lt;li&gt;[x] Internet connectivity requirement for rendering&lt;/li&gt;
&lt;li&gt;[x] API key management and rotation&lt;/li&gt;
&lt;li&gt;[x] External service availability dependency&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Api2pdf Namespace&lt;/th&gt;
&lt;th&gt;IronPDF Namespace&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Api2Pdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core client/renderer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Api2Pdf.Models&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.Rendering&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Request options / render settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.Editing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Watermarks, headers, footers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Api2pdf Class&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Api2Pdf&lt;/code&gt; (client)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The entry point for PDF generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ChromeHtmlToPdfRequest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderOptions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Render configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Api2PdfResult&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The generated PDF (URL vs. in-memory object)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a2pClient.PdfSharp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PdfDocument&lt;/code&gt; static methods&lt;/td&gt;
&lt;td&gt;Merge and manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Api2pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;a2pClient.Chrome.HtmlToPdf(request)&lt;/code&gt; → URL&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt; → &lt;code&gt;PdfDocument&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL to PDF&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;a2pClient.Chrome.UrlToPdf(request)&lt;/code&gt; → URL&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;renderer.RenderUrlAsPdf(url)&lt;/code&gt; → &lt;code&gt;PdfDocument&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File to download&lt;/td&gt;
&lt;td&gt;&lt;code&gt;result.SaveFile("path")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.SaveAs("path")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;a2pClient.PdfSharp.MergePdfs(...)&lt;/code&gt; → URL&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt; → &lt;code&gt;PdfDocument&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Api2pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get page count&lt;/td&gt;
&lt;td&gt;N/A (not exposed via API)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access specific page&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[index]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add watermark&lt;/td&gt;
&lt;td&gt;Not directly supported&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.ApplyWatermark(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set password&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a2pClient.PdfSharp.SetPassword(new PdfPasswordRequest { ... })&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.SecuritySettings.UserPassword = "..."&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge / Split Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Api2pdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;a2pClient.PdfSharp.MergePdfs(new PdfMergeRequest { Urls = ... })&lt;/code&gt; → URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split / extract&lt;/td&gt;
&lt;td&gt;Not directly supported&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Api2pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfApi2pdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a2p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your-api-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChromeHtmlToPdfRequest&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: Arial; }
                .header { background: #0d47a1; color: white; padding: 20px; }
                table { width: 100%; border-collapse: collapse; margin: 20px 0; }
                td, th { padding: 8px; border: 1px solid #ddd; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;
                &amp;lt;div class='header'&amp;gt;&amp;lt;h1&amp;gt;Statement&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;table&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Date&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Amount&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;2025-01-15&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Service fee&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$250.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;2025-01-20&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Subscription&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$99.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;a2p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HtmlToPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Must download from temporary URL&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByteArrayAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"statement.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Downloaded statement.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintHtmlBackgrounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: Arial; }
                .header { background: #0d47a1; color: white; padding: 20px; }
                table { width: 100%; border-collapse: collapse; margin: 20px 0; }
                td, th { padding: 8px; border: 1px solid #ddd; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;
                &amp;lt;div class='header'&amp;gt;&amp;lt;h1&amp;gt;Statement&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;table&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Date&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Amount&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;2025-01-15&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Service fee&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$250.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;2025-01-20&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Subscription&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$99.00&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"statement.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved locally. No download step."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No HTTP client. No temporary URL. No download race condition. See &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML-to-PDF tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Api2pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeApi2pdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a2p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your-api-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Api2pdf merge requires URLs to existing PDFs&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdfUrls&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"https://your-server.com/files/part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"https://your-server.com/files/part2.pdf"&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;a2p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MergePdfsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PdfMergeRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Urls&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdfUrls&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merge error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Download the merged result&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByteArrayAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged and downloaded."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged locally."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Checklist: Merge Migration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] No need to host PDFs at public URLs for merge input&lt;/li&gt;
&lt;li&gt;[x] No download step after merge&lt;/li&gt;
&lt;li&gt;[x] Merge works with local files, byte arrays, or in-memory PdfDocuments&lt;/li&gt;
&lt;li&gt;[x] No 24-hour expiry on the merged result&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;See &lt;a href="https://ironpdf.com/examples/merge-pdfs/" rel="noopener noreferrer"&gt;IronPDF merge documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Api2pdf, not directly supported):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Api2pdf does not have a native watermark endpoint.&lt;/span&gt;
&lt;span class="c1"&gt;// Common workaround: generate the watermark as HTML overlay,&lt;/span&gt;
&lt;span class="c1"&gt;// or use a separate library after downloading the PDF.&lt;/span&gt;
&lt;span class="c1"&gt;// This is a gap in the Api2pdf feature set.&lt;/span&gt;

&lt;span class="c1"&gt;// You would need to:&lt;/span&gt;
&lt;span class="c1"&gt;// 1. Generate PDF via Api2pdf&lt;/span&gt;
&lt;span class="c1"&gt;// 2. Download the PDF&lt;/span&gt;
&lt;span class="c1"&gt;// 3. Use a local library (PdfSharp, iText, etc.) to add watermark&lt;/span&gt;
&lt;span class="c1"&gt;// 4. Save the result&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarking requires a second tool with Api2pdf."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1 style='color:rgba(0,0,0,0.15);font-size:60px;'&amp;gt;DRAFT&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked locally."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF handles watermarking natively. No second library needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (Api2pdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Net.Http&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordApi2pdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a2p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Api2Pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"your-api-key"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Api2pdf password endpoint requires a URL to an existing PDF&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;a2p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfSharp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetPasswordAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PdfPasswordRequest&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://your-server.com/files/input.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner123"&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Password error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetByteArrayAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Password-protected and downloaded."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoPrint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserCopyPasteContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected locally."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF gives you specific permission settings, not just a single password. Your PDF file never leaves your server. See &lt;a href="https://ironpdf.com/how-to/pdf-permissions-passwords/" rel="noopener noreferrer"&gt;IronPDF security documentation&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Execution Model Change: SaaS to Library
&lt;/h3&gt;

&lt;p&gt;This is not a typical API-to-API migration. You are changing the execution model:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;th&gt;Api2pdf (SaaS)&lt;/th&gt;
&lt;th&gt;IronPDF (Library)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Where rendering happens&lt;/td&gt;
&lt;td&gt;Api2pdf's AWS/GCP servers&lt;/td&gt;
&lt;td&gt;Your server / container&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data transit&lt;/td&gt;
&lt;td&gt;HTML sent over internet&lt;/td&gt;
&lt;td&gt;HTML stays in-process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Availability&lt;/td&gt;
&lt;td&gt;Depends on Api2pdf uptime&lt;/td&gt;
&lt;td&gt;Depends on your uptime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;Network round-trip + render time&lt;/td&gt;
&lt;td&gt;Render time only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File lifecycle&lt;/td&gt;
&lt;td&gt;24-hour temp URL&lt;/td&gt;
&lt;td&gt;Your filesystem / memory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Async Patterns
&lt;/h3&gt;

&lt;p&gt;Api2pdf calls are inherently async (HTTP). IronPDF rendering is synchronous by default but offers async variants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// IronPDF async rendering&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Handling Shift
&lt;/h3&gt;

&lt;p&gt;Api2pdf returns &lt;code&gt;result.Success&lt;/code&gt; / &lt;code&gt;result.Error&lt;/code&gt; on every call. IronPDF throws exceptions. Update your error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Api2pdf pattern&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// IronPDF pattern&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  File Management
&lt;/h3&gt;

&lt;p&gt;With Api2pdf, you downloaded PDFs from temporary URLs. With IronPDF, you have &lt;code&gt;PdfDocument&lt;/code&gt; objects in memory. You choose when and where to persist them. Remove any download-and-cleanup logic from your codebase.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Latency Reduction
&lt;/h3&gt;

&lt;p&gt;The most significant performance gain is eliminating the network round-trip. A rough benchmark:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Api2pdf: ~1,500–4,000ms per render (network + remote render + download)&lt;/li&gt;
&lt;li&gt;IronPDF in-process: ~200–1,000ms per render (render only, depends on HTML complexity)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are illustrative ranges, not benchmarks. Your actual numbers depend on network conditions, HTML complexity, and server resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Renderer Reuse
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disposal
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Edge Cases Worth Flagging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LibreOffice replacement:&lt;/strong&gt; If you use Api2pdf's LibreOffice endpoint for Office-to-PDF conversion, IronPDF does not replace this. Run LibreOffice headless locally (&lt;code&gt;libreoffice --headless --convert-to pdf input.docx&lt;/code&gt;) or use a dedicated service. Alternatively, the &lt;a href="https://ironsoftware.com" rel="noopener noreferrer"&gt;IronWord library from Iron Software&lt;/a&gt; handles DOCX-to-PDF within .NET.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;wkhtmltopdf rendering differences:&lt;/strong&gt; If your existing Api2pdf integration uses wkhtmltopdf (not Chrome), switching to IronPDF's Chrome engine may produce different output for the same HTML. Test your templates and adjust CSS if needed. Chrome's rendering is more modern and accurate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Barcode generation:&lt;/strong&gt; Api2pdf offers barcode/QR code generation. IronPDF does not. Use a dedicated library like ZXing.NET or IronBarcode, and embed the generated barcode image in your HTML before rendering.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration (8 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Export your Api2pdf usage data: call count, endpoints used, average render time&lt;/li&gt;
&lt;li&gt;[ ] Categorize calls: Chrome HTML, Chrome URL, wkhtmltopdf, LibreOffice, merge, password&lt;/li&gt;
&lt;li&gt;[ ] Identify LibreOffice calls that need a separate replacement&lt;/li&gt;
&lt;li&gt;[ ] Check for wkhtmltopdf-specific HTML that may render differently in Chrome&lt;/li&gt;
&lt;li&gt;[ ] Verify your deployment environment supports IronPDF (.NET 6+ or Framework 4.6.2+)&lt;/li&gt;
&lt;li&gt;[ ] Obtain an IronPDF trial key from &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;ironpdf.com/get-started/license-keys/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Create migration branch&lt;/li&gt;
&lt;li&gt;[ ] Audit your HTML templates for sensitive data currently sent to Api2pdf servers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration (10 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove &lt;code&gt;Api2Pdf&lt;/code&gt; NuGet package&lt;/li&gt;
&lt;li&gt;[ ] Add &lt;code&gt;IronPdf&lt;/code&gt; NuGet package&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;new Api2Pdf("key")&lt;/code&gt; with &lt;code&gt;IronPdf.License.LicenseKey = "..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;a2pClient.Chrome.HtmlToPdf()&lt;/code&gt; with &lt;code&gt;renderer.RenderHtmlAsPdf()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;a2pClient.Chrome.UrlToPdf()&lt;/code&gt; with &lt;code&gt;renderer.RenderUrlAsPdf()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;a2pClient.PdfSharp.MergePdfs()&lt;/code&gt; with &lt;code&gt;PdfDocument.Merge()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;a2pClient.PdfSharp.SetPassword()&lt;/code&gt; with &lt;code&gt;SecuritySettings&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;[ ] Remove all &lt;code&gt;HttpClient.GetByteArrayAsync(result.FileUrl)&lt;/code&gt; download code&lt;/li&gt;
&lt;li&gt;[ ] Remove any temporary-file cleanup logic tied to the 24-hour URL lifecycle&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;result.Success&lt;/code&gt; checks with try/catch exception handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing (7 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Compare PDF output visually for your top 10 templates (Chrome engine may differ slightly from Api2pdf's Chrome version)&lt;/li&gt;
&lt;li&gt;[ ] Test any wkhtmltopdf-specific HTML in IronPDF's Chrome engine. Adjust CSS as needed&lt;/li&gt;
&lt;li&gt;[ ] Verify password-protected PDFs open correctly in Adobe Reader&lt;/li&gt;
&lt;li&gt;[ ] Test merge with 3+ documents&lt;/li&gt;
&lt;li&gt;[ ] Benchmark render time: in-process vs. Api2pdf round-trip&lt;/li&gt;
&lt;li&gt;[ ] Test in your production deployment environment (Docker, Azure, etc.)&lt;/li&gt;
&lt;li&gt;[ ] Verify no sensitive data is being sent externally after migration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration (4 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Cancel or downgrade your Api2pdf subscription&lt;/li&gt;
&lt;li&gt;[ ] Remove Api2pdf API key from secrets/configuration management&lt;/li&gt;
&lt;li&gt;[ ] Remove download-and-cleanup background jobs&lt;/li&gt;
&lt;li&gt;[ ] Monitor production render times and error rates for two weeks&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Before You Ship
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Worth knowing even without IronPDF:&lt;/strong&gt; if you are evaluating in-process alternatives and want to stay open-source, Puppeteer Sharp is a .NET port of Puppeteer that drives headless Chrome locally. It requires managing a Chrome installation but produces the same quality output as Api2pdf's Chrome endpoint. Playwright for .NET is another option with broader browser support.&lt;/p&gt;

&lt;p&gt;Here is my question: if you are currently running Api2pdf at high volume, what is your download-and-cleanup strategy? Do you download synchronously in the request, run a background job, or use webhooks? I am curious how teams handle the temporary URL lifecycle in production. It is the part of the Api2pdf model that introduces the most operational complexity.&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test before committing.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>Apache PDFBox to IronPDF: What Actually Matters</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Thu, 04 Jun 2026 16:54:38 +0000</pubDate>
      <link>https://dev.to/ironsoftware/apache-pdfbox-to-ironpdf-what-actually-matters-4m91</link>
      <guid>https://dev.to/ironsoftware/apache-pdfbox-to-ironpdf-what-actually-matters-4m91</guid>
      <description>&lt;p&gt;Most .NET teams who reach for Apache PDFBox end up on one of three NuGet packages: &lt;code&gt;Pdfbox-IKVM&lt;/code&gt;, &lt;code&gt;PdfBox_DotNet_Version&lt;/code&gt;, or &lt;code&gt;MASES.NetPDF&lt;/code&gt;. None of them are official. Two of the three have been abandoned for years. The third still calls out to a real JVM at runtime via JCOBridge. If you have one of these in your &lt;code&gt;.csproj&lt;/code&gt; and are wondering whether to keep maintaining a Java-shaped API and a Java-runtime dependency inside a .NET application, this guide is for you.&lt;/p&gt;

&lt;p&gt;Apache PDFBox is a solid open-source Java library. The migration question is not about the upstream library's quality. It is about whether the .NET port you happen to be running still belongs in a modern .NET stack. This guide covers the shift to &lt;a href="https://ironpdf.com" rel="noopener noreferrer"&gt;IronPDF&lt;/a&gt;, but eighty percent of the framework (dependency auditing, API mapping, testing patterns) applies to any .NET-native PDF library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;PDFBox is one of the most widely deployed PDF libraries in the world. Here is why .NET teams specifically move away from its .NET ports:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unofficial port status.&lt;/strong&gt; Apache ships only Java artifacts. Every .NET PDFBox option on NuGet is a community-driven port. &lt;code&gt;Pdfbox&lt;/code&gt; (built against PDFBox 1.8.2) and &lt;code&gt;Pdfbox-IKVM&lt;/code&gt; were last published in 2013 and 2017 respectively. &lt;code&gt;PdfBox_DotNet_Version&lt;/code&gt; was last published in 2019. &lt;code&gt;MASES.NetPDF&lt;/code&gt; is the only actively maintained option, and it is a JCOBridge wrapper that requires a JVM at runtime alongside the CLR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No HTML-to-PDF.&lt;/strong&gt; PDFBox does not convert HTML in any form. If you need HTML rendering, you are pairing PDFBox with another tool, adding a second dependency on top of the port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime baggage.&lt;/strong&gt; The IKVM-based ports bundle a .NET reimplementation of the JVM. &lt;code&gt;MASES.NetPDF&lt;/code&gt; calls into a real JVM via JCOBridge. Either way, the deployment carries Java-runtime weight that idiomatic .NET libraries avoid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IKVM compatibility gaps.&lt;/strong&gt; The IKVM-based ports were built against older PDFBox lines (1.8.x or 2.0.x). They do not track upstream PDFBox 3.0.x, and IKVM's coverage of newer Java features is limited.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API verbosity for common operations.&lt;/strong&gt; Because the ports expose the Java API directly, the surface keeps Java conventions: &lt;code&gt;camelCase&lt;/code&gt; methods, &lt;code&gt;File&lt;/code&gt; objects, explicit &lt;code&gt;close()&lt;/code&gt; calls. Merging two PDFs requires constructing a &lt;code&gt;PDFMergerUtility&lt;/code&gt;, adding sources, and calling &lt;code&gt;mergeDocuments(MemoryUsageSetting...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual resource management.&lt;/strong&gt; Documents hold native resources and must be explicitly closed. In a port that wraps Java semantics, leaking a &lt;code&gt;PDDocument&lt;/code&gt; is easier than leaking an &lt;code&gt;IDisposable&lt;/code&gt; in idiomatic C#.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text extraction ordering.&lt;/strong&gt; PDFBox extracts text in the order it appears in the PDF content stream, which is not necessarily visual order. Reading order requires &lt;code&gt;PDFTextStripper.setSortByPosition(true)&lt;/code&gt;, a common source of bugs for teams unfamiliar with PDF internals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No async support.&lt;/strong&gt; The Java-shaped API is synchronous. In an async .NET pipeline, blocking on JVM-bridge calls ties up thread pool threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Font handling across platforms.&lt;/strong&gt; Font resolution flows through the wrapped Java font infrastructure. Font availability and rendering may differ between development machines and Linux containers in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sparse .NET community.&lt;/strong&gt; Help, examples, and best practices for .NET-specific issues with these ports are difficult to find. Most search results point at the Java PDFBox documentation, which uses a slightly different API surface than each port exposes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Apache PDFBox (.NET Ports)&lt;/th&gt;
&lt;th&gt;IronPDF (.NET)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PDF manipulation, text extraction, form filling&lt;/td&gt;
&lt;td&gt;HTML-first PDF generation + manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free, Apache License 2.0&lt;/td&gt;
&lt;td&gt;Per-developer, perpetual licenses available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Java objects mirroring PDF spec (PDDocument, PDPage)&lt;/td&gt;
&lt;td&gt;C# fluent API, HTML-to-PDF, property-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate, Java idioms plus PDF internals&lt;/td&gt;
&lt;td&gt;Low, HTML/CSS developers productive quickly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML Rendering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Built-in Chrome rendering engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Page Indexing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Thread Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PDDocument not thread-safe&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChromePdfRenderer&lt;/code&gt; stateless, safe to share&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;org.apache.pdfbox.*&lt;/code&gt; (IKVM) or &lt;code&gt;Org.Apache.Pdfbox.*&lt;/code&gt; (MASES)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;PDFBox cannot do this; IronPDF is purpose-built for it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text extraction&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Both extract text; API shape and sort behavior differ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both offer merge; IronPDF is a one-liner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split / extract pages&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Different API, same concept&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermark&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;PDFBox uses PDPageContentStream drawing; IronPDF uses HTML overlay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password / encryption&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;PDFBox uses AccessPermission + StandardProtectionPolicy; IronPDF uses SecuritySettings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form filling (AcroForms)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Both support AcroForms with different API surfaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;td&gt;Medium-High&lt;/td&gt;
&lt;td&gt;Different libraries and API patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF/A validation&lt;/td&gt;
&lt;td&gt;High / N/A&lt;/td&gt;
&lt;td&gt;PDFBox has the Preflight subproject; IronPDF supports PDF/A export but does not validate existing documents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image extraction&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Both support image extraction with different APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF rendering to image&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;PDFBox renders pages to BufferedImage; IronPDF rasterizes via &lt;code&gt;ToBitmap(dpi)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.NET app pinned to an abandoned IKVM-based PDFBox port&lt;/td&gt;
&lt;td&gt;Migrate. The port no longer tracks upstream and brings IKVM-era constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDFBox used only for text extraction&lt;/td&gt;
&lt;td&gt;Evaluate. IronPDF extracts text, but also consider &lt;a href="https://github.com/UglyToad/PdfPig" rel="noopener noreferrer"&gt;PdfPig&lt;/a&gt; as a lighter .NET-native alternative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDFBox used for PDF/A validation via Preflight&lt;/td&gt;
&lt;td&gt;Keep Preflight (or veraPDF) as a separate validator; IronPDF generates PDF/A but does not validate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full .NET stack, needs HTML-to-PDF + manipulation&lt;/td&gt;
&lt;td&gt;Migrate. IronPDF covers both in one NuGet package&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;.NET 6+ (or .NET Framework 4.6.2+)&lt;/li&gt;
&lt;li&gt;A trial or licensed &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;IronPDF key&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Inventory of which PDFBox port your project uses: &lt;code&gt;Pdfbox&lt;/code&gt;, &lt;code&gt;Pdfbox-IKVM&lt;/code&gt;, &lt;code&gt;PdfBox_DotNet_Version&lt;/code&gt;, or &lt;code&gt;MASES.NetPDF&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Find PDFBox References
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find PDFBox usage across the codebase&lt;/span&gt;
rg &lt;span class="s2"&gt;"org&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;apache&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;pdfbox|Org&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;Apache&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;Pdfbox|PDDocument|PDFTextStripper|PDFMergerUtility"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Identify which port the project references&lt;/span&gt;
rg &lt;span class="s2"&gt;"Pdfbox|Pdfbox-IKVM|PdfBox_DotNet_Version|MASES&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;NetPDF"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.csproj"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In PowerShell: &lt;code&gt;Get-ChildItem -Recurse -Filter *.cs | Select-String "PDDocument|pdfbox|PDFTextStripper"&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Swap Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove whichever PDFBox .NET port your project uses&lt;/span&gt;
dotnet remove package Pdfbox            &lt;span class="c"&gt;# PDFBox 1.8.2-era IKVM port&lt;/span&gt;
dotnet remove package Pdfbox-IKVM       &lt;span class="c"&gt;# IKVM wrapper, last published 2017&lt;/span&gt;
dotnet remove package PdfBox_DotNet_Version  &lt;span class="c"&gt;# last published 2019&lt;/span&gt;
dotnet remove package MASES.NetPDF      &lt;span class="c"&gt;# JCOBridge wrapper, requires JVM&lt;/span&gt;

&lt;span class="c"&gt;# Install IronPDF&lt;/span&gt;
dotnet add package IronPdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox .NET port, no license needed but a JVM-shaped runtime is):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Apache 2.0 — no license key required.&lt;/span&gt;
&lt;span class="c1"&gt;// IKVM-based ports bundle a .NET-side JVM reimplementation;&lt;/span&gt;
&lt;span class="c1"&gt;// MASES.NetPDF calls into a real JVM via JCOBridge.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PDDocument&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"PDFBox ready. Pages: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getNumberOfPages&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF, one line of configuration):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// License key — trial available at ironpdf.com&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"IronPDF licensed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLicensed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// No bundled JVM, no JCOBridge, no Java-shaped API&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox .NET port, IKVM-style):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel.font&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.multipdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;java.io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// watermarks, headers, footers&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Rendering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// render options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Basic PDF Creation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox .NET port, manual page construction):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel.font&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PDDocument&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;PDPage&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;PDPageContentStream&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDPageContentStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDType1Font&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HELVETICA_BOLD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newLineAtOffset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;72&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// x, y from bottom-left&lt;/span&gt;
            &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Monthly Report"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"report_pdfbox.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;finally&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with PDFBox."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF, HTML rendering):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPaperSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Letter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1 style='font-family:Helvetica;font-size:24pt;'&amp;gt;Monthly Report&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"report_ironpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No bundled JVM. No coordinate math. The &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML-to-PDF tutorial&lt;/a&gt; covers rendering options in detail.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;p&gt;These map the Java-shaped APIs exposed by the PDFBox .NET ports to native IronPDF APIs. Because the ports surface Java method names directly through IKVM or JCOBridge, the differences are both naming (camelCase to PascalCase) and conceptual (page construction to HTML rendering).&lt;/p&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PDFBox .NET Port&lt;/th&gt;
&lt;th&gt;IronPDF Namespace&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;org.apache.pdfbox.pdmodel&lt;/code&gt; / &lt;code&gt;Org.Apache.Pdfbox.Pdmodel&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core document operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;org.apache.pdfbox.text&lt;/code&gt; / &lt;code&gt;Org.Apache.Pdfbox.Text&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Text extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;org.apache.pdfbox.multipdf&lt;/code&gt; / &lt;code&gt;Org.Apache.Pdfbox.Multipdf&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge/split utilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;org.apache.pdfbox.pdmodel.font&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CSS &lt;code&gt;font-family&lt;/code&gt; in HTML&lt;/td&gt;
&lt;td&gt;Font handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;org.apache.pdfbox.pdmodel.encryption&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.Security&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Security/encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PDFBox Class&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PDDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The PDF document object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PDPage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.Pages[n]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Individual page access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PDPageContentStream&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML/CSS via &lt;code&gt;ChromePdfRenderer&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Content creation (IronPDF uses HTML instead of drawing commands)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PDFMergerUtility&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Document merging&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;PDFBox .NET Port&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Open from file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PDDocument.load(new File("f.pdf"))&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("f.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open with password&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PDDocument.load(file, "pass")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("f.pdf", "pass")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create new&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new PDDocument()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.save("out.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.SaveAs("out.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;PDFBox .NET Port&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get page count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.getNumberOfPages()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get page&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;document.getPage(index)&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[index]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.addPage(new PDPage())&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Render HTML (pages auto-created)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.removePage(index)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RemovePages(index)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge / Split Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;PDFBox .NET Port&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PDFMergerUtility&lt;/code&gt; → &lt;code&gt;addSource()&lt;/code&gt; → &lt;code&gt;mergeDocuments()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract pages&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PDDocument.getPage()&lt;/code&gt; + new doc + import page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox has no HTML-to-PDF; common workaround):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PDFBox cannot convert HTML to PDF.&lt;/span&gt;
&lt;span class="c1"&gt;// Common workaround: shell out to wkhtmltopdf, then optionally&lt;/span&gt;
&lt;span class="c1"&gt;// post-process the result with PDFBox.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Diagnostics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfPdfbox&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;psi&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ProcessStartInfo&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;FileName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"wkhtmltopdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"--page-size Letter --margin-top 20 --margin-bottom 20 input.html report.pdf"&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;psi&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WaitForExit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExitCode&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"wkhtmltopdf failed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExitCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Optional: post-process with PDFBox if needed&lt;/span&gt;
        &lt;span class="c1"&gt;// PDDocument doc = PDDocument.load(new File("report.pdf"));&lt;/span&gt;
        &lt;span class="c1"&gt;// ... manipulate ...&lt;/span&gt;
        &lt;span class="c1"&gt;// doc.save("report_final.pdf");&lt;/span&gt;
        &lt;span class="c1"&gt;// doc.close();&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated with wkhtmltopdf + PDFBox."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPaperSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Letter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintHtmlBackgrounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: Arial, sans-serif; }
                .title { color: #1a237e; border-bottom: 2px solid #1a237e; padding-bottom: 10px; }
                table { width: 100%; border-collapse: collapse; margin-top: 20px; }
                td, th { padding: 10px; border: 1px solid #e0e0e0; }
                th { background: #f5f5f5; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;
                &amp;lt;h1 class='title'&amp;gt;Q4 Sales Report&amp;lt;/h1&amp;gt;
                &amp;lt;table&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Region&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Revenue&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Growth&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;North&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$1.2M&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;+12%&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;South&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$890K&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;+8%&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;West&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$2.1M&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;+22%&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"report.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No external process. No second toolchain. See the &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML-to-PDF tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox .NET port):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.multipdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergePdfbox&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PDFMergerUtility&lt;/span&gt; &lt;span class="n"&gt;merger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDFMergerUtility&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setDestinationFileName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged_pdfbox.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// MemoryUsageSetting governs heap vs temp-file buffering&lt;/span&gt;
        &lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mergeDocuments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemoryUsageSetting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setupMainMemoryOnly&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged with PDFBox."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;MemoryUsageSetting&lt;/code&gt;. No merger utility class. See &lt;a href="https://ironpdf.com/examples/merge-pdfs/" rel="noopener noreferrer"&gt;IronPDF merge documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox .NET port, content-stream drawing):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel.font&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.util&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;java.io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkPdfbox&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PDDocument&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDPage&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPages&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;PDPageContentStream&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDPageContentStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PDPageContentStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AppendMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APPEND&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PDType1Font&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HELVETICA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setNonStrokingColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// light gray&lt;/span&gt;

                &lt;span class="c1"&gt;// Rotate 45 degrees around page center&lt;/span&gt;
                &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMediaBox&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getWidth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMediaBox&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getHeight&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Matrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRotateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toRadians&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newLineAtOffset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// approximate centering&lt;/span&gt;
                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked_pdfbox.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;finally&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked with PDFBox."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1 style='color:rgb(200,200,200);font-size:48px;opacity:0.5;font-family:Helvetica;'&amp;gt;CONFIDENTIAL&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Content-stream operations, matrix transforms, and per-page loops collapse into one HTML string.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (PDFBox .NET port):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;org.apache.pdfbox.pdmodel.encryption&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;java.io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordPdfbox&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PDDocument&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;AccessPermission&lt;/span&gt; &lt;span class="n"&gt;perms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AccessPermission&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;perms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCanPrint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;perms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCanModify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;perms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCanExtractContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;StandardProtectionPolicy&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StandardProtectionPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"owner123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// owner password&lt;/span&gt;
                &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// user password&lt;/span&gt;
                &lt;span class="n"&gt;perms&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEncryptionKeyLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;protect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;policy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected_pdfbox.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;finally&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected with PDFBox."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoPrint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserCopyPasteContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserEdits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfEditSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoEdit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;AccessPermission&lt;/code&gt; + &lt;code&gt;StandardProtectionPolicy&lt;/code&gt; ceremony. See &lt;a href="https://ironpdf.com/how-to/pdf-permissions-passwords/" rel="noopener noreferrer"&gt;IronPDF security documentation&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Runtime Shift Is the Migration
&lt;/h3&gt;

&lt;p&gt;Unlike a port-to-port API swap, this migration changes the runtime shape of the dependency. You are eliminating an IKVM-bundled JVM (or a real JVM via JCOBridge) and the Java-style surface that comes with it. Plan for the dependency cleanup, not just the code rewrite. The &lt;code&gt;.csproj&lt;/code&gt; references, transitive Java-class assemblies, and any bootstrap code that initialized the bridge all need to go.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page Indexing
&lt;/h3&gt;

&lt;p&gt;Both PDFBox and IronPDF use 0-based page indexing. This is the one thing that does not change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Text Extraction Ordering
&lt;/h3&gt;

&lt;p&gt;PDFBox's &lt;code&gt;PDFTextStripper&lt;/code&gt; extracts text in content-stream order by default, which can produce scrambled output. You must set &lt;code&gt;setSortByPosition(true)&lt;/code&gt; for visual reading order. IronPDF's &lt;code&gt;ExtractAllText()&lt;/code&gt; returns text without requiring that toggle; if extraction quality matters for your corpus, compare outputs side-by-side on representative documents during the migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Management
&lt;/h3&gt;

&lt;p&gt;PDFBox's &lt;code&gt;PDDocument&lt;/code&gt; requires an explicit &lt;code&gt;close()&lt;/code&gt; call. IronPDF's &lt;code&gt;PdfDocument&lt;/code&gt; implements &lt;code&gt;IDisposable&lt;/code&gt;, so a &lt;code&gt;using&lt;/code&gt; block handles cleanup. The pattern maps naturally, and disposal failures are easier to catch in idiomatic C# than in Java-shaped wrappers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bouncy Castle Dependency
&lt;/h3&gt;

&lt;p&gt;The IKVM-based PDFBox ports pull in Bouncy Castle for encryption. IronPDF handles encryption internally in .NET, so the Bouncy Castle dependency goes away with the port.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Eliminating the Bridge
&lt;/h3&gt;

&lt;p&gt;Calls through IKVM or JCOBridge cross a runtime boundary on every invocation. Direct .NET calls in IronPDF avoid that crossover:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before: Java-bridged call through the .NET port&lt;/span&gt;
&lt;span class="c1"&gt;// PDDocument doc = PDDocument.load(new File(path));&lt;/span&gt;

&lt;span class="c1"&gt;// After: in-process .NET, no bridge&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Renderer Reuse
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disposal
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Edge Cases Worth Flagging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text extraction quality:&lt;/strong&gt; PDFBox's &lt;code&gt;PDFTextStripper&lt;/code&gt; is well-regarded for extraction quality. Compare IronPDF's output against your representative document corpus. For extraction-heavy workloads, also consider &lt;a href="https://github.com/UglyToad/PdfPig" rel="noopener noreferrer"&gt;PdfPig&lt;/a&gt;, a .NET-native PDF text extraction library under Apache 2.0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF/A validation:&lt;/strong&gt; PDFBox's Preflight module validates PDF/A compliance. IronPDF generates PDF/A but does not validate existing documents. If you need validation, keep Preflight or move to &lt;a href="https://verapdf.org/" rel="noopener noreferrer"&gt;veraPDF&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large file memory:&lt;/strong&gt; PDFBox exposes &lt;code&gt;MemoryUsageSetting&lt;/code&gt; to choose between heap and temp-file buffering for large documents. IronPDF handles this internally; benchmark with your largest production documents during migration.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration (8 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Identify which PDFBox .NET port is referenced: &lt;code&gt;Pdfbox&lt;/code&gt;, &lt;code&gt;Pdfbox-IKVM&lt;/code&gt;, &lt;code&gt;PdfBox_DotNet_Version&lt;/code&gt;, or &lt;code&gt;MASES.NetPDF&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] List all PDFBox operations in use: merge, text extraction, form fill, encryption, etc.&lt;/li&gt;
&lt;li&gt;[ ] Determine whether PDFBox Preflight (PDF/A validation) is in the dependency tree&lt;/li&gt;
&lt;li&gt;[ ] Obtain an IronPDF trial key from &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;ironpdf.com/get-started/license-keys/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Create a migration branch&lt;/li&gt;
&lt;li&gt;[ ] Document any bootstrap code that initializes IKVM or JCOBridge&lt;/li&gt;
&lt;li&gt;[ ] Identify all call sites that pass &lt;code&gt;java.io.File&lt;/code&gt; or other bridged Java types&lt;/li&gt;
&lt;li&gt;[ ] Plan removal of IKVM/JCOBridge runtime assets from the deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration (10 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Add the &lt;code&gt;IronPdf&lt;/code&gt; NuGet package to the .NET project&lt;/li&gt;
&lt;li&gt;[ ] Set &lt;code&gt;IronPdf.License.LicenseKey&lt;/code&gt; in application startup&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PDDocument.load(new File(...))&lt;/code&gt; with &lt;code&gt;PdfDocument.FromFile(...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PDFMergerUtility&lt;/code&gt; patterns with &lt;code&gt;PdfDocument.Merge()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;PDPageContentStream&lt;/code&gt; watermark drawing with &lt;code&gt;ApplyWatermark()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;AccessPermission&lt;/code&gt; + &lt;code&gt;StandardProtectionPolicy&lt;/code&gt; with &lt;code&gt;SecuritySettings&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace external-tool HTML-to-PDF with &lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Add &lt;code&gt;using&lt;/code&gt; blocks for all &lt;code&gt;PdfDocument&lt;/code&gt; instances&lt;/li&gt;
&lt;li&gt;[ ] Test text extraction output against the PDFBox baseline&lt;/li&gt;
&lt;li&gt;[ ] Remove the PDFBox port and IKVM/JCOBridge packages from &lt;code&gt;.csproj&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing (7 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Compare PDF merge output byte-for-byte or visually&lt;/li&gt;
&lt;li&gt;[ ] Compare text extraction output against PDFBox for 10+ diverse documents&lt;/li&gt;
&lt;li&gt;[ ] Test password protection round-trip (encrypt, save, open, verify permissions)&lt;/li&gt;
&lt;li&gt;[ ] Test watermark positioning on multi-page documents&lt;/li&gt;
&lt;li&gt;[ ] Benchmark native IronPDF calls against the PDFBox-port baseline&lt;/li&gt;
&lt;li&gt;[ ] Validate on Linux containers (the bundled JVM and IronPDF's runtime behave differently)&lt;/li&gt;
&lt;li&gt;[ ] Run integration tests for all existing PDF workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration (4 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove IKVM/JCOBridge runtime assemblies from the build output&lt;/li&gt;
&lt;li&gt;[ ] Drop the JDK or JRE from CI agents if it was only there for the port&lt;/li&gt;
&lt;li&gt;[ ] Slim Docker base images that previously included Java tooling&lt;/li&gt;
&lt;li&gt;[ ] Update architecture diagrams (one fewer runtime to think about)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where to Go From Here
&lt;/h2&gt;

&lt;p&gt;The real migration here is runtime-to-runtime, not API-to-API. You are removing a Java-shaped surface, a bundled or bridged JVM, and the Java exception types and &lt;code&gt;File&lt;/code&gt; objects that leak through any .NET PDFBox port. The dependency simplification is where the savings compound.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Worth knowing even without IronPDF:&lt;/strong&gt; if you are pinned to an IKVM-based PDFBox port for compatibility reasons, IKVM's coverage of newer Java versions is limited. If you stay in .NET but want a free option, &lt;a href="https://github.com/UglyToad/PdfPig" rel="noopener noreferrer"&gt;PdfPig&lt;/a&gt; handles text extraction and basic manipulation in pure C# under Apache 2.0, though it does not do HTML-to-PDF.&lt;/p&gt;

&lt;p&gt;What is the most unusual PDFBox-port setup you have inherited? I have seen IKVM bindings, JCOBridge wrappers, a CLI shell-out, and even a scheduled job that polled a shared folder. Drop it in the comments if you have seen something even more unusual.&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test before committing.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>Moving from ActivePDF to IronPDF: Three Components to One</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Thu, 04 Jun 2026 16:53:22 +0000</pubDate>
      <link>https://dev.to/ironsoftware/moving-from-activepdf-to-ironpdf-three-components-to-one-5afn</link>
      <guid>https://dev.to/ironsoftware/moving-from-activepdf-to-ironpdf-three-components-to-one-5afn</guid>
      <description>&lt;p&gt;Three separate ActivePDF NuGet packages. Three separate DLL references. Three separate licensing conversations with procurement. Your WebGrabber handles HTML conversion, Toolkit handles manipulation, and DocConverter handles everything else. None of them communicate cleanly, and all of them require Windows Server.&lt;/p&gt;

&lt;p&gt;Then the Apryse acquisition happened, and now your support tickets route through a portal that looks nothing like the one your team bookmarked two years ago. The product still works. But the question every architect eventually asks is: do we really need three components for what is, fundamentally, one pipeline?&lt;/p&gt;

&lt;p&gt;This guide walks you through consolidating ActivePDF into &lt;a href="https://ironpdf.com" rel="noopener noreferrer"&gt;IronPDF&lt;/a&gt;, a single NuGet package that covers HTML-to-PDF, manipulation, merge, watermark, and security. Eighty percent of this content applies regardless of your target library. The other twenty percent shows the specific IronPDF API mappings. Use what is useful, ignore what is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;ActivePDF has served enterprise .NET shops for over a decade. Here is why teams re-evaluate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modular overhead.&lt;/strong&gt; You buy and license Toolkit, WebGrabber, and DocConverter separately. Each has its own DLL, its own NuGet package, its own API surface. A single PDF generation workflow might touch all three.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows Server lock-in.&lt;/strong&gt; ActivePDF components require Windows Server. If you are moving to Linux containers, Docker on ARM, or Azure App Service on Linux, ActivePDF does not follow you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MSI installer dependencies.&lt;/strong&gt; WebGrabber and DocConverter require MSI installation on the host, not just a NuGet restore. This breaks immutable infrastructure patterns and complicates CI/CD.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acquisition uncertainty.&lt;/strong&gt; Apryse acquired ActivePDF and merged support portals. The product roadmap, pricing, and long-term component strategy may shift toward Apryse's own PDFTron SDK.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IE-era rendering engine.&lt;/strong&gt; WebGrabber historically offered Native and Internet Explorer rendering engines. Modern HTML5/CSS3 applications need a Chrome-class renderer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API verbosity.&lt;/strong&gt; Toolkit uses COM-style patterns inherited from its Classic ASP roots. Method names like &lt;code&gt;SetMasterPassword&lt;/code&gt; and &lt;code&gt;CopyForm&lt;/code&gt; work, but they are verbose compared to fluent property-based APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited cross-platform path.&lt;/strong&gt; Even though Toolkit's NuGet targets .NET Standard 1.0, the underlying native code and WebGrabber/DocConverter dependencies are Windows-only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate HTML conversion path.&lt;/strong&gt; If you need both HTML-to-PDF and PDF manipulation, you are calling WebGrabber to generate the PDF, then loading it into Toolkit to manipulate it. That is two separate APIs for one workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DocConverter as a Windows service.&lt;/strong&gt; DocConverter runs as a watched-folder service or COM automation host. In a microservices architecture, this model feels like a detour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License complexity.&lt;/strong&gt; Each ActivePDF component is licensed separately, often per-server. For teams scaling horizontally, the licensing math gets expensive.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;ActivePDF (Toolkit + WebGrabber)&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modular: Toolkit = manipulation, WebGrabber = HTML-to-PDF&lt;/td&gt;
&lt;td&gt;Unified: generation + manipulation in one package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per-component, per-server licensing&lt;/td&gt;
&lt;td&gt;Per-developer, perpetual licenses available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;COM-influenced methods, procedural&lt;/td&gt;
&lt;td&gt;Fluent properties, C#-native patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium, need to learn multiple component APIs&lt;/td&gt;
&lt;td&gt;Low, single namespace, discoverable API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML Rendering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebGrabber: Native and IE engines&lt;/td&gt;
&lt;td&gt;Chrome rendering engine, modern web standards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Page Indexing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1-based in Toolkit (&lt;code&gt;-1&lt;/code&gt; means "to end")&lt;/td&gt;
&lt;td&gt;0-based page indices in most APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Thread Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Toolkit instances are stateful; serialize access per instance&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChromePdfRenderer&lt;/code&gt; is stateless, safe to share&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;APToolkitNET&lt;/code&gt; / &lt;code&gt;APWebGrabber&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF (from WebGrabber)&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Direct replacement; IronPDF eliminates the separate WebGrabber dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF manipulation (from Toolkit)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;API shape differs; Toolkit's COM-style methods map to IronPDF properties&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PdfDocument.Merge()&lt;/code&gt; replaces Toolkit's merge methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split / extract pages&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;IronPDF page indexer vs. Toolkit page operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermark / stamping&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Toolkit draws watermarks as page text per page; IronPDF uses HTML-based &lt;code&gt;ApplyWatermark&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password / encryption&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both support owner/user passwords; property names differ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form filling&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Toolkit has extensive form APIs; IronPDF uses &lt;code&gt;FormField&lt;/code&gt; collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Document conversion (300+ formats)&lt;/td&gt;
&lt;td&gt;High / N/A&lt;/td&gt;
&lt;td&gt;DocConverter has no direct IronPDF equivalent. Use IronPDF for HTML/URL; for Office to PDF, consider a dedicated converter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Print-to-PDF (Server)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;No direct equivalent in IronPDF. Consider OS-level print drivers or alternative tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watched-folder automation (Meridian)&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Architectural pattern, implement with FileSystemWatcher or message queues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Different API surface; see the &lt;a href="https://ironpdf.com/how-to/cryptographic-sign/" rel="noopener noreferrer"&gt;IronPDF digital signatures documentation&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML-to-PDF + basic manipulation, no DocConverter&lt;/td&gt;
&lt;td&gt;Migrate. IronPDF unifies WebGrabber + Toolkit into one NuGet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy DocConverter usage (Office, CAD conversions)&lt;/td&gt;
&lt;td&gt;Partial migration. Use IronPDF for HTML/PDF ops, keep DocConverter or find a dedicated converter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling to Linux / Docker / cross-platform&lt;/td&gt;
&lt;td&gt;Migrate. ActivePDF is Windows-only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deep Toolkit form automation&lt;/td&gt;
&lt;td&gt;Evaluate IronPDF's form API coverage for your specific form workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;.NET 6+ (or .NET Framework 4.6.2+)&lt;/li&gt;
&lt;li&gt;A trial or licensed &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;IronPDF key&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Inventory of which ActivePDF components your codebase uses&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Find ActivePDF References
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all ActivePDF using statements and DLL references&lt;/span&gt;
rg &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"APToolkitNET|APWebGrabber|ActivePDF|APDocConverter"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Count Toolkit instantiations&lt;/span&gt;
rg &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"new Toolkit&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Find project/config references&lt;/span&gt;
rg &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"ActivePDF"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.csproj"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.config"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't have &lt;code&gt;rg&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rl&lt;/span&gt; &lt;span class="s2"&gt;"APToolkitNET&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;APWebGrabber&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;ActivePDF"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.cs"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In PowerShell, &lt;code&gt;Get-ChildItem -Recurse -Filter *.cs | Select-String "APToolkitNET|APWebGrabber|ActivePDF"&lt;/code&gt; covers the same ground.&lt;/p&gt;

&lt;h3&gt;
  
  
  Swap NuGet Packages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove ActivePDF packages&lt;/span&gt;
dotnet remove package ActivePDF.Toolkit
dotnet remove package ActivePDF.WebGrabber  &lt;span class="c"&gt;# if present as NuGet&lt;/span&gt;

&lt;span class="c"&gt;# Install IronPDF (replaces both)&lt;/span&gt;
dotnet add package IronPdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If WebGrabber or DocConverter were installed via MSI rather than NuGet, remove the DLL references from your &lt;code&gt;.csproj&lt;/code&gt; manually and uninstall the MSI from your build/deploy hosts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ActivePDF Toolkit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ActivePDF Toolkit licensing is handled by the installed product (per-server&lt;/span&gt;
&lt;span class="c1"&gt;// or per-core license file), not by a code-level API. From Toolkit 10 onward&lt;/span&gt;
&lt;span class="c1"&gt;// the native libraries also need to be discoverable - typically via the&lt;/span&gt;
&lt;span class="c1"&gt;// CoreLibPath constructor argument pointing at the install directory.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APToolkitNET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Toolkit&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Toolkit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;CoreLibPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;@"C:\Program Files\ActivePDF\Toolkit\bin"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Licensing comes from the installed ActivePDF license file.&lt;/span&gt;
            &lt;span class="c1"&gt;// Toolkit methods return integer status codes (0 = success).&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ActivePDF Toolkit ready."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// One line. Works in containers, CI, serverless.&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"IronPDF licensed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLicensed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ActivePDF - Toolkit and WebGrabber ship and license separately&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APToolkitNET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// Toolkit: PDF manipulation&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APWebGrabber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// WebGrabber: HTML-to-PDF / URL-to-PDF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// watermarks, headers, footers&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Rendering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// render options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Basic HTML-to-PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ActivePDF WebGrabber):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WebGrabber renders from a URL or HTML file path, so HTML strings&lt;/span&gt;
&lt;span class="c1"&gt;// have to be written to a temp file first.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APWebGrabber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebGrabber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;&amp;lt;body&amp;gt;
                &amp;lt;h1&amp;gt;Invoice #1042&amp;lt;/h1&amp;gt;
                &amp;lt;p&amp;gt;Amount: $5,200.00&amp;lt;/p&amp;gt;
            &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;tempHtml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTempPath&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"input.html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tempHtml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempHtml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputDirectory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCurrentDirectory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFilename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ConvertToPDF returns 0 on success.&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertToPDF&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"Saved with WebGrabber."&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$"WebGrabber error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPaperSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Letter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// mm&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;&amp;lt;body&amp;gt;
                &amp;lt;h1&amp;gt;Invoice #1042&amp;lt;/h1&amp;gt;
                &amp;lt;p&amp;gt;Amount: $5,200.00&amp;lt;/p&amp;gt;
            &amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No output directory configuration. No status-code checking. No separate install. One NuGet, one renderer, one &lt;code&gt;SaveAs&lt;/code&gt;. See the &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML-to-PDF tutorial&lt;/a&gt; for URL-based and file-based rendering.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ActivePDF Namespace&lt;/th&gt;
&lt;th&gt;IronPDF Namespace&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APToolkitNET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Document manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APWebGrabber&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML-to-PDF conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N/A (COM properties)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.Editing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Watermarks, headers, footers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ActivePDF Class&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APToolkitNET.Toolkit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PDF loading, manipulation, saving&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;APWebGrabber.WebGrabber&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML/URL to PDF conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DocConverter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;N/A (no direct equivalent)&lt;/td&gt;
&lt;td&gt;300+ format conversion, use dedicated tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status code returns (int, &lt;code&gt;0&lt;/code&gt; = success)&lt;/td&gt;
&lt;td&gt;Standard .NET exceptions&lt;/td&gt;
&lt;td&gt;Error handling pattern shift&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ActivePDF Toolkit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Open existing PDF&lt;/td&gt;
&lt;td&gt;&lt;code&gt;toolkit.OpenInputFile("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open with password&lt;/td&gt;
&lt;td&gt;&lt;code&gt;toolkit.OpenInputFile("file.pdf", password: "pass")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("file.pdf", "pass")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create from HTML&lt;/td&gt;
&lt;td&gt;WebGrabber separate component&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderHtmlAsPdf(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create from URL&lt;/td&gt;
&lt;td&gt;WebGrabber with &lt;code&gt;URL&lt;/code&gt; property&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renderer.RenderUrlAsPdf("https://...")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ActivePDF Toolkit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get page count&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;toolkit.NumPages&lt;/code&gt; (property)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy specific pages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;toolkit.CopyForm(startPage, endPage)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add pages from another PDF&lt;/td&gt;
&lt;td&gt;&lt;code&gt;toolkit.MergeFile(file, startPage, endPage)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete pages&lt;/td&gt;
&lt;td&gt;&lt;code&gt;toolkit.DeletePage(index)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RemovePages(index)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge / Split Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ActivePDF Toolkit&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge multiple PDFs&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;OpenOutputFile&lt;/code&gt; + loop &lt;code&gt;MergeFile(path, 1, -1)&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2, pdf3)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split by page range&lt;/td&gt;
&lt;td&gt;&lt;code&gt;toolkit.CopyForm(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(start, end)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ActivePDF WebGrabber):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APWebGrabber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfActivePdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebGrabber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;
            &amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: 'Segoe UI', sans-serif; }
                .banner { background: #1a237e; color: #fff; padding: 24px; }
                .items { margin: 20px; }
                table { width: 100%; border-collapse: collapse; }
                td, th { padding: 10px; border-bottom: 1px solid #eee; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;
            &amp;lt;body&amp;gt;
                &amp;lt;div class='banner'&amp;gt;&amp;lt;h1&amp;gt;Order Confirmation&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div class='items'&amp;gt;
                    &amp;lt;table&amp;gt;
                        &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Item&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Widget Pro&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$49.95&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Gadget Lite&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$19.99&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;/table&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/body&amp;gt;
            &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// WebGrabber takes a URL or file path; HTML strings go via a temp file.&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;tempHtml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTempPath&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"order.html"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tempHtml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempHtml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputDirectory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"C:\output\"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFilename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"order.pdf"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;APWebGrabber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Letter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConvertToPDF&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"Success"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$"Error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPaperSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Letter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintHtmlBackgrounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CssMediaType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfCssMediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Screen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;
            &amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: 'Segoe UI', sans-serif; }
                .banner { background: #1a237e; color: #fff; padding: 24px; }
                .items { margin: 20px; }
                table { width: 100%; border-collapse: collapse; }
                td, th { padding: 10px; border-bottom: 1px solid #eee; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;
            &amp;lt;body&amp;gt;
                &amp;lt;div class='banner'&amp;gt;&amp;lt;h1&amp;gt;Order Confirmation&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div class='items'&amp;gt;
                    &amp;lt;table&amp;gt;
                        &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Item&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Qty&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Widget Pro&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;5&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$49.95&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Gadget Lite&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;2&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$19.99&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;/table&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/body&amp;gt;
            &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"order.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No output directory. No status code to check. No MSI prerequisite. The Chrome engine renders the CSS grid and background colors faithfully. See the &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML-to-PDF tutorial&lt;/a&gt; for advanced rendering options.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ActivePDF Toolkit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APToolkitNET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeActivePdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Toolkit&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Toolkit&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Open the destination first, then merge each source file into it.&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenOutputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"C:\output\merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Output error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// MergeFile signature: MergeFile(FileName, StartPage, EndPage); -1 = "to end".&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MergeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"C:\input\part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merge1 error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MergeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"C:\input\part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merge2 error: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseOutputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged with ActivePDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The open-output, merge-file, close-output ceremony reduces to a single static call. See the &lt;a href="https://ironpdf.com/examples/merge-pdfs/" rel="noopener noreferrer"&gt;IronPDF merge documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ActivePDF Toolkit - drawn as page text per page):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APToolkitNET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkActivePdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Toolkit&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Toolkit&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenOutputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenInputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Toolkit draws watermarks as page text per page using CopyForm + PrintText.&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumPages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Helvetica"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;72&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetTextColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PrintText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DRAFT"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseInputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseOutputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked with ActivePDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// HTML watermark - full CSS control, one call covers all pages.&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1 style='color:rgb(200,200,200);font-size:48px;font-family:Helvetica;'&amp;gt;DRAFT&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ActivePDF Toolkit):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;APToolkitNET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordActivePdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Toolkit&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Toolkit&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenOutputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenInputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Toolkit applies encryption via a single call.&lt;/span&gt;
            &lt;span class="c1"&gt;// Signature: SetEncryption(ownerPassword, userPassword, keyLength, permissions)&lt;/span&gt;
            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetEncryption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"owner123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// copy all pages into the encrypted output&lt;/span&gt;
            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseInputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseOutputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected with ActivePDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoPrint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserCopyPasteContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserEdits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfEditSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoEdit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No open-output/close-output dance. No separate input/output file streams. See &lt;a href="https://ironpdf.com/how-to/pdf-permissions-passwords/" rel="noopener noreferrer"&gt;IronPDF password protection documentation&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Status Codes to Exceptions
&lt;/h3&gt;

&lt;p&gt;ActivePDF returns integer status codes from nearly every method (0 = success, non-zero = error). IronPDF throws exceptions on failure. Your error handling needs to shift from &lt;code&gt;if (result != 0)&lt;/code&gt; checks to &lt;code&gt;try/catch&lt;/code&gt; blocks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ActivePDF pattern&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MergeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1 to -1 = all pages&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* handle error */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// IronPDF pattern&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// handle error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Page Indexing Differences
&lt;/h3&gt;

&lt;p&gt;ActivePDF Toolkit uses 1-based page numbering in most operations. IronPDF uses 0-based indexing. Audit every page reference in your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Input/Output File Pattern
&lt;/h3&gt;

&lt;p&gt;ActivePDF Toolkit separates "open input" and "open output" into distinct calls. IronPDF loads a document and saves it. There is no separate output file concept. Any code that relies on the input/output split needs restructuring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ActivePDF pattern&lt;/span&gt;
&lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenOutputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenInputFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CopyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// copy all input pages into the output&lt;/span&gt;
&lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseInputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;toolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CloseOutputFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// IronPDF pattern&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... manipulate ...&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unit Conversion
&lt;/h3&gt;

&lt;p&gt;ActivePDF WebGrabber's &lt;code&gt;PageWidth&lt;/code&gt; / &lt;code&gt;PageHeight&lt;/code&gt; properties are in points (612 x 792 = US Letter; 595 x 842 = A4). IronPDF expresses standard sizes through the &lt;code&gt;PdfPaperSize&lt;/code&gt; enum and custom sizes through &lt;code&gt;SetCustomPaperSizeInMillimeters&lt;/code&gt; / &lt;code&gt;SetCustomPaperSizeInInches&lt;/code&gt;. Margins in IronPDF are millimeters, so if any of your existing configuration uses inches, multiply by 25.4 (for example, a 0.5 inch margin becomes &lt;code&gt;MarginTop = 12.7&lt;/code&gt; mm).&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Eliminating the Component Hop
&lt;/h3&gt;

&lt;p&gt;With ActivePDF, a typical HTML-to-manipulated-PDF workflow looks like: WebGrabber converts HTML, saves to disk, Toolkit opens the file, manipulates, then saves again. That is two disk round-trips and two component initializations.&lt;/p&gt;

&lt;p&gt;IronPDF keeps everything in memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// in-memory PdfDocument&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;DRAFT&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// still in memory&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// still in memory&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"final.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                   &lt;span class="c1"&gt;// one write to disk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Renderer Reuse
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ChromePdfRenderer&lt;/code&gt; is stateless. Create one and share it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disposal
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PdfDocument&lt;/code&gt; is &lt;code&gt;IDisposable&lt;/code&gt;. In high-throughput services, wrap in &lt;code&gt;using&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Edge Cases Worth Flagging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DocConverter replacement:&lt;/strong&gt; If you depend on DocConverter for Office-to-PDF, IronPDF does not natively convert &lt;code&gt;.docx&lt;/code&gt; or &lt;code&gt;.xlsx&lt;/code&gt; to PDF. Consider pairing IronPDF with a library like IronWord or a dedicated conversion service. Alternatively, Puppeteer Sharp or LibreOffice headless can handle Office conversions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watched-folder patterns:&lt;/strong&gt; If Meridian's watched-folder feature is part of your pipeline, replace it with a &lt;code&gt;FileSystemWatcher&lt;/code&gt; + IronPDF processing loop. This gives you more control over error handling and retry logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large batch processing:&lt;/strong&gt; IronPDF supports &lt;code&gt;Parallel.ForEach&lt;/code&gt; with a shared renderer instance. ActivePDF Toolkit instances are stateful, so concurrent code typically serializes access per instance or pools instances.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration (8 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Inventory which ActivePDF components are in use: Toolkit, WebGrabber, DocConverter, Meridian, Server&lt;/li&gt;
&lt;li&gt;[ ] Run &lt;code&gt;rg&lt;/code&gt; scan to find all ActivePDF references across the codebase&lt;/li&gt;
&lt;li&gt;[ ] Identify DocConverter-dependent workflows that need alternative solutions&lt;/li&gt;
&lt;li&gt;[ ] Obtain an IronPDF trial key from &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;ironpdf.com/get-started/license-keys/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Create a migration branch&lt;/li&gt;
&lt;li&gt;[ ] Document any WebGrabber MSI installation steps in deployment scripts&lt;/li&gt;
&lt;li&gt;[ ] Identify all status-code error handling patterns that need try/catch conversion&lt;/li&gt;
&lt;li&gt;[ ] List all 1-based Toolkit page-index references (and any uses of &lt;code&gt;-1&lt;/code&gt; for "to end") that need updating&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration (10 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove all ActivePDF NuGet packages and DLL references&lt;/li&gt;
&lt;li&gt;[ ] Uninstall WebGrabber / DocConverter MSIs from build servers (if applicable)&lt;/li&gt;
&lt;li&gt;[ ] Add &lt;code&gt;IronPdf&lt;/code&gt; NuGet package&lt;/li&gt;
&lt;li&gt;[ ] Replace all namespace imports&lt;/li&gt;
&lt;li&gt;[ ] Replace licensing calls with &lt;code&gt;IronPdf.License.LicenseKey = "..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace WebGrabber HTML-to-PDF with &lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace Toolkit open/copy/close patterns with &lt;code&gt;PdfDocument.FromFile()&lt;/code&gt; + &lt;code&gt;SaveAs()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;SetEncryption(...)&lt;/code&gt; with &lt;code&gt;SecuritySettings&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;[ ] Replace status-code error handling with try/catch&lt;/li&gt;
&lt;li&gt;[ ] Update Toolkit 1-based page indices and &lt;code&gt;-1&lt;/code&gt; "to end" sentinels for the new APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing (7 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Compare PDF output visually between ActivePDF and IronPDF for key templates&lt;/li&gt;
&lt;li&gt;[ ] Test HTML rendering of your most complex CSS (grid, flexbox, web fonts)&lt;/li&gt;
&lt;li&gt;[ ] Verify password protection open/save round-trip&lt;/li&gt;
&lt;li&gt;[ ] Test merge with 5+ documents&lt;/li&gt;
&lt;li&gt;[ ] Validate watermark rendering on multi-page documents&lt;/li&gt;
&lt;li&gt;[ ] Run load tests with concurrent rendering&lt;/li&gt;
&lt;li&gt;[ ] Test on Linux container if cross-platform is a goal&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration (4 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove WebGrabber/DocConverter MSI installation from deployment automation&lt;/li&gt;
&lt;li&gt;[ ] Remove ActivePDF license files and server registrations&lt;/li&gt;
&lt;li&gt;[ ] Update project documentation and architecture diagrams&lt;/li&gt;
&lt;li&gt;[ ] Monitor production for two weeks, tracking PDF-related error rates&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The biggest win in this migration is consolidation. Going from three separate components (WebGrabber + Toolkit + potentially DocConverter) to a single NuGet package simplifies your dependency tree, your licensing, and your deployment pipeline. The biggest risk is DocConverter: if you rely on Office-to-PDF conversion for 300+ formats, plan that replacement separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Worth knowing even without IronPDF:&lt;/strong&gt; the ActivePDF Toolkit pattern of opening an output file, merging files into it, then closing is fragile. Forget to close and you get corrupted files. Any modern PDF library that uses an in-memory document model eliminates this class of bug.&lt;/p&gt;

&lt;p&gt;What is the most obscure ActivePDF Toolkit method your codebase depends on? I am curious whether it is &lt;code&gt;CopyForm&lt;/code&gt; with page-range offsets, some Meridian watched-folder hook, or maybe DocConverter's CAD-to-PDF pipeline. Let me know in the comments, those are the patterns that trip up real-world migrations.&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test before committing.&lt;/p&gt;




</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>Moving from ABCpdf to IronPDF: What I Learned</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Thu, 04 Jun 2026 16:45:46 +0000</pubDate>
      <link>https://dev.to/ironsoftware/moving-from-abcpdf-to-ironpdf-what-i-learned-k50</link>
      <guid>https://dev.to/ironsoftware/moving-from-abcpdf-to-ironpdf-what-i-learned-k50</guid>
      <description>&lt;p&gt;Your ABCpdf &lt;code&gt;Doc&lt;/code&gt; object just swallowed a 47-page HTML invoice and spat out a blank PDF. Again. The bundled Chromium engine you pinned eighteen months ago is now several Chromium majors behind upstream, and the CSS grid you shipped last sprint renders as a single column. You could pin a newer ABCChrome runtime, patch the HTML, or file another ticket. Or you could migrate.&lt;/p&gt;

&lt;p&gt;This guide walks you through replacing ABCpdf with &lt;a href="https://ironpdf.com" rel="noopener noreferrer"&gt;IronPDF&lt;/a&gt; in a .NET codebase. Eighty percent of what follows is general migration knowledge (dependency auditing, API surface mapping, testing strategy) that applies even if you pick a different target library. The remaining twenty percent is where IronPDF specifically cuts the boilerplate. Copy-paste the code, run the checklist, and ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Migrate
&lt;/h2&gt;

&lt;p&gt;Nobody migrates a working PDF pipeline for fun. Here are the concrete triggers that push teams to evaluate alternatives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML engine version churn.&lt;/strong&gt; ABCpdf bundles multiple Chromium forks ("ABCChrome") and exposes them through &lt;code&gt;EngineType.Chrome123&lt;/code&gt;, &lt;code&gt;Chrome117&lt;/code&gt;, &lt;code&gt;Chrome86&lt;/code&gt;, and &lt;code&gt;Chrome65&lt;/code&gt;. The default in v13 is Chrome123, but pinning to an older engine to keep behavior stable means you fall behind on CSS features supported by modern browsers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native runtime deployment.&lt;/strong&gt; ABCpdf requires platform-specific native binaries alongside the managed assembly. On Linux this means pulling the &lt;code&gt;ABCpdf.ABCChrome117.Linux&lt;/code&gt; or &lt;code&gt;ABCpdf.ABCChrome123.Linux&lt;/code&gt; runtime packages. Docker builds, Azure App Services, and CI agents all need these resolved correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License file mechanics.&lt;/strong&gt; ABCpdf uses license keys that historically lived in the registry or in &lt;code&gt;XSettings&lt;/code&gt;-style installation calls. Cloud-first deployments, especially ephemeral containers, fight with this model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API verbosity for common tasks.&lt;/strong&gt; Generating a PDF from HTML in ABCpdf requires creating a &lt;code&gt;Doc&lt;/code&gt;, calling &lt;code&gt;Doc.AddImageHtml()&lt;/code&gt;, sometimes chaining additional pages, then calling &lt;code&gt;doc.Save()&lt;/code&gt; and &lt;code&gt;doc.Clear()&lt;/code&gt;. That is a lot of ceremony for "turn this HTML into a file."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page coordinate system.&lt;/strong&gt; ABCpdf uses a bottom-left origin with point-based coordinates. If your team thinks in pixels or CSS units, every measurement needs manual conversion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread safety caveats.&lt;/strong&gt; ABCpdf &lt;code&gt;Doc&lt;/code&gt; objects are not designed to be shared across threads. High-throughput services need careful pooling or per-request instantiation, and it is easy to get wrong under load.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform gaps.&lt;/strong&gt; Linux support arrived in v13, but some features (XPS, WPF rendering) remain Windows-only. macOS is not supported at all. If your deployment matrix spans operating systems, you carry conditional code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Font embedding complexity.&lt;/strong&gt; Getting CJK or custom web fonts to render correctly often requires manual font installation on the server, plus explicit configuration in ABCpdf's rendering options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No built-in Razor or template integration.&lt;/strong&gt; If your .NET app uses Razor views, you must pre-render them to HTML strings yourself before passing to ABCpdf.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upgrade friction between major versions.&lt;/strong&gt; Namespace and assembly names change between major versions (e.g., &lt;code&gt;WebSupergoo.ABCpdf12&lt;/code&gt; to &lt;code&gt;WebSupergoo.ABCpdf13&lt;/code&gt;). Every major upgrade is a mini-migration anyway.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;ABCpdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full PDF manipulation with multiple HTML engines&lt;/td&gt;
&lt;td&gt;HTML-first PDF generation and manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tiered: Standard $329 (32-bit), Professional $479, Enterprise $4,790, Group $33,530&lt;/td&gt;
&lt;td&gt;Per-developer, perpetual licenses available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API Style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Imperative &lt;code&gt;Doc&lt;/code&gt; object, manual page chaining&lt;/td&gt;
&lt;td&gt;Fluent renderer, one-call HTML-to-PDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate, coordinate system and chaining take time&lt;/td&gt;
&lt;td&gt;Low, HTML/CSS developers productive in minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML Rendering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multiple Chromium versions (Chrome123/117/86/65), Gecko, WebKit, MSHtml&lt;/td&gt;
&lt;td&gt;Built-in Chromium rendering engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Page Indexing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1-based&lt;/td&gt;
&lt;td&gt;0-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Thread Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Doc&lt;/code&gt; not designed for shared use, manual pooling required&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChromePdfRenderer&lt;/code&gt; reusable across requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WebSupergoo.ABCpdf13&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Migration Complexity Assessment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Effort by Feature
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Direct replacement, IronPDF handles pagination automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL to PDF&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;RenderUrlAsPdf&lt;/code&gt; replaces &lt;code&gt;AddImageUrl&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PdfDocument.Merge()&lt;/code&gt; is a one-liner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split / extract pages&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Page range copy via &lt;code&gt;CopyPages&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermark&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;ABCpdf uses &lt;code&gt;Doc.AddText&lt;/code&gt; at coordinates, IronPDF uses &lt;code&gt;ApplyWatermark&lt;/code&gt; with HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password / encryption&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Property-based in both, IronPDF uses &lt;code&gt;SecuritySettings&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Different API surface, consult the IronPDF signing docs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form filling&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;ABCpdf uses field atoms, IronPDF uses a &lt;code&gt;FormField&lt;/code&gt; collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF/A compliance&lt;/td&gt;
&lt;td&gt;Medium-High&lt;/td&gt;
&lt;td&gt;ABCpdf has long-standing PDF/A export, IronPDF supports PDF/A export as well&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text extraction&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Both offer text extraction, API shape differs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accessibility tagging&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;ABCpdf 13 has mature auto-tagging, evaluate IronPDF coverage against your requirements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTML-heavy generation, minimal low-level manipulation&lt;/td&gt;
&lt;td&gt;Migrate, IronPDF's one-call renderer saves significant code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy PDF/A and accessibility tagging workflows&lt;/td&gt;
&lt;td&gt;Evaluate carefully, ABCpdf 13's tagging is mature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker / Linux-first deployment&lt;/td&gt;
&lt;td&gt;Migrate, IronPDF's single NuGet, no separate native runtime package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Existing large ABCpdf codebase with coordinate-based drawing&lt;/td&gt;
&lt;td&gt;Phased migration, wrap new features in IronPDF, legacy in ABCpdf&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Before You Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;.NET 6+ (or .NET Framework 4.6.2+)&lt;/li&gt;
&lt;li&gt;A trial or licensed &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;IronPDF key&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Access to your CI pipeline configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Find ABCpdf References
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;rg&lt;/code&gt; (ripgrep) to locate every ABCpdf touchpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all ABCpdf using statements and references&lt;/span&gt;
rg &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"WebSupergoo|ABCpdf|XSettings|Doc&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;Add"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Count occurrences for effort estimation&lt;/span&gt;
rg &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"new Doc&lt;/span&gt;&lt;span class="se"&gt;\(\)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.cs"&lt;/span&gt;

&lt;span class="c"&gt;# Find project file references&lt;/span&gt;
rg &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"ABCpdf"&lt;/span&gt; &lt;span class="nt"&gt;--glob&lt;/span&gt; &lt;span class="s2"&gt;"*.csproj"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do not have &lt;code&gt;rg&lt;/code&gt;, the &lt;code&gt;grep&lt;/code&gt; equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rl&lt;/span&gt; &lt;span class="s2"&gt;"WebSupergoo&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;ABCpdf&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;XSettings"&lt;/span&gt; &lt;span class="nt"&gt;--include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.cs"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In PowerShell, &lt;code&gt;Get-ChildItem -Recurse -Filter *.cs | Select-String -Pattern "WebSupergoo|ABCpdf"&lt;/code&gt; achieves the same result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Swap NuGet Packages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove ABCpdf&lt;/span&gt;
dotnet remove package ABCpdf

&lt;span class="c"&gt;# Install IronPDF&lt;/span&gt;
dotnet add package IronPdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Quick Start Migration (3 Steps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: License Configuration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ABCpdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ABCpdf license -- installed via XSettings or registry&lt;/span&gt;
        &lt;span class="n"&gt;XSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-ABCPDF-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ABCpdf license installed."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// IronPDF license -- one line, works in containers&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"IronPDF licensed: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsLicensed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Namespace Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13.Objects&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Editing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// watermarks, headers, footers&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Rendering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// render options&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Basic HTML-to-PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ABCpdf, verbose &lt;code&gt;Doc&lt;/code&gt; lifecycle):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13.Objects&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;XSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-ABCPDF-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Doc&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Doc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EngineType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chrome123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddImageHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Invoice&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;Hello from ABCpdf&amp;lt;/p&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// manual cleanup required&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CssMediaType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfCssMediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Screen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Invoice&amp;lt;/h1&amp;gt;&amp;lt;p&amp;gt;Hello from IronPDF&amp;lt;/p&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// no Clear() needed, IDisposable handles cleanup via using blocks&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The manual &lt;code&gt;Doc.Clear()&lt;/code&gt; and the engine selection step are gone. IronPDF paginates multi-page HTML automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Tables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Namespace Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ABCpdf Namespace&lt;/th&gt;
&lt;th&gt;IronPDF Namespace&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WebSupergoo.ABCpdf13&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core classes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WebSupergoo.ABCpdf13.Objects&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.Editing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Document manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WebSupergoo.ABCpdf13.Atoms&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.Rendering&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Render options, low-level types&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Core Class Mapping
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ABCpdf Class&lt;/th&gt;
&lt;th&gt;IronPDF Class&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Doc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChromePdfRenderer&lt;/code&gt; + &lt;code&gt;PdfDocument&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;ABCpdf combines rendering and document in one object, IronPDF separates them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;XSettings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;IronPdf.License&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Licensing configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;HtmlOptions&lt;/code&gt; / &lt;code&gt;EngineType&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderOptions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML rendering configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Rect&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;RenderingOptions.MarginTop&lt;/code&gt; etc.&lt;/td&gt;
&lt;td&gt;Page area / margin control&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Document Loading Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ABCpdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Load from file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new Doc(); doc.Read("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("file.pdf")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from bytes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.Read(byteArray)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromBinaryData(byteArray)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load from stream&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.Read(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromStream(stream)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load password-protected&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new Doc("file.pdf", "pass")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile("file.pdf", "pass")&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Page Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ABCpdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get page count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigate to page&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;doc.Page = n&lt;/code&gt; (1-based)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[n]&lt;/code&gt; (0-based)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add blank page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.AddPage()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Render HTML with empty content, or copy from template&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.Delete(pageId)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RemovePages(index)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Merge / Split Operations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;ABCpdf&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merge documents&lt;/td&gt;
&lt;td&gt;&lt;code&gt;doc.Append(otherDoc)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge(pdf1, pdf2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract page range&lt;/td&gt;
&lt;td&gt;Manual page copy loop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.CopyPages(startIndex, endIndex)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Four Complete Before/After Migrations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. HTML to PDF
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ABCpdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13.Objects&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfAbcpdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;XSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-ABCPDF-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Doc&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Doc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Engine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EngineType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Chrome123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HtmlOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BrowserWidth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Inset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;
            &amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: Arial; }
                .header { background: #2c3e50; color: white; padding: 20px; }
                table { width: 100%; border-collapse: collapse; }
                td, th { border: 1px solid #ddd; padding: 8px; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;
            &amp;lt;body&amp;gt;
                &amp;lt;div class='header'&amp;gt;&amp;lt;h1&amp;gt;Monthly Report&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;table&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Metric&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Revenue&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$142,000&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Users&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8,421&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/body&amp;gt;
            &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddImageHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"report_abcpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with ABCpdf."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HtmlToPdfIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CssMediaType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfCssMediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Screen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintHtmlBackgrounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// preserve CSS backgrounds&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ViewPortWidth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
            &amp;lt;html&amp;gt;
            &amp;lt;head&amp;gt;&amp;lt;style&amp;gt;
                body { font-family: Arial; }
                .header { background: #2c3e50; color: white; padding: 20px; }
                table { width: 100%; border-collapse: collapse; }
                td, th { border: 1px solid #ddd; padding: 8px; }
            &amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;
            &amp;lt;body&amp;gt;
                &amp;lt;div class='header'&amp;gt;&amp;lt;h1&amp;gt;Monthly Report&amp;lt;/h1&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;table&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Metric&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Revenue&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$142,000&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                    &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Users&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;8,421&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/body&amp;gt;
            &amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"report_ironpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PrintHtmlBackgrounds = true&lt;/code&gt; is what preserves the dark header background you set in CSS. ABCpdf rendered that by default. &lt;code&gt;ViewPortWidth&lt;/code&gt; maps directly to ABCpdf's &lt;code&gt;BrowserWidth&lt;/code&gt;. The &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML-to-PDF tutorial&lt;/a&gt; covers the full rendering options including JavaScript wait conditions and custom headers.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Merge PDFs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ABCpdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeAbcpdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;XSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-ABCPDF-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Doc&lt;/span&gt; &lt;span class="n"&gt;doc1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Doc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Doc&lt;/span&gt; &lt;span class="n"&gt;doc2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Doc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;doc1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// mutates doc1 in place&lt;/span&gt;
        &lt;span class="n"&gt;doc1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged_abcpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged with ABCpdf."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MergeIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part1.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"part2.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Static merge -- returns a new PdfDocument, inputs are unchanged&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdf2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"merged_ironpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Merged with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PdfDocument.Merge()&lt;/code&gt; accepts &lt;code&gt;params PdfDocument[]&lt;/code&gt;, so you can pass any number of documents in one call. The &lt;a href="https://ironpdf.com/examples/merge-pdfs/" rel="noopener noreferrer"&gt;merge and split documentation&lt;/a&gt; has patterns for merging 5+ documents and combining generated PDFs with file-based ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Watermark
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ABCpdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkAbcpdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;XSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-ABCPDF-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Doc&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Doc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Apply text watermark to each page -- manual coordinate loop&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"200 200 200"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// light gray&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Font&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Helvetica"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FontSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CONFIDENTIAL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked_abcpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked with ABCpdf."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WatermarkIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// HTML watermark -- use any CSS, no coordinate math, applies to all pages&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ApplyWatermark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h1 style='color:lightgray;font-size:48px;opacity:0.5;'&amp;gt;CONFIDENTIAL&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;hyperlink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"watermarked_ironpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Watermarked with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coordinate math and per-page loop collapse into a single &lt;code&gt;ApplyWatermark&lt;/code&gt; call. Position control via &lt;code&gt;VerticalAlignment&lt;/code&gt; and &lt;code&gt;HorizontalAlignment&lt;/code&gt; enums in &lt;code&gt;IronPdf.Editing&lt;/code&gt; is covered in the &lt;a href="https://ironpdf.com/how-to/watermark/" rel="noopener noreferrer"&gt;watermark alignment docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Password Protection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ABCpdf):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;WebSupergoo.ABCpdf13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordAbcpdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;XSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InstallLicense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR-ABCPDF-KEY"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Doc&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Doc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encryption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EncryptionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AES128&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encryption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encryption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanPrint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encryption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanCopy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encryption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanEdit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected_abcpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected with ABCpdf."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After (IronPDF):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordIronPdf&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Named properties, no integer flags to look up&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OwnerPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"owner123"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"user456"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserPrinting&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfPrintSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoPrint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserCopyPasteContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SecuritySettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowUserEdits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfEditSecurity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoEdit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"protected_ironpdf.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Protected with IronPDF."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF uses typed enums instead of integer flags. The full &lt;code&gt;SecuritySettings&lt;/code&gt; surface is in the &lt;a href="https://ironpdf.com/how-to/pdf-permissions-passwords/" rel="noopener noreferrer"&gt;PDF permissions and passwords docs&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Critical Migration Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Page Indexing Differences
&lt;/h3&gt;

&lt;p&gt;ABCpdf uses 1-based page numbering (&lt;code&gt;doc.Page = 1&lt;/code&gt; is the first page). IronPDF uses 0-based indexing (&lt;code&gt;pdf.Pages[0]&lt;/code&gt; is the first page). Every loop, every page reference, every index needs adjusting. A quick &lt;code&gt;rg "doc\.Page\s*=" --glob "*.cs"&lt;/code&gt; will find them all.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doc Object vs. Separate Renderer and Document
&lt;/h3&gt;

&lt;p&gt;ABCpdf's &lt;code&gt;Doc&lt;/code&gt; is both the renderer and the document. IronPDF separates these: &lt;code&gt;ChromePdfRenderer&lt;/code&gt; handles creation, &lt;code&gt;PdfDocument&lt;/code&gt; handles the result. If your ABCpdf code passes &lt;code&gt;doc&lt;/code&gt; around for both rendering and manipulation, you will need to refactor call sites to accept the appropriate type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unit Conversion
&lt;/h3&gt;

&lt;p&gt;ABCpdf works in PDF points (1 point = 1/72 inch) with a bottom-left origin. IronPDF margins are specified in millimeters by default. If you have hard-coded coordinate values, convert them: 1 point = 0.353 mm.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disposal Patterns
&lt;/h3&gt;

&lt;p&gt;ABCpdf required an explicit &lt;code&gt;doc.Clear()&lt;/code&gt; to release resources. IronPDF's &lt;code&gt;PdfDocument&lt;/code&gt; is &lt;code&gt;IDisposable&lt;/code&gt;, so a standard &lt;code&gt;using&lt;/code&gt; block handles cleanup. Drop the &lt;code&gt;Clear()&lt;/code&gt; call and wrap with &lt;code&gt;using&lt;/code&gt; when migrating each site.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Renderer Reuse
&lt;/h3&gt;

&lt;p&gt;In ABCpdf, you create a new &lt;code&gt;Doc&lt;/code&gt; per render. In IronPDF, &lt;code&gt;ChromePdfRenderer&lt;/code&gt; is meant to be created once and shared across requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create once, share across all requests&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;ChromePdfRenderer&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt; &lt;span class="nf"&gt;GeneratePdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disposal
&lt;/h3&gt;

&lt;p&gt;Always dispose &lt;code&gt;PdfDocument&lt;/code&gt; instances when done. In high-throughput services, this matters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// pdf is disposed here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For async patterns in concurrent workloads, the &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/" rel="noopener noreferrer"&gt;Microsoft async programming docs&lt;/a&gt; cover &lt;code&gt;Task.WhenAll&lt;/code&gt; and &lt;code&gt;ConfigureAwait(false)&lt;/code&gt; usage that applies when batching PDF generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge Cases Worth Flagging
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large HTML tables (1000+ rows):&lt;/strong&gt; Both libraries handle these, but consider paginating in HTML with &lt;code&gt;page-break-before: always&lt;/code&gt; for predictable output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript-dependent rendering:&lt;/strong&gt; IronPDF's Chrome engine executes JS by default. If your HTML relies on JS to build the DOM, leave &lt;code&gt;renderer.RenderingOptions.EnableJavaScript = true&lt;/code&gt; and consider adding a &lt;code&gt;RenderDelay&lt;/code&gt; if content loads asynchronously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent rendering:&lt;/strong&gt; IronPDF's &lt;code&gt;ChromePdfRenderer&lt;/code&gt; is designed for reuse across requests. For batch jobs, &lt;code&gt;Parallel.ForEach&lt;/code&gt; with the same renderer instance works. ABCpdf typically required explicit &lt;code&gt;Doc&lt;/code&gt;-per-thread isolation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Migration Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Migration (8 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Run &lt;code&gt;rg&lt;/code&gt; scan to inventory all ABCpdf usage across the codebase&lt;/li&gt;
&lt;li&gt;[ ] Catalog which ABCpdf features you actually use (HTML-to-PDF, merge, forms, etc.)&lt;/li&gt;
&lt;li&gt;[ ] Obtain an IronPDF trial key from &lt;a href="https://ironpdf.com/get-started/license-keys/" rel="noopener noreferrer"&gt;ironpdf.com/get-started/license-keys/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Create a migration branch in source control&lt;/li&gt;
&lt;li&gt;[ ] Identify integration tests that exercise PDF generation paths&lt;/li&gt;
&lt;li&gt;[ ] Document any ABCpdf coordinate-based drawing code that needs rethinking&lt;/li&gt;
&lt;li&gt;[ ] Check for ABCpdf license files or registry entries in deployment scripts&lt;/li&gt;
&lt;li&gt;[ ] Review Docker / CI configurations for native runtime package copy steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Migration (10 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Replace NuGet package: remove &lt;code&gt;ABCpdf&lt;/code&gt;, add &lt;code&gt;IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Update all &lt;code&gt;using&lt;/code&gt; directives from &lt;code&gt;WebSupergoo.ABCpdf*&lt;/code&gt; to &lt;code&gt;IronPdf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;XSettings.InstallLicense()&lt;/code&gt; with &lt;code&gt;IronPdf.License.LicenseKey = "..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;Doc&lt;/code&gt; + &lt;code&gt;AddImageHtml&lt;/code&gt; with &lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;Doc.Append()&lt;/code&gt; with &lt;code&gt;PdfDocument.Merge()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Replace coordinate-based watermarks with &lt;code&gt;ApplyWatermark()&lt;/code&gt; HTML&lt;/li&gt;
&lt;li&gt;[ ] Replace encryption integer flags with &lt;code&gt;SecuritySettings&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;[ ] Convert all 1-based page indices to 0-based&lt;/li&gt;
&lt;li&gt;[ ] Convert point-based margins to millimeters&lt;/li&gt;
&lt;li&gt;[ ] Replace &lt;code&gt;doc.Clear()&lt;/code&gt; calls with &lt;code&gt;using&lt;/code&gt; blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing (7 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Run existing PDF output tests and compare visually&lt;/li&gt;
&lt;li&gt;[ ] Verify multi-page HTML renders without manual chaining&lt;/li&gt;
&lt;li&gt;[ ] Test password-protected PDF open/save round-trip&lt;/li&gt;
&lt;li&gt;[ ] Test merge with 3+ documents&lt;/li&gt;
&lt;li&gt;[ ] Validate watermark positioning on single-page and multi-page docs&lt;/li&gt;
&lt;li&gt;[ ] Load-test concurrent rendering in staging&lt;/li&gt;
&lt;li&gt;[ ] Verify Docker/Linux deployment produces identical output&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Post-Migration (4 items)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Remove ABCpdf native runtime packages from deployment artifacts&lt;/li&gt;
&lt;li&gt;[ ] Remove ABCpdf license registry entries or file deployment steps&lt;/li&gt;
&lt;li&gt;[ ] Update project documentation and onboarding guides&lt;/li&gt;
&lt;li&gt;[ ] Monitor production error rates for PDF-related exceptions for two weeks&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The hardest part of this migration is not the API mapping. It is the coordinate-system shift and the engine-version cleanup. If your codebase is mostly HTML-to-PDF with straightforward merge and security, expect a one-to-two day migration for a mid-size project. If you have heavy coordinate-based drawing or accessibility tagging, plan for a phased approach.&lt;/p&gt;

&lt;p&gt;Worth knowing even without IronPDF: pinning an HTML engine to a specific Chromium major (ABCpdf's &lt;code&gt;Chrome117&lt;/code&gt;, &lt;code&gt;Chrome86&lt;/code&gt;, etc.) is a common source of "renders fine in the browser, renders wrong in the PDF" bugs. Any modern HTML-to-PDF library that tracks a single, current Chromium internally eliminates that class of bug entirely.&lt;/p&gt;




&lt;p&gt;Have you hit an edge case migrating from ABCpdf that is not covered here? Maybe around ABCpdf's &lt;code&gt;ContentStreamScanner&lt;/code&gt;, custom atom manipulation, or 3D PDF rendering. Drop it in the comments. Those are the patterns that are hardest to Google and most useful to document.&lt;/p&gt;

&lt;p&gt;The free trial is on &lt;a href="https://www.nuget.org/packages/IronPdf" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt; if you want to test the migration against your actual templates before committing.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>pdf</category>
      <category>ironpdf</category>
    </item>
    <item>
      <title>TuesPechkin vs IronPDF: side by side for .NET teams in 2026</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Mon, 25 May 2026 14:52:00 +0000</pubDate>
      <link>https://dev.to/ironsoftware/tuespechkin-vs-ironpdf-side-by-side-for-net-teams-in-2026-5e6l</link>
      <guid>https://dev.to/ironsoftware/tuespechkin-vs-ironpdf-side-by-side-for-net-teams-in-2026-5e6l</guid>
      <description>&lt;p&gt;&lt;a href="https://ironpdf.com" rel="noopener noreferrer"&gt;IronPDF&lt;/a&gt; is a commercial .NET library using a modern Chromium rendering engine — the same technology powering Chrome and Edge. Rather than wrapping a decade-old WebKit fork, it renders HTML/CSS/JavaScript the way current browsers display content. Install via NuGet (&lt;code&gt;IronPdf&lt;/code&gt;), no separate binary downloads required, and it targets Windows, Linux, macOS, Docker, and Azure.&lt;/p&gt;

&lt;p&gt;The core API centers on &lt;code&gt;ChromePdfRenderer&lt;/code&gt; with methods like &lt;code&gt;RenderHtmlAsPdf()&lt;/code&gt; for strings, &lt;code&gt;RenderUrlAsPdf()&lt;/code&gt; for live sites, and &lt;code&gt;RenderHtmlFileAsPdf()&lt;/code&gt; for local templates. It handles CSS Grid, Flexbox, Web Fonts, SVG, and JavaScript execution out of the box, making it suitable for modern SaaS reporting, invoice systems, and document automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where TuesPechkin Fits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Product Status
&lt;/h3&gt;

&lt;p&gt;TuesPechkin is a .NET wrapper around the wkhtmltopdf native binary, distributed via the &lt;code&gt;TuesPechkin&lt;/code&gt; NuGet package paired with &lt;code&gt;TuesPechkin.Wkhtmltox.Win64&lt;/code&gt; or &lt;code&gt;TuesPechkin.Wkhtmltox.Win32&lt;/code&gt; for the platform-specific binary. The underlying wkhtmltopdf project — built on a WebKit fork from roughly 2015 — has been archived upstream and is no longer receiving active development. Teams adopting it today inherit a dependency chain that predates modern .NET and modern web standards.&lt;/p&gt;

&lt;h3&gt;
  
  
  Capability Gaps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Limited modern CSS&lt;/strong&gt;: CSS Grid and newer Flexbox features can render incorrectly — verify against your version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constrained JavaScript execution&lt;/strong&gt;: Complex SPAs or dynamic content may not render as expected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-async API surface&lt;/strong&gt;: Originally targeted .NET Framework, lacks async/await patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual container setup&lt;/strong&gt;: Native library management is typically required in Docker images&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operational Constraints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resident native binary&lt;/strong&gt;: The wkhtmltox native library stays resident in the host process after conversions, which can matter for long-running web workers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread safety pattern&lt;/strong&gt;: Typically requires a singleton/&lt;code&gt;ThreadSafeConverter&lt;/code&gt; pattern with &lt;code&gt;RemotingToolset&lt;/code&gt; for IIS scenarios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture-specific deployment&lt;/strong&gt;: Separate &lt;code&gt;Win32EmbeddedDeployment&lt;/code&gt; vs &lt;code&gt;Win64EmbeddedDeployment&lt;/code&gt; packages depending on target bitness&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure App Service / serverless&lt;/strong&gt;: Native-binary dependency commonly fails on locked-down PaaS hosts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Support Model
&lt;/h3&gt;

&lt;p&gt;Community-maintained. There is no commercial backing, SLA, or hotfix pipeline; rendering-engine issues typically route to the upstream wkhtmltopdf tracker, which is itself archived.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Notes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;StaticDeployment&lt;/code&gt; pattern requires pre-extracting native DLLs to a specific folder structure before first use. This adds steps to CI/CD pipelines and can introduce race conditions in horizontally scaled environments. The &lt;code&gt;RemotingToolset&lt;/code&gt; abstraction, while solving IIS hosting issues, adds an AppDomain boundary and serialization overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Comparison Overview
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;TuesPechkin&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Current Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wrapper around archived wkhtmltopdf upstream&lt;/td&gt;
&lt;td&gt;Active development, regular updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTML 4/5 partial, circa-2015 CSS&lt;/td&gt;
&lt;td&gt;Full HTML5, CSS3, CSS Grid, Flexbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rendering Engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WebKit fork (circa 2015)&lt;/td&gt;
&lt;td&gt;Chromium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NuGet + native binary package + runtime deps&lt;/td&gt;
&lt;td&gt;Single NuGet package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Community forums&lt;/td&gt;
&lt;td&gt;Commercial support, engineering team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Future Trajectory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Upstream archived&lt;/td&gt;
&lt;td&gt;Chromium-aligned roadmap&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Code Comparison: HTML String Conversion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TuesPechkin — HTML String to PDF
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package TuesPechkin&lt;/span&gt;
&lt;span class="c1"&gt;// NuGet: Install-Package TuesPechkin.Wkhtmltox.Win64&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;TuesPechkin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TuesPechkinExample&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IConverter&lt;/span&gt; &lt;span class="n"&gt;_converter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;TuesPechkinExample&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Pre-create deployment path for the native binary&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;deploymentPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;AppDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"wkhtmltopdf"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deploymentPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Singleton thread-safe converter pattern (common for web apps)&lt;/span&gt;
        &lt;span class="n"&gt;_converter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ThreadSafeConverter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;RemotingToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PdfToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Win64EmbeddedDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StaticDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deploymentPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;GenerateInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HtmlToPdfDocument&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;GlobalSettings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PaperKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Orientation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GlobalSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperOrientation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Portrait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Margins&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MarginSettings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millimeters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;Objects&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectSettings&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;HtmlText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;WebSettings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;LoadImages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Things to note in this pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The converter is typically a static singleton — it is not designed for per-request creation and disposal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Win64EmbeddedDeployment&lt;/code&gt; is bitness-specific; 32-bit apps need the Win32 equivalent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StaticDeployment&lt;/code&gt; requires the folder to exist before first use (worth scripting in CI rather than relying on first-call creation)&lt;/li&gt;
&lt;li&gt;The API is synchronous — there is no async overload, so the call blocks the calling thread&lt;/li&gt;
&lt;li&gt;CSS support reflects the underlying WebKit fork; modern Grid and newer Flexbox features may not render as expected&lt;/li&gt;
&lt;li&gt;The native binary is loaded into the host process and remains resident across calls&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  IronPDF — HTML String to PDF
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IronPdfExample&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;]&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GenerateInvoiceAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Modern CSS rendering settings&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CssMediaType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rendering&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PdfCssMediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Screen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintHtmlBackgrounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF's approach eliminates the static deployment ceremony. The renderer handles native dependencies automatically, works on any CPU architecture, and disposes cleanly. The async pattern prevents thread blocking, making it suitable for high-traffic ASP.NET Core applications. Learn more about &lt;a href="https://ironpdf.com/how-to/html-string-to-pdf/" rel="noopener noreferrer"&gt;HTML string conversion&lt;/a&gt; and the &lt;a href="https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html" rel="noopener noreferrer"&gt;ChromePdfRenderer API&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code Comparison: URL to PDF with Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TuesPechkin — URL Conversion
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package TuesPechkin&lt;/span&gt;
&lt;span class="c1"&gt;// NuGet: Install-Package TuesPechkin.Wkhtmltox.Win64&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;TuesPechkin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TuesPechkinUrlConverter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IConverter&lt;/span&gt; &lt;span class="n"&gt;_converter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TuesPechkinUrlConverter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;deploymentPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;AppDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"wkhtmltopdf"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deploymentPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;_converter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ThreadSafeConverter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;RemotingToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PdfToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Win64EmbeddedDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StaticDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deploymentPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConvertUrlToPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HtmlToPdfDocument&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;GlobalSettings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PaperKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Orientation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GlobalSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperOrientation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Portrait&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;Objects&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectSettings&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;PageUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;WebSettings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;LoadImages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="c1"&gt;// Basic HTTP auth surface only&lt;/span&gt;
                        &lt;span class="n"&gt;UserStyleSheet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"print.css"&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pdfBytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteAllBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdfBytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Things to note in this pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication surface is limited to basic HTTP auth — there is no first-class bearer token or OAuth flow&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UserStyleSheet&lt;/code&gt; paths are resolved against the deployment, which can be fragile in container environments — verify paths against your runtime layout&lt;/li&gt;
&lt;li&gt;JavaScript-heavy pages (SPAs) may not render fully under the WebKit fork&lt;/li&gt;
&lt;li&gt;Custom request headers and programmatic cookies are not part of the URL-loading API&lt;/li&gt;
&lt;li&gt;Modern TLS handshakes can fail with HTTPS hosts depending on the bundled binary version&lt;/li&gt;
&lt;li&gt;There is no first-class timeout knob on the URL fetch path&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  IronPDF — URL to PDF with Modern Auth
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IronPdfUrlConverter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;]&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ConvertAuthenticatedUrlAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;bearerToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Cookie-based credential passthrough&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoginCredentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomCookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AuthToken"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bearerToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// seconds&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitFor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderDelay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Wait for JS&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderUrlAsPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF handles modern authentication patterns, sets explicit timeouts, and waits for JavaScript execution. The async API prevents blocking in web contexts, and resource disposal is automatic. See the &lt;a href="https://ironpdf.com/how-to/ironpdf-2021-chrome-rendering-engine-eap/" rel="noopener noreferrer"&gt;Chrome rendering engine guide&lt;/a&gt; for advanced scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code Comparison: Complex Layout with Images
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TuesPechkin — Layout Rendering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package TuesPechkin&lt;/span&gt;
&lt;span class="c1"&gt;// NuGet: Install-Package TuesPechkin.Wkhtmltox.Win64&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;TuesPechkin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TuesPechkinLayoutRenderer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IConverter&lt;/span&gt; &lt;span class="n"&gt;_converter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TuesPechkinLayoutRenderer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;AppDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"wkhtmltopdf"&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;_converter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ThreadSafeConverter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;RemotingToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PdfToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Win64EmbeddedDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StaticDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;RenderDashboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;htmlWithGrid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HtmlToPdfDocument&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;GlobalSettings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;PaperSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PaperKind&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Orientation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GlobalSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperOrientation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Landscape&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Margins&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MarginSettings&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Unit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Millimeters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Bottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Right&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;Objects&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ObjectSettings&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;HtmlText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htmlWithGrid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;WebSettings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;LoadImages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;PrintMediaType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// Use print CSS&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="c1"&gt;// No first-class viewport setting on this API&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Things to note in this pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CSS Grid is not part of the underlying engine's spec coverage — Grid layouts typically need fallback markup&lt;/li&gt;
&lt;li&gt;Flexbox is partially supported; &lt;code&gt;flex-wrap&lt;/code&gt; and newer features may not match modern browsers — verify against your version&lt;/li&gt;
&lt;li&gt;Web Fonts loaded from external CDNs can fail depending on the binary's TLS support&lt;/li&gt;
&lt;li&gt;SVG support is limited compared to a current Chromium engine&lt;/li&gt;
&lt;li&gt;Base64-encoded images may render inconsistently depending on the binary version&lt;/li&gt;
&lt;li&gt;There is no built-in viewport-width knob for responsive layouts&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  IronPDF — Modern Layout Rendering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf.Rendering&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IronPdfLayoutRenderer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;]&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;RenderDashboardAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;htmlWithGrid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Modern layout support&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperOrientation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; 
            &lt;span class="n"&gt;PdfPaperOrientation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Landscape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginTop&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarginBottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CssMediaType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfCssMediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Screen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrintHtmlBackgrounds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Responsive viewport for mobile-first designs&lt;/span&gt;
        &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RenderingOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PaperFit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseResponsiveCssRendering&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1280&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdfAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;htmlWithGrid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BinaryData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF's Chromium engine natively supports CSS Grid, Flexbox, Web Fonts, SVG, and Canvas elements. The &lt;code&gt;UseResponsiveCssRendering&lt;/code&gt; method allows viewport control for mobile-first layouts. &lt;a href="https://ironpdf.com/how-to/pixel-perfect-html-to-pdf/" rel="noopener noreferrer"&gt;Pixel-perfect rendering documentation&lt;/a&gt; explains advanced customization.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TuesPechkin Concept&lt;/th&gt;
&lt;th&gt;IronPDF Equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HtmlToPdfDocument&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ObjectSettings.PageUrl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderUrlAsPdf()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ObjectSettings.HtmlText&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass string to &lt;code&gt;RenderHtmlAsPdf()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GlobalSettings.PaperSize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RenderingOptions.PaperSize&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GlobalSettings.Orientation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RenderingOptions.PaperOrientation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MarginSettings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RenderingOptions.MarginTop/Bottom/Left/Right&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;WebSettings.LoadImages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enabled by default, no explicit flag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ThreadSafeConverter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Renderer is thread-safe by design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;StaticDeployment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Automatic native dependency management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RemotingToolset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not required—no IIS special handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Convert()&lt;/code&gt; method&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;RenderHtmlAsPdf()&lt;/code&gt; / &lt;code&gt;RenderUrlAsPdf()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfToolset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abstracted—no manual toolset selection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Header/Footer APIs&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;RenderingOptions.TextHeader&lt;/code&gt; / &lt;code&gt;TextFooter&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Comprehensive Feature Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature Category&lt;/th&gt;
&lt;th&gt;TuesPechkin&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status &amp;amp; Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active Development&lt;/td&gt;
&lt;td&gt;Wrapper around archived wkhtmltopdf&lt;/td&gt;
&lt;td&gt;Yes (regular releases)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commercial Support&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes — engineering team + SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Patches&lt;/td&gt;
&lt;td&gt;Depends on upstream&lt;/td&gt;
&lt;td&gt;Regular product updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.NET 9 Support&lt;/td&gt;
&lt;td&gt;Not first-class&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LTS Commitment&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Multi-year roadmap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content Creation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML5 Support&lt;/td&gt;
&lt;td&gt;Partial (circa-2015 WebKit fork)&lt;/td&gt;
&lt;td&gt;Full (Chromium)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS3 Features&lt;/td&gt;
&lt;td&gt;Limited spec coverage&lt;/td&gt;
&lt;td&gt;Grid, Flexbox, Variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript Execution&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Chrome V8 engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Fonts&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Full support (Google Fonts, custom)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SVG Rendering&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Chromium-grade SVG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responsive Layouts&lt;/td&gt;
&lt;td&gt;No viewport API&lt;/td&gt;
&lt;td&gt;UseResponsiveCssRendering()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PDF Operations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL to PDF&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Async API&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Built-in &lt;code&gt;PdfDocument.Merge()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split PDFs&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes — PdfDocument operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add Watermarks&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes — text and image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Digital Signatures&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes — X.509 certificates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form Creation&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CreatePdfFormsFromHtml = true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract Text&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes — &lt;code&gt;PdfDocument.ExtractAllText()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password Protection&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes — AES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certificate Encryption&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permissions (Print/Copy)&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes — granular control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redaction&lt;/td&gt;
&lt;td&gt;Out of scope&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native Binary Residency&lt;/td&gt;
&lt;td&gt;Loaded into host process&lt;/td&gt;
&lt;td&gt;Managed internally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread Safety&lt;/td&gt;
&lt;td&gt;Singleton + &lt;code&gt;ThreadSafeConverter&lt;/code&gt; pattern&lt;/td&gt;
&lt;td&gt;Thread-safe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container Deployment&lt;/td&gt;
&lt;td&gt;Manual native-binary extraction&lt;/td&gt;
&lt;td&gt;Works out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure App Service&lt;/td&gt;
&lt;td&gt;Typically not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux Compatibility&lt;/td&gt;
&lt;td&gt;Native binary only&lt;/td&gt;
&lt;td&gt;Yes (.NET Core / 5+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;macOS Support&lt;/td&gt;
&lt;td&gt;Native binary only&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NuGet Install&lt;/td&gt;
&lt;td&gt;2 packages + native runtime deps&lt;/td&gt;
&lt;td&gt;Single package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Surface&lt;/td&gt;
&lt;td&gt;Deployment ceremony required&lt;/td&gt;
&lt;td&gt;Typically 3–5 lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging&lt;/td&gt;
&lt;td&gt;Limited error messages&lt;/td&gt;
&lt;td&gt;Detailed exceptions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Samples&lt;/td&gt;
&lt;td&gt;Community-curated&lt;/td&gt;
&lt;td&gt;Extensive docs + examples&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Patterns Teams Hit When Migrating
&lt;/h2&gt;

&lt;p&gt;When teams move off TuesPechkin, these patterns commonly come up — verify each against your version and target environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;CSS Grid layouts&lt;/strong&gt;: The underlying engine predates the Grid spec; layouts using Grid typically need fallback markup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native binary stays resident&lt;/strong&gt;: The wkhtmltox library is loaded into the host process and stays loaded across calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern TLS/HTTPS&lt;/strong&gt;: Older bundled binaries can struggle with current TLS handshakes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript-heavy pages&lt;/strong&gt;: SPAs and dynamic dashboards may not render fully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker images&lt;/strong&gt;: Containers typically need explicit native-binary extraction and runtime deps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure App Service / locked-down PaaS&lt;/strong&gt;: Native-binary dependencies commonly fail in these environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bitness selection&lt;/strong&gt;: 32-bit vs 64-bit requires the matching &lt;code&gt;TuesPechkin.Wkhtmltox.Win32&lt;/code&gt; / &lt;code&gt;Win64&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Fonts from CDNs&lt;/strong&gt;: Loading from external CDNs can fail depending on the binary's TLS support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SVG rendering&lt;/strong&gt;: SVG coverage is narrower than current browsers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous API&lt;/strong&gt;: There is no async overload; calls block the calling thread&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Installation Comparison
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TuesPechkin:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Install-Package TuesPechkin
Install-Package TuesPechkin.Wkhtmltox.Win64  &lt;span class="c"&gt;# or .Win32 for 32-bit&lt;/span&gt;
&lt;span class="c"&gt;# Plus the matching Visual C++ runtime on the host&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;TuesPechkin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Static initialization before first use&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;deployPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentDomain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wkhtmltopdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deployPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ThreadSafeConverter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;RemotingToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PdfToolset&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Win64EmbeddedDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StaticDeployment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deployPath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IronPDF:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Install-Package IronPdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;TuesPechkin solved a real problem in the .NET Framework era — it gave .NET teams a clean managed surface over wkhtmltopdf. For teams maintaining legacy applications with simple layout needs and no budget for commercial tools, it can still do the job, with the caveat that the underlying wkhtmltopdf project is archived upstream and not receiving further development.&lt;/p&gt;

&lt;p&gt;Migration tends to come up when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your CSS uses Grid, newer Flexbox, or CSS Variables&lt;/li&gt;
&lt;li&gt;You deploy to Docker, Azure App Service, or Linux containers&lt;/li&gt;
&lt;li&gt;Long-running web workers care about native-binary residency&lt;/li&gt;
&lt;li&gt;You need async patterns for scalable web apps&lt;/li&gt;
&lt;li&gt;JavaScript-heavy content (SPAs, charts) needs to render the way browsers render it today&lt;/li&gt;
&lt;li&gt;You want ongoing patch management from a vendor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IronPDF approaches the problem differently: a current Chromium engine, native dependencies handled internally, and a .NET-idiomatic API. The trade-off is a commercial license in exchange for less deployment ceremony and rendering that tracks current browsers. For teams where rendering fidelity and maintenance burden are real concerns, that trade-off often pays back inside the first sprint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is your experience with wkhtmltopdf-based tools in modern .NET projects?&lt;/strong&gt; Any gotchas or workarounds worth sharing?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ironpdf.com/how-to/html-string-to-pdf/" rel="noopener noreferrer"&gt;IronPDF HTML String to PDF Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html/" rel="noopener noreferrer"&gt;ChromePdfRenderer API Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Scryber.Core vs IronPDF: side by side for .NET teams</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Mon, 25 May 2026 14:50:00 +0000</pubDate>
      <link>https://dev.to/ironsoftware/scrybercore-vs-ironpdf-side-by-side-for-net-teams-30ah</link>
      <guid>https://dev.to/ironsoftware/scrybercore-vs-ironpdf-side-by-side-for-net-teams-30ah</guid>
      <description>&lt;p&gt;Picture this: a flexbox layout that previews cleanly in the browser but breaks pagination once it hits the PDF renderer, and the docs say only "CSS support is partial." The root cause is usually the same — the PDF library uses a custom CSS pipeline rather than a browser engine, and a spec feature you depended on simply is not implemented.&lt;/p&gt;

&lt;p&gt;Scryber.Core is an open-source, template-driven PDF library for .NET that emphasizes programmatic document layout and data binding with a Handlebars-style template syntax. It is built entirely in C# with no browser dependency, which makes it portable and lightweight. The trade-off is that its XHTML/CSS support depends on the maintainer implementing each spec feature manually. If you are reaching for Scryber, this comparison aims to help you decide when its approach fits, and when a Chromium-based renderer would save troubleshooting time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding IronPDF
&lt;/h2&gt;

&lt;p&gt;IronPDF uses Google Chrome's rendering engine (Chromium/Blink) to generate PDFs, which means it supports whatever Chrome supports: CSS Grid, Flexbox, CSS variables, web fonts, SVG, and JavaScript. When you call &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;&lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf()&lt;/code&gt;&lt;/a&gt;, your HTML renders the way it would in Chrome's "Print to PDF" feature. If a CSS property works in Chrome DevTools, it typically works in the PDF.&lt;/p&gt;

&lt;p&gt;The trade-off is footprint: IronPDF bundles the Chromium engine, which is substantially larger than Scryber's pure-C# package. For teams that value "write HTML once, render everywhere" over minimal package size, that is usually an acceptable trade. IronPDF targets .NET 10, 9, 8, 7, 6, .NET Core, and .NET Framework, and runs on Windows, Linux, macOS, Docker, and major cloud platforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Characteristics of Scryber.Core
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Product Status
&lt;/h3&gt;

&lt;p&gt;Open-source project under LGPL-3.0; commercial use is permitted, but modifications to Scryber itself must be shared under LGPL. Active maintainer (&lt;code&gt;richard-scryber&lt;/code&gt;) on GitHub. The library has steady releases — current version is 9.x. Community support runs through GitHub issues; there is no dedicated commercial support team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering Capabilities
&lt;/h3&gt;

&lt;p&gt;Scryber implements a custom XHTML/CSS layout engine rather than embedding a browser engine, so support for modern web standards is whatever the maintainer has implemented. CSS Grid is not part of the supported layout model — verify against the latest docs before relying on it. Complex CSS selectors (&lt;code&gt;:nth-of-type&lt;/code&gt;, advanced attribute selectors, less-common pseudo-elements) have partial support. JavaScript execution is not supported — any dynamic content must be pre-rendered server-side. Web fonts work via &lt;code&gt;@font-face&lt;/code&gt; but may need explicit configuration. SVG is supported; CSS animations and some advanced transforms typically are not.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout and Pagination
&lt;/h3&gt;

&lt;p&gt;The layout engine uses Scryber's own flow logic rather than a browser layout algorithm, which can lead to subtle differences from a browser preview. Page size and margins are declared via CSS &lt;code&gt;@page&lt;/code&gt; in the template, which is Scryber's idiom for paged-media layout. Remote images are fetched synchronously at render time. Table rendering and font-metrics calculation may differ from a browser, so dense or complex layouts can need tuning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Support Status
&lt;/h3&gt;

&lt;p&gt;Community-driven support via GitHub issues; response time depends on maintainer availability. Documentation covers basic scenarios thoroughly but is thinner on edge-case troubleshooting. No SLA or hotfix guarantees. Commercial projects need to factor in LGPL compliance — linking is permitted, but modifications to Scryber itself must be published.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Notes
&lt;/h3&gt;

&lt;p&gt;Template syntax mixes XHTML with Handlebars-style binding (&lt;code&gt;{{variable}}&lt;/code&gt;), backed by Scryber's own expression engine — not standard JavaScript/Razor. Data binding happens at render time via &lt;code&gt;doc.Params&lt;/code&gt;; there is no strongly-typed model binding equivalent to MVC Razor. Performance can scale with document complexity, since the layout engine is single-threaded. Debugging layout differences requires understanding Scryber's box model rather than browser DevTools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Comparison Overview
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Scryber.Core&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Current Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Active open-source (single maintainer)&lt;/td&gt;
&lt;td&gt;Commercial, active development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;XHTML + CSS subset&lt;/td&gt;
&lt;td&gt;Full HTML5 / CSS3 / JavaScript (Chromium)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rendering Engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom layout engine&lt;/td&gt;
&lt;td&gt;Chromium-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single NuGet (smaller footprint)&lt;/td&gt;
&lt;td&gt;Single NuGet (Chromium bundled)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub issues (community)&lt;/td&gt;
&lt;td&gt;Commercial engineering support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Licensing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LGPL-3.0&lt;/td&gt;
&lt;td&gt;Commercial license&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Code Comparison: Common Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scryber.Core — Rendering HTML with Data Binding
&lt;/h3&gt;

&lt;p&gt;Scryber's approach uses XHTML templates with Handlebars-style binding. Here is an invoice with a line-items list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package Scryber.Core&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Scryber.Components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScryberInvoiceGenerator&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GenerateInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// XHTML template with Scryber {{ }} binding&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;templateHtml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
&amp;lt;html xmlns='http://www.w3.org/1999/xhtml'&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Invoice {{invoiceNumber}}&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        @page { size: A4 portrait; margin: 20pt; }
        body { font-family: Arial, sans-serif; margin: 20px; }
        .invoice-header { display: block; }
        table { width: 100%; border-collapse: collapse; }
        td, th { border: 1px solid #ddd; padding: 8px; }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class='invoice-header'&amp;gt;
        &amp;lt;h1&amp;gt;Invoice #{{invoiceNumber}}&amp;lt;/h1&amp;gt;
        &amp;lt;p&amp;gt;Date: {{invoiceDate}}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;table&amp;gt;
        &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Item&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Quantity&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;
            &amp;lt;template data-bind='{{#each items}}'&amp;gt;
                &amp;lt;tr&amp;gt;
                    &amp;lt;td&amp;gt;{{name}}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;{{quantity}}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;${{price}}&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
            &amp;lt;/template&amp;gt;
        &amp;lt;/tbody&amp;gt;
    &amp;lt;/table&amp;gt;

    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Total: ${{total}}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;FetchInvoiceData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;templateHtml&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ParseSourceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DynamicContent&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Bind data via Params dictionary&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"invoiceNumber"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvoiceNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"invoiceDate"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"yyyy-MM-dd"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Total&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"items"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;
            &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAsPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;InvoiceData&lt;/span&gt; &lt;span class="nf"&gt;FetchInvoiceData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Implementation details...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvoiceData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvoiceData&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;InvoiceNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Total&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LineItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ItemName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Quantity&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;decimal&lt;/span&gt; &lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Things to know when working with Scryber:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;XHTML strictness&lt;/strong&gt;: Templates must be well-formed XHTML. Most real-world HTML needs to be cleaned up before Scryber will parse it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In-memory templates&lt;/strong&gt;: &lt;code&gt;Document.ParseDocument(reader, "", ParseSourceType.DynamicContent)&lt;/code&gt; accepts a &lt;code&gt;TextReader&lt;/code&gt;, so you can render directly from a string without writing to disk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data binding syntax&lt;/strong&gt;: The &lt;code&gt;{{#each}}&lt;/code&gt; and &lt;code&gt;&amp;lt;template data-bind=...&amp;gt;&lt;/code&gt; constructs require a specific object shape. If your model does not match, project it to anonymous types first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS scope&lt;/strong&gt;: Modern layout features such as CSS Grid are not part of Scryber's supported subset; verify Flexbox behavior against your version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page geometry&lt;/strong&gt;: Page size and margins live in CSS &lt;code&gt;@page&lt;/code&gt;, which is the documented Scryber idiom.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No JavaScript&lt;/strong&gt;: Any client-side logic must be pre-computed server-side before binding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonts&lt;/strong&gt;: &lt;code&gt;@font-face&lt;/code&gt; is supported but may need explicit paths or embedded data; metrics can differ slightly from a browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IronPDF — Rendering HTML with Data Binding
&lt;/h3&gt;

&lt;p&gt;IronPDF accepts HTML strings, files, or URLs directly. No template file requirement, no special binding syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GenerateInvoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;FetchInvoiceData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;invoiceHtml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$@"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;style&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        body &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sans&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        .invoice-header &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
            &lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;justify&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        table &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;%;&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;collapse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;collapse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        td, th &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt; &lt;span class="n"&gt;solid&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="n"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;/style&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;div class='invoice-header'&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;h1&amp;gt;Invoice #&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvoiceNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;p&amp;gt;Date: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;yyyy&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;MM&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;table&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;thead&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;            &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Item&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Quantity&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Price&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;/thead&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;tbody&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;$@"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;            &amp;lt;tr&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;                &amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;                &amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;                &amp;lt;td&amp;gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;F2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;            &amp;lt;/tr&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;        &amp;lt;/tbody&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;/table&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="s"&gt;    &amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Total: $&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;invoiceData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;F2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invoiceHtml&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Learn more about &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;HTML to PDF conversion&lt;/a&gt; and &lt;a href="https://ironpdf.com/how-to/html-file-to-pdf/" rel="noopener noreferrer"&gt;handling HTML files&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IronPDF characteristics worth noting:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML renders through Chromium, so a browser preview is a reliable proxy for the PDF output.&lt;/li&gt;
&lt;li&gt;Work with HTML strings, files, or URLs directly — no template-file I/O required.&lt;/li&gt;
&lt;li&gt;CSS Grid, Flexbox, and modern layout features are supported through the Chromium engine.&lt;/li&gt;
&lt;li&gt;JavaScript executes before PDF generation when enabled (see the &lt;a href="https://ironpdf.com/examples/javascript-html-to-pdf/" rel="noopener noreferrer"&gt;JavaScript support guide&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scryber.Core — Handling Modern CSS
&lt;/h3&gt;

&lt;p&gt;Scryber's CSS support covers a documented subset; for features outside that subset you typically fall back to traditional layout primitives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package Scryber.Core&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Scryber.Components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RenderComplexLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;templateHtml&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
&amp;lt;html xmlns='http://www.w3.org/1999/xhtml'&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
        @page { size: A4 portrait; margin: 20pt; }

        :root {
            --primary-color: #3498db;
            --spacing: 20px;
        }

        body {
            font-family: 'Segoe UI', Tahoma, sans-serif;
            margin: var(--spacing);
            color: #333;
        }

        /* CSS Grid is not part of Scryber's supported layout model */
        .grid-container { display: block; }

        /* Flexbox: basic support; complex justify/wrap combinations may need testing */
        .flex-container { display: flex; }

        /* Traditional two-column layout via floats works reliably */
        .two-column { width: 100%; }
        .two-column .column {
            float: left;
            width: 48%;
            margin-right: 2%;
        }

        .table-striped tr:nth-child(even) {
            background-color: #f2f2f2;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1 style='color: var(--primary-color);'&amp;gt;Layout Sample&amp;lt;/h1&amp;gt;

    &amp;lt;table style='width: 100%;'&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td style='width: 50%; vertical-align: top;'&amp;gt;&amp;lt;p&amp;gt;Column 1 content&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;
            &amp;lt;td style='width: 50%; vertical-align: top;'&amp;gt;&amp;lt;p&amp;gt;Column 2 content&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;templateHtml&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ParseDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ParseSourceType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DynamicContent&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAsPDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scryber CSS checklist:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Preview in the browser first, then verify Scryber renders the same layout.&lt;/li&gt;
&lt;li&gt;Test CSS features in isolation before combining them in production templates.&lt;/li&gt;
&lt;li&gt;For complex multi-column or card-grid designs, traditional layouts (tables, floats) are typically more predictable than Grid.&lt;/li&gt;
&lt;li&gt;Check the project's GitHub issues for any documented limitations relevant to your CSS.&lt;/li&gt;
&lt;li&gt;Expect some differences from CSS Paged Media — page geometry is set via &lt;code&gt;@page&lt;/code&gt; in CSS, which is Scryber's documented idiom.&lt;/li&gt;
&lt;li&gt;Verify fonts load as expected; silent fallback can happen if a font cannot be resolved.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  IronPDF — Rendering Modern CSS
&lt;/h3&gt;

&lt;p&gt;IronPDF renders through Chromium, so modern CSS generally works as it does in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RenderComplexLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
        :root {
            --primary-color: #3498db;
            --spacing: 20px;
        }

        body {
            font-family: 'Segoe UI', Tahoma, sans-serif;
            margin: var(--spacing);
        }

        .grid-container {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: var(--spacing);
        }

        .flex-container {
            display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
            align-items: center;
        }

        .grid-item:nth-child(3n) {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }

        .card::before {
            content: '\2192';
            margin-right: 10px;
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1 style='color: var(--primary-color);'&amp;gt;Layout Sample&amp;lt;/h1&amp;gt;

    &amp;lt;div class='grid-container'&amp;gt;
        &amp;lt;div class='card'&amp;gt;Item 1&amp;lt;/div&amp;gt;
        &amp;lt;div class='card'&amp;gt;Item 2&amp;lt;/div&amp;gt;
        &amp;lt;div class='card'&amp;gt;Item 3&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class='flex-container'&amp;gt;
        &amp;lt;p&amp;gt;Flex Item 1&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;Flex Item 2&amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;Flex Item 3&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Preview in Chrome DevTools, get the same PDF output.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scryber.Core API&lt;/th&gt;
&lt;th&gt;IronPDF Equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Document.ParseDocument(reader, "", ParseSourceType.DynamicContent)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf(html)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Document.ParseDocument(path)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderHtmlFileAsPdf(path)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;doc.Params[key] = value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String interpolation or Razor templates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;{{variable}}&lt;/code&gt; syntax&lt;/td&gt;
&lt;td&gt;C# string interpolation &lt;code&gt;{variable}&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;{{#each collection}}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;LINQ &lt;code&gt;.Select()&lt;/code&gt; + &lt;code&gt;string.Join()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;doc.SaveAsPDF(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.SaveAs(path)&lt;/code&gt; or &lt;code&gt;pdf.BinaryData&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;@page&lt;/code&gt; CSS in template&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ChromePdfRenderer.RenderingOptions&lt;/code&gt; (paper size, margins)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;doc.RenderOptions.Compression&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderingOptions&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;doc.Info.Title&lt;/code&gt; / &lt;code&gt;doc.Info.Author&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.MetaData.Title&lt;/code&gt; / &lt;code&gt;pdf.MetaData.Author&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom font embedding&lt;/td&gt;
&lt;td&gt;CSS &lt;code&gt;@font-face&lt;/code&gt; (Chromium font handling)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Comprehensive Feature Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Scryber.Core&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Active development&lt;/td&gt;
&lt;td&gt;Yes (single maintainer)&lt;/td&gt;
&lt;td&gt;Yes (commercial team)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;.NET 10 support&lt;/td&gt;
&lt;td&gt;.NET Standard 2.0/2.1, .NET 8/9&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;Yes (LGPL-3.0)&lt;/td&gt;
&lt;td&gt;No (commercial)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Read-the-docs site + samples&lt;/td&gt;
&lt;td&gt;Comprehensive with troubleshooting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Community channel&lt;/td&gt;
&lt;td&gt;GitHub issues&lt;/td&gt;
&lt;td&gt;Commercial engineering support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;SLA availability&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (support plans)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content Creation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTML templates&lt;/td&gt;
&lt;td&gt;XHTML with Scryber binding&lt;/td&gt;
&lt;td&gt;Standard HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;CSS3 support&lt;/td&gt;
&lt;td&gt;Subset&lt;/td&gt;
&lt;td&gt;Full (Chromium)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;CSS Grid&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Flexbox&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;JavaScript execution&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Modern selectors&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PDF Operations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Split PDFs&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Watermarks&lt;/td&gt;
&lt;td&gt;Overlay HTML in template&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ApplyStamp&lt;/code&gt; / &lt;code&gt;ApplyWatermark&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;td&gt;Not part of public API&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;Not part of public API&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Permissions&lt;/td&gt;
&lt;td&gt;Not part of public API&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Differences&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CSS Grid rendering&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Flexbox&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Font metrics&lt;/td&gt;
&lt;td&gt;Custom engine&lt;/td&gt;
&lt;td&gt;Chromium metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;JavaScript support&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Input strictness&lt;/td&gt;
&lt;td&gt;Well-formed XHTML required&lt;/td&gt;
&lt;td&gt;Real-world HTML accepted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Learning curve&lt;/td&gt;
&lt;td&gt;Scryber template syntax&lt;/td&gt;
&lt;td&gt;Standard HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Debugging tools&lt;/td&gt;
&lt;td&gt;Custom engine&lt;/td&gt;
&lt;td&gt;Chrome DevTools as preview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Performance (large docs)&lt;/td&gt;
&lt;td&gt;Single-threaded layout&lt;/td&gt;
&lt;td&gt;Optimized Chromium pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Installation Comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scryber.Core Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install base package&lt;/span&gt;
dotnet add package Scryber.Core

&lt;span class="c"&gt;# Namespace imports&lt;/span&gt;
&lt;span class="c"&gt;# using Scryber.Components;   // Document, Page, etc.&lt;/span&gt;
&lt;span class="c"&gt;# using Scryber.Drawing;      // Units, colors&lt;/span&gt;
&lt;span class="c"&gt;# using Scryber.PDF;          // RenderOptions / OutputCompressionType&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pure-C# install, no native dependencies. Templates can be supplied as files on disk or directly from a &lt;code&gt;TextReader&lt;/code&gt; / &lt;code&gt;StringReader&lt;/code&gt; in memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  IronPDF Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Single package with bundled Chromium&lt;/span&gt;
dotnet add package IronPdf

&lt;span class="c"&gt;# Namespace import&lt;/span&gt;
&lt;span class="c"&gt;# using IronPdf;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Larger package because Chromium ships with it. Accepts HTML strings, files, or URLs without template files.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Scryber.Core Makes Sense
&lt;/h2&gt;

&lt;p&gt;Scryber.Core fits scenarios where its trade-offs align with project constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lightweight footprint priorities&lt;/strong&gt;: If package size matters more than full CSS compatibility — embedded systems, IoT devices, or environments with strict size limits — Scryber's pure-C# footprint is noticeably smaller than a Chromium-bundled renderer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Template-driven workflows&lt;/strong&gt;: Teams already comfortable with XHTML templates and Handlebars-style binding may find Scryber's syntax a natural fit. If your architecture separates presentation (templates) from logic and you do not need modern CSS layout, Scryber works well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LGPL-compatible projects&lt;/strong&gt;: Open-source projects under LGPL-3.0 or compatible licenses can use Scryber without licensing costs. Commercial projects can link to Scryber under LGPL terms (your application code does not need to be open-sourced; modifications to Scryber itself do).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple document layouts&lt;/strong&gt;: Reports with tables, text, and images — no responsive web-style layouts — render reliably in Scryber. If your PDF templates look more like "formatted Word documents" than "web pages," Scryber's limitations rarely surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  When IronPDF is the Better Choice
&lt;/h2&gt;

&lt;p&gt;For most modern .NET teams, IronPDF's architecture aligns with current web-tooling practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome DevTools as your preview&lt;/strong&gt;: If your workflow is "design in browser, export to PDF," IronPDF's Chromium-based rendering removes most of the "looks good in browser, breaks in PDF" gap. Teams using modern CSS (Grid, Flexbox, transforms, animations) avoid working around partial-support questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript-dependent content&lt;/strong&gt;: Anything that depends on JavaScript execution — charts rendered by Chart.js, dynamic forms with validation, content loaded via AJAX — needs a JavaScript-capable renderer. Scryber does not execute JS; IronPDF does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support and SLA requirements&lt;/strong&gt;: Enterprise teams needing guaranteed response times typically need more than community GitHub issues. IronPDF provides commercial support with SLAs available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rapid iteration&lt;/strong&gt;: When CSS does not render as expected, Chrome DevTools let you inspect and adjust the page interactively, then re-render. Scryber's custom engine does not have a comparable inspector, so iteration is more of a guess-and-check loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Scryber.Core is a thoughtful open-source PDF library that prioritizes a lightweight footprint and template-driven generation. For simple documents and teams comfortable working inside its XHTML/CSS subset, it is a viable choice. Its custom rendering engine does mean you cannot rely on browser previews matching PDF output one-to-one, which can slow down troubleshooting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;IronPDF's Chromium-based approach&lt;/a&gt; narrows that gap. HTML renders similarly in browser and PDF. Modern CSS features work without checking documentation for partial support. JavaScript executes when needed. The trade-off is package size, which most teams accept for development velocity and rendering predictability.&lt;/p&gt;

&lt;p&gt;For teams building new PDF workflows today, the question is: do you optimize for package size (Scryber) or development speed (IronPDF)? Most teams choose speed once they have spent enough time debugging layout differences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What CSS feature has caused you the most PDF rendering headaches?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Additional IronPDF resources: &lt;a href="https://ironpdf.com/examples/javascript-html-to-pdf/" rel="noopener noreferrer"&gt;JavaScript in HTML to PDF&lt;/a&gt;, &lt;a href="https://ironpdf.com/how-to/html-file-to-pdf/" rel="noopener noreferrer"&gt;HTML file rendering guide&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>PDFium vs IronPDF: the decision guide for .NET teams</title>
      <dc:creator>IronSoftware</dc:creator>
      <pubDate>Mon, 25 May 2026 12:49:00 +0000</pubDate>
      <link>https://dev.to/ironsoftware/pdfium-vs-ironpdf-the-decision-guide-for-net-teams-2f3e</link>
      <guid>https://dev.to/ironsoftware/pdfium-vs-ironpdf-the-decision-guide-for-net-teams-2f3e</guid>
      <description>&lt;p&gt;A .NET team needs PDF thumbnails for a document portal, reaches for a PDFium-based wrapper, and ships locally in an hour. Then the deployment to a Linux container surfaces a "Unable to load DLL 'pdfium.dll'" — and a few hours later, the team also realises the wrapper renders pages but cannot fill the AcroForm fields the next user story depends on. That gap — rendering engine vs. full PDF toolkit — is the real story when comparing PDFium with IronPDF.&lt;/p&gt;

&lt;p&gt;PDFium is Google's open-source C++ PDF library, the same engine that ships inside Chromium and Android, released under BSD-3-Clause. There is no official Google-supplied .NET binding. The .NET ecosystem ships several community wrappers around the native engine, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PdfiumViewer&lt;/code&gt; (Apache 2.0; archived August 2019, last NuGet release 2.13.0 in November 2017)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PdfiumViewer.Updated&lt;/code&gt; (maintained community fork targeting .NET Core / .NET 6)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PDFiumCore&lt;/code&gt; (Dtronix, .NET Standard 2.1 P/Invoke bindings)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Pdfium.Net.SDK&lt;/code&gt; (Patagames, commercial)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The wrappers differ in API surface, platform support, and maintenance cadence, but they share one trait: PDFium itself is a rendering and parsing engine, not an HTML-to-PDF or document-authoring engine. None of the wrappers can convert HTML to PDF on their own, because PDFium has no HTML parser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding IronPDF
&lt;/h2&gt;

&lt;p&gt;IronPDF is a commercial PDF generation and manipulation library built on a Chromium rendering engine. The core use case is &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;creating PDFs from HTML&lt;/a&gt;, URLs, or other content with rendering aligned to Chrome Print Preview. Unlike PDFium wrappers that render existing PDFs to images, IronPDF generates new PDFs from web content (HTML5, CSS3, JavaScript), manipulates existing PDFs (merge, split, forms, signatures, encryption), and extracts content (text, images, metadata). It targets .NET Framework 4.6.2+, .NET Core 3.1+, and modern .NET versions through .NET 10, with cross-platform packaging for Windows, Linux, macOS, Docker, and cloud environments — separate native binary packages are not required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where PDFium wrappers fit, and where they do not
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Product status
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fragmented ecosystem — multiple wrappers, no single canonical package&lt;/li&gt;
&lt;li&gt;Community maintenance — most wrappers are individual or small-team efforts&lt;/li&gt;
&lt;li&gt;Version drift — wrappers update their bundled PDFium binaries independently, so binaries can be incompatible across packages&lt;/li&gt;
&lt;li&gt;API surface differs between wrappers and across major versions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Missing capabilities (relative to a full PDF toolkit)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No HTML-to-PDF generation in PDFium itself&lt;/li&gt;
&lt;li&gt;No URL-to-PDF conversion&lt;/li&gt;
&lt;li&gt;Document-edit operations (merge, split, insert) are limited or absent in free wrappers; Patagames Pdfium.Net.SDK exposes more&lt;/li&gt;
&lt;li&gt;Form filling and AcroForm manipulation are limited or absent in free wrappers&lt;/li&gt;
&lt;li&gt;Digital signatures and encryption are not exposed by the free wrappers&lt;/li&gt;
&lt;li&gt;Text extraction may not be present in viewer-only wrappers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Technical considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Native binary dependency: requires the appropriate &lt;code&gt;pdfium.dll&lt;/code&gt; / &lt;code&gt;libpdfium.so&lt;/code&gt; / &lt;code&gt;libpdfium.dylib&lt;/code&gt; per RID, which adds deployment steps&lt;/li&gt;
&lt;li&gt;P/Invoke marshaling overhead on frequent native calls&lt;/li&gt;
&lt;li&gt;Manual disposal — forgetting &lt;code&gt;using&lt;/code&gt; statements can cause native handles to leak&lt;/li&gt;
&lt;li&gt;Platform packaging varies — some wrappers are Windows-only, others ship per-RID native binaries you must wire up&lt;/li&gt;
&lt;li&gt;Different wrappers use different PDFium builds and cannot be mixed in one process&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Free wrappers rely on GitHub issues and community channels&lt;/li&gt;
&lt;li&gt;Documentation depth varies — some wrappers have minimal published docs and rely on IntelliSense / source&lt;/li&gt;
&lt;li&gt;Bug-fix cadence depends on maintainer availability&lt;/li&gt;
&lt;li&gt;Patagames Pdfium.Net.SDK is the commercial option in the family and offers paid support tiers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tight coupling to native binaries can complicate containerized and serverless deployments unless RID-specific layouts are explicit&lt;/li&gt;
&lt;li&gt;Async APIs vary by wrapper; several expose synchronous-only operations&lt;/li&gt;
&lt;li&gt;Configurability is typically narrow — wrappers tend to expose a small subset of PDFium's configuration surface&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Feature Comparison Overview
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;PDFium wrappers&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Current status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fragmented, community-maintained (free); commercial Patagames option&lt;/td&gt;
&lt;td&gt;Active, commercial, single product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTML support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None (PDFium has no HTML parser)&lt;/td&gt;
&lt;td&gt;HTML5 / CSS3 / JS via Chromium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rendering quality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Suited to rendering existing PDFs&lt;/td&gt;
&lt;td&gt;Chromium-based output for generated PDFs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wrapper package + per-RID native binaries&lt;/td&gt;
&lt;td&gt;Single NuGet, multi-target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Community for free wrappers; paid for Patagames&lt;/td&gt;
&lt;td&gt;Commercial support / SLA options&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Future viability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Depends on individual maintainers / vendor&lt;/td&gt;
&lt;td&gt;.NET 10-ready, cross-platform&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Code Comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PDFium (PdfiumViewer) — Render PDF pages to images
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: PdfiumViewer  (representative open-source PDFium wrapper)&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;PdfiumViewer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Drawing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Drawing.Imaging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Ensure the PDFium native binary for your RID is on the load path&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"existing-report.pdf"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// PdfiumViewer exposes per-page sizes via document.PageSizes&lt;/span&gt;
                    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSizes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// 2x scale&lt;/span&gt;
                    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bitmap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;96&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;96&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PdfRenderFlags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Annotations&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"page-&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ImageFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Png&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PDF rendered to images successfully."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DllNotFoundException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// pdfium.dll not found in output directory&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"ERROR: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BadImageFormatException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// x86 / x64 mismatch between process and native binary&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"ERROR: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes on this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PDFium is a rendering / parsing engine; generating a PDF from HTML requires a different library&lt;/li&gt;
&lt;li&gt;The native binary must match the process architecture and RID&lt;/li&gt;
&lt;li&gt;Pages are not first-class objects in PdfiumViewer — per-page size lives on &lt;code&gt;document.PageSizes[i]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sequential per-page calls — batching across pages is the caller's responsibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IronPDF — Generate PDF from HTML
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;htmlContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;@"
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
        body { font-family: Arial; margin: 40px; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Monthly Report&amp;lt;/h1&amp;gt;
    &amp;lt;table&amp;gt;
        &amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;Metric&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Value&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Revenue&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;$125,000&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;htmlContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"monthly-report.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;HTML to PDF tutorial&lt;/a&gt; walks through modern web content rendering (CSS Grid, Flexbox, JavaScript) without manual layout calculation. Platform-specific binaries are bundled by IronPdf and resolved at runtime.&lt;/p&gt;




&lt;h3&gt;
  
  
  PDFium (PdfiumViewer) — Extract page count and text
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: PdfiumViewer&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;PdfiumViewer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contract.pdf"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Document has &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; pages."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="c1"&gt;// PdfiumViewer's text extraction is per-page raw text via GetPdfText(int).&lt;/span&gt;
                &lt;span class="c1"&gt;// Layout/format metadata is not exposed.&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AppendLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPdfText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"PDF error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes on this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text extraction is per-page raw text via &lt;code&gt;GetPdfText(i)&lt;/code&gt;; layout / format information is minimal&lt;/li&gt;
&lt;li&gt;AcroForm field read/write is not exposed by the open-source wrappers&lt;/li&gt;
&lt;li&gt;Document-info access and modification depend on the wrapper; not all free wrappers expose metadata writes&lt;/li&gt;
&lt;li&gt;Digital signature validation is not part of the free-wrapper surface&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IronPDF — Extract text and metadata
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contract.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Extract all text&lt;/span&gt;
&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;allText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExtractAllText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Read metadata&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MetaData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Title: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Pages: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Modify metadata&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Legal Team"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Subject&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Updated Contract"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"contract-updated.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF provides read/write access to metadata, form fields, and content extraction. The &lt;a href="https://ironpdf.com/how-to/rendering-options/" rel="noopener noreferrer"&gt;rendering options documentation&lt;/a&gt; covers watermarking, headers/footers, and custom page sizes.&lt;/p&gt;




&lt;h3&gt;
  
  
  PDFium (PDFiumCore) — Render pages in parallel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: PDFiumCore  (Dtronix, .NET Standard 2.1 P/Invoke bindings)&lt;/span&gt;
&lt;span class="c1"&gt;// The exact API surface varies between PDFiumCore releases — verify method names&lt;/span&gt;
&lt;span class="c1"&gt;// against your installed version.&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;PDFiumCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// PDFiumCore uses .NET Standard 2.1 — target .NET Core 3.1+ or .NET 5+.&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PdfDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"large-manual.pdf"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderTasks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Capture for closure&lt;/span&gt;
                    &lt;span class="n"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pageIndex&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="c1"&gt;// Page width/height are in points (1/72 inch).&lt;/span&gt;
                            &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;widthPts&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                            &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;heightPts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                            &lt;span class="c1"&gt;// Convert to pixels at 150 DPI.&lt;/span&gt;
                            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pixelWidth&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;widthPts&lt;/span&gt;  &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;150.0&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;72.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pixelHeight&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;heightPts&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;150.0&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;72.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bitmap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PDFiumBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pixelWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixelHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                                &lt;span class="c1"&gt;// Bitmap conversion / save APIs vary by version.&lt;/span&gt;
                            &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Rendered &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pageCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; pages."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileNotFoundException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"ERROR: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes on this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual conversion from points to pixels at the target DPI&lt;/li&gt;
&lt;li&gt;Type conversion between &lt;code&gt;PDFiumBitmap&lt;/code&gt; and &lt;code&gt;System.Drawing.Bitmap&lt;/code&gt; adds a copy&lt;/li&gt;
&lt;li&gt;Thread safety of &lt;code&gt;PdfDocument&lt;/code&gt; instances depends on the wrapper — verify against your version's documentation&lt;/li&gt;
&lt;li&gt;Output is rasterized images; rendered images cannot be re-inserted into the source PDF without another library&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IronPDF — Generate multi-page PDF from an HTML file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Render HTML file; page breaks come from CSS print media rules.&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlFileAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"product-catalog.html"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Add page numbers&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddPageNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Page {page} of {total-pages}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"catalog-with-page-numbers.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://ironpdf.com/how-to/html-file-to-pdf/" rel="noopener noreferrer"&gt;HTML file to PDF guide&lt;/a&gt; covers external CSS, JavaScript execution timing, and responsive layouts.&lt;/p&gt;




&lt;h3&gt;
  
  
  PDFium (generic wrapper) — native binary placement
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Reflection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Most PDFium wrappers load pdfium.dll / libpdfium.so / libpdfium.dylib&lt;/span&gt;
        &lt;span class="c1"&gt;// from a runtimes/&amp;lt;rid&amp;gt;/native folder or from the application directory.&lt;/span&gt;
        &lt;span class="c1"&gt;// Container / cloud deploys typically need the runtimes folder included.&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isWindows&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OSVersion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Platform&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;PlatformID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Win32NT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;is64Bit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Is64BitProcess&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;dllName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isWindows&lt;/span&gt;
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is64Bit&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"pdfium_x64.dll"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pdfium_x86.dll"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"libpdfium.so"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;dllPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDirectoryName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;)!,&lt;/span&gt;
            &lt;span class="s"&gt;"runtimes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;isWindows&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"win"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"linux"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;dllName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dllPath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Without the expected native binary the wrapper cannot initialise.&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"PDFium native binary not found at &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dllPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"PDFium native binary located at &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dllPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notes on this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native binary discovery is the application's responsibility per RID&lt;/li&gt;
&lt;li&gt;Missing or misplaced binaries surface as &lt;code&gt;DllNotFoundException&lt;/code&gt; at first use&lt;/li&gt;
&lt;li&gt;Containerized builds need the &lt;code&gt;runtimes/&lt;/code&gt; folder explicitly included in the publish output&lt;/li&gt;
&lt;li&gt;There is no in-process fallback if the native binary fails to load&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IronPDF — single-package deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// NuGet: Install-Package IronPdf&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ChromePdfRenderer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RenderHtmlAsPdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Deployed Successfully&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"deployment-test.pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IronPDF bundles platform-specific binaries inside its NuGet package and resolves them at runtime. The same package is used on Windows, Linux, macOS, Docker, Azure Functions, and AWS Lambda; whether each scenario is a fit for your project should still be validated against your environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Mapping Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PDFium wrapper concept&lt;/th&gt;
&lt;th&gt;IronPDF equivalent&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Load(path)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromFile(path)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load from file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Load(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromStream(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load from stream&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(wrap bytes in MemoryStream)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.FromBinaryData(bytes)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Load from bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;document.Render(page, w, h, dpi, dpi, flags)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.RasterizeToImageFiles(path, DPI)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rasterize pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native DLL management&lt;/td&gt;
&lt;td&gt;Bundled in IronPdf NuGet&lt;/td&gt;
&lt;td&gt;Embedded Chromium / per-RID payload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;document.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.PageCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;document.PageSizes[i].Width/Height&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.Pages[i].Width/Height&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Per-page size in points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;document.GetPdfText(i)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.Pages[i].Text&lt;/code&gt; / &lt;code&gt;pdf.ExtractAllText()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Per-page or whole-document&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;document.Save(stream)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf.SaveAs(path)&lt;/code&gt; / &lt;code&gt;pdf.Stream&lt;/code&gt; / &lt;code&gt;pdf.BinaryData&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Save variants&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(not available in PDFium)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderHtmlAsPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate from HTML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(not available in PDFium)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ChromePdfRenderer.RenderUrlAsPdf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate from URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(not available in free wrappers)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PdfDocument.Merge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Combine PDFs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(not available in free wrappers)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.Form&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AcroForm read/write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(not available in free wrappers)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.SignWithDigitalSignature&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;(not available in free wrappers)&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pdf.SecuritySettings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Password / permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Comprehensive Feature Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;PDFium wrappers&lt;/th&gt;
&lt;th&gt;IronPDF&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;Community-maintained (free); commercial Patagames&lt;/td&gt;
&lt;td&gt;Commercial, active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breaking changes&lt;/td&gt;
&lt;td&gt;Vary by wrapper / version&lt;/td&gt;
&lt;td&gt;Versioned releases with migration notes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform support&lt;/td&gt;
&lt;td&gt;Varies by wrapper&lt;/td&gt;
&lt;td&gt;Cross-platform NuGet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Varies by wrapper&lt;/td&gt;
&lt;td&gt;Documentation + API reference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Channels&lt;/td&gt;
&lt;td&gt;GitHub issues (free); paid tiers for Patagames&lt;/td&gt;
&lt;td&gt;Commercial support options&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise SLA&lt;/td&gt;
&lt;td&gt;Available via Patagames&lt;/td&gt;
&lt;td&gt;Available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content creation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML to PDF&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;URL to PDF&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate from scratch&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge PDFs&lt;/td&gt;
&lt;td&gt;Free wrappers: no; Patagames: partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split PDFs&lt;/td&gt;
&lt;td&gt;Free wrappers: no; Patagames: partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PDF operations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Render to bitmap&lt;/td&gt;
&lt;td&gt;Yes (core capability)&lt;/td&gt;
&lt;td&gt;Yes (via rasterization)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract text&lt;/td&gt;
&lt;td&gt;Per page (free wrappers)&lt;/td&gt;
&lt;td&gt;Full document or per page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract images&lt;/td&gt;
&lt;td&gt;SDK-dependent&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form filling&lt;/td&gt;
&lt;td&gt;Free wrappers: no; Patagames: yes&lt;/td&gt;
&lt;td&gt;Full AcroForm support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;td&gt;Free wrappers: no; Patagames: yes&lt;/td&gt;
&lt;td&gt;Yes (X.509)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;Free wrappers: no; Patagames: yes&lt;/td&gt;
&lt;td&gt;Yes (AES 128 / 256)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Watermarks&lt;/td&gt;
&lt;td&gt;Not built-in&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Headers/footers&lt;/td&gt;
&lt;td&gt;Not built-in&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password protection&lt;/td&gt;
&lt;td&gt;Free wrappers: read-only; Patagames: read/write&lt;/td&gt;
&lt;td&gt;Read and write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Certificate signatures&lt;/td&gt;
&lt;td&gt;Free wrappers: no&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redaction&lt;/td&gt;
&lt;td&gt;Not exposed&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operational&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native binary deployment&lt;/td&gt;
&lt;td&gt;Required (per RID)&lt;/td&gt;
&lt;td&gt;Bundled in NuGet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;x86 / x64 conflicts&lt;/td&gt;
&lt;td&gt;Possible if process / binary mismatch&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thread safety&lt;/td&gt;
&lt;td&gt;Verify per wrapper&lt;/td&gt;
&lt;td&gt;Documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory management&lt;/td&gt;
&lt;td&gt;Manual disposal of native handles&lt;/td&gt;
&lt;td&gt;Managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker support&lt;/td&gt;
&lt;td&gt;Manual native binary placement&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Development&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Async / await&lt;/td&gt;
&lt;td&gt;Wrapper-dependent&lt;/td&gt;
&lt;td&gt;Async APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependency injection&lt;/td&gt;
&lt;td&gt;Wrapper-dependent&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unit testing&lt;/td&gt;
&lt;td&gt;Native dependency may complicate mocking&lt;/td&gt;
&lt;td&gt;Standard mocking works&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NuGet packages&lt;/td&gt;
&lt;td&gt;Wrapper + per-RID native&lt;/td&gt;
&lt;td&gt;Single, multi-target&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Installation Comparison
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PDFium (PdfiumViewer example):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Install-Package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PdfiumViewer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# On Linux, obtain libpdfium.so (e.g. from pdfium-binaries) and place under&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# runtimes/linux-x64/native/ in the publish output.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;PdfiumViewer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Ensure the native pdfium binary for your RID is on the load path.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IronPDF:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Install-Package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IronPdf&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;# Single package, multi-target&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;IronPdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LicenseKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR-LICENSE-KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// No additional configuration required.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;PDFium wrappers fit a specific niche: rendering existing PDFs to bitmaps for display in viewer controls or thumbnail generation, plus per-page raw text extraction. For teams building custom PDF viewers in WinForms, WPF, or desktop apps — and willing to manage native binaries per RID — wrappers like PdfiumViewer, PdfiumViewer.Updated, PDFiumCore, or the commercial Pdfium.Net.SDK can be a good fit.&lt;/p&gt;

&lt;p&gt;Migration to a fuller toolkit tends to make sense when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML-to-PDF generation is required (reports, invoices, dynamic content)&lt;/li&gt;
&lt;li&gt;PDF manipulation is needed beyond viewing (merge, split, forms, signatures)&lt;/li&gt;
&lt;li&gt;Cross-platform deployment is on the roadmap (Docker, Linux, macOS) and per-RID native binary management is unwelcome&lt;/li&gt;
&lt;li&gt;Commercial support and SLA are business requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IronPDF complements PDFium's strength in rendering with comprehensive PDF generation from HTML, URLs, and other sources through a &lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;Chromium rendering engine&lt;/a&gt;. The library covers document manipulation (merge, split, forms, encryption, signatures) and text / image extraction, and packages platform-specific binaries inside a single NuGet so consuming projects do not need to place native binaries by hand.&lt;/p&gt;

&lt;p&gt;Have you hit "Unable to load DLL 'pdfium.dll'" errors in production? Share your PDFium wrapper troubleshooting stories in the comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ironpdf.com/how-to/rendering-options/" rel="noopener noreferrer"&gt;IronPDF Rendering Options Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ironpdf.com/tutorials/html-to-pdf/" rel="noopener noreferrer"&gt;HTML to PDF Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
