# How to Use IronPDF with Cursor
Ask any AI assistant to write IronPDF code and it will produce something that looks right. Sometimes it is. Other times it calls a method that has never existed, and you find out at the build rather than the review. The model is not malfunctioning. It is filling a gap in what it knows with something plausible-shaped, which is the same instinct that makes it useful and dangerous in equal measure.
Cursor is an AI-first code editor built on VS Code, and its most valuable feature for library work is not the chat box. It is the ability to index a library's documentation and to commit project rules to the repository, so the editor answers from real IronPDF APIs and follows your team's conventions without being told twice. IronPDF renders HTML, CSS, and JavaScript to PDF through an embedded Chromium engine. Neither tool knows about the other, and there is no integration to install. What you set up instead is context, and that setup is what the first half of this guide covers.
One distinction before you begin, because two similar topics get confused. This guide is about using an AI editor to *build software* with IronPDF. It is not about using AI models to read or analyze the contents of PDF files, which the [AI-powered PDF processing tutorial](/tutorials/ai-powered-pdf-processing-csharp/) covers separately.
*as-heading:2(Quickstart)*
!!!--LIBRARY_NUGET_INSTALL_BLOCK--!!!
Open a C# project in Cursor and prompt against the indexed documentation rather than the model's memory:
```text
@Docs IronPDF
In this C# project, create Program.cs that renders "<h1>Hello from IronPDF</h1>"
to hello.pdf. Read the license key from the IRONPDF_LICENSE_KEY environment
variable. Use only methods that appear in the indexed documentation.
```
Cursor writes the few lines that matter: construct a `ChromePdfRenderer`, call `RenderHtmlAsPdf` on the markup, and `SaveAs` the result to disk. The `@Docs` mention is what separates this from the same request typed into a general chat window, and setting it up is the first real section below.
A short safety note. An agent with file-write and terminal access should never be handed a license key inline, so keep it in an environment variable or a configuration file that is excluded from source control. The [license key guide](/get-started/license-keys/) covers the supported options.
<div class="hsg-featured-snippet">
<h3>Minimal Workflow (5 steps)</h3>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://www.nuget.org/packages/IronPdf/">Download the C# PDF library from NuGet</a></li>
<li>Add the IronPDF documentation as a custom source so <code>@Docs</code> can reach it</li>
<li>Commit a project rule pinning the IronPDF version and your conventions</li>
<li>Reference indexed docs and specific files with <code>@</code> mentions when prompting</li>
<li>Build, open the PDF, and check every API name against the <a href="/object-reference/api/">API reference</a></li>
</ol>
</div>
<br class="clear" />
---
## What is actually running behind the chat box?
Cursor is the one tool in this series that does not come with a model attached. It ships its own, and it also lets you point the same editor at somebody else's.
Composer is Cursor's in-house agentic model, built to be fast and closely wired into the editor. Fusion is the model behind Tab, the inline completion that finishes a line and predicts the next edit. Alongside those, the model picker reaches frontier models from Anthropic, OpenAI, and Google, and you can switch between them inside a single session.
For PDF work that has one practical consequence worth planning around. Most of a document session is cheap, repetitive work: adjust a margin, rebuild, look at the output, adjust again. Occasionally a table breaks across a page for a reason no compiler will explain, and that is the moment to move up to a model that thinks longer before it edits. Expect the document to shift with the choice, too. The same prompt handed to two models returns two layouts that differ in spacing and page breaks while still hitting whatever you specified explicitly, which is the argument for pinning the page count, the header text, and the footer format rather than trusting a default.
It also means this series overlaps here. Run a Claude model inside Cursor and the observations in the [Claude Code guide](/ai-agents/claude-code/) still apply to its output, because the model is the same even though the surface is not.
## How do you index the IronPDF documentation so Cursor stops guessing?
Cursor can index external documentation and make it available in prompts through the `@Docs` mention. You add a URL as a custom documentation source in Cursor's settings, under the docs and indexing section, and the editor crawls and indexes those pages. Adding IronPDF's documentation is the single highest-value setup step in this guide, because it replaces recall with retrieval.
The reasoning is worth stating plainly for anyone new to this. A model asked about a specific library draws on whatever it absorbed during training, which may be a year stale and was never verified against the current release. An indexed documentation source gives the editor something to look at. The difference shows up immediately in method names: an ungrounded model invents `renderer.ConvertHtmlToPdfDocument()`, and it reads perfectly well until the compiler disagrees.
Once indexed, the source is referenced in a prompt the same way a file is:
```text
@Docs IronPDF
What are the options for adding a footer with page numbers to a rendered PDF?
Show the exact class and property names from the documentation, and link the
page you took them from.
```
Asking for the source page is a cheap verification habit. If the editor cannot point at a real documentation page for the API it just recommended, that is a signal to check before writing code against it.
[[t:(This pays off again later, on the unfamiliar classes. Ask the editor to summarize the rendering options type and list which ones your project already sets, and the [API reference](/object-reference/api/) becomes something you query instead of scroll.)]]
## How do you write project rules that encode your IronPDF conventions?
Cursor project rules live in a `.cursor/rules` directory at the repository root and are version-controlled, so they are committed alongside the code and every developer inherits the same behaviour without configuring anything.
Rules are `.mdc` files: markdown with YAML frontmatter carrying `description`, `globs`, and `alwaysApply`. Cursor reads them recursively, so subdirectories work. A plain `.md` file in that folder is ignored, because it has no frontmatter to activate. A rule for IronPDF conventions looks like this:
```text
---
description: IronPDF conventions for PDF generation in this project
globs: ["**/Services/**/*.cs", "**/Pdf/**/*.cs"]
alwaysApply: false
---
# IronPDF conventions
- Use ChromePdfRenderer for all HTML-to-PDF conversion.
- Target the IronPDF version pinned in Directory.Packages.props. Do not upgrade it
as part of an unrelated change.
- Never inline a license key. Read it from configuration or the
IRONPDF_LICENSE_KEY environment variable.
- Prefer the shared PdfDocumentService helper over constructing a renderer
per call. A ChromePdfRenderer instance is reusable.
- Use the async rendering methods in web request paths.
- Do not invent IronPDF API names. If a method is uncertain, say so and cite
the documentation instead of guessing.
```
That last line does more work than it looks. Telling the model that admitting uncertainty is acceptable reduces invented APIs, and putting it in a committed rule means you stop repeating it in every prompt.
The `globs` line is the part worth copying deliberately. Everything marked `alwaysApply: true` loads into every request and spends context budget, so scoping the IronPDF rule to the paths where PDF code actually lives keeps it out of requests that have nothing to do with rendering.
[[i:(Cursor also reads a plain `AGENTS.md` at the project root, the same file ChatGPT Codex and Google Antigravity read. It carries no frontmatter, so it has no globs and always applies. Reach for `.cursor/rules` when you want scoping, and for `AGENTS.md` when you want one instructions file that several tools honour.)]]
One limit surprises people: rules apply to agent and chat interactions, not to Tab completion or inline edits. A convention encoded in a rule shapes what the agent writes and will not stop Tab from suggesting something else. Worth knowing before concluding that a rule is being ignored.
## Which mode fits the change?
Cursor exposes more distinct ways to make an edit than anything else in this series, and picking the wrong one is the most common way to waste time. The useful instinct is scale.
| Mode | Reach for it when | Typical PDF task |
|---|---|---|
| Tab | You are already typing and the next edit is predictable | Finishing a rendering-options property you have set before |
| Inline edit | The change fits in one sentence and lives in one file | Adding a margin, a footer, or a page-size setting |
| Agent | The work spans files, or needs a build and a fix loop | Wiring a renderer into a service and getting it compiling |
| Plan first | A rewrite is large enough that reviewing it after the fact would be worse than agreeing on it first | Migrating a report generator off another PDF library |
| Background | The task does not need watching and blocks nothing | Writing a test suite around PDF output |
An inline edit on a renderer is the clearest illustration, because you describe the change and review a diff in place rather than reading a new file:
```text
Add a 25mm top margin and an HTML footer showing "{page} of {total-pages}",
centred, max height 15mm.
```
What lands in the file is short enough to check at a glance:
```cs
var renderer = new ChromePdfRenderer();
// Footers occupy space the page content does not automatically yield,
// so the margin and the footer are set together or the two collide.
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
MaxHeight = 15,
HtmlFragment = "<center>{page} of {total-pages}</center>"
};
```
`{page}` and `{total-pages}` are IronPDF's own merge fields rather than string placeholders you substitute yourself, which is the kind of detail an indexed documentation source gets right and an ungrounded guess usually does not.
## What does an `@` mention actually change?
Context mentions tell the editor exactly what to look at. Naming the file that builds a PDF produces a far better result than describing it, because a description is lossy and a file reference is not.
```text
@Services/InvoiceRenderer.cs @Templates/invoice.html @Docs IronPDF
The footer overlaps the last line of the invoice table. Fix it in the renderer
configuration, not the template. Explain which setting causes the overlap.
```
Alongside files, Cursor takes folders for work spanning a module, the wider codebase when you do not know which file matters, indexed documentation, and the web. Combining a file with a documentation source, as above, is the pattern that keeps IronPDF work accurate: the file supplies what your code currently does, and the docs supply what the library actually offers.
That particular prompt also illustrates why grounding matters. A footer configured without a corresponding margin overlaps the body, because the footer occupies space the content does not surrender on its own. It is a renderer setting rather than a CSS problem, and the [headers and footers guide](/how-to/headers-and-footers/) documents the relationship.
## How do you plan and run a migration to IronPDF?
Migrations are where an unreviewed multi-file rewrite becomes expensive, because unpicking one is harder than writing it. Planning before implementation exists for exactly this: it takes the goal, asks clarifying questions, and produces an editable plan before any code is written.
```text
@Reports/ @Docs IronPDF
This folder builds PDFs by positioning text at coordinates with another library.
Plan a migration to IronPDF using HTML templates.
Summarize what the current output looks like, covering page size, sections, and
fonts, then propose the template structure and the files that change. Keep
existing public method signatures so callers don't change. Don't write code yet.
```
Review the plan, correct it in a sentence or two, and hand it back to be implemented. Agent mode reads the codebase, edits across files, runs terminal commands, reads the output, and iterates, so the follow-up is short:
```text
Implement the approved plan. Then run dotnet build, fix what breaks, and
show me the diff. Don't add new packages.
```
Constraining the agent to the approved plan and forbidding new packages matters more than it looks. Agents left unconstrained tend to treat a migration as an invitation to redesign the calling convention as a bonus.
Work that needs no supervision can run in the background while you continue elsewhere. A test suite around PDF output is a good candidate, because the tests assert on the document rather than the implementation and do not need the migration finished first:
```text
Write xUnit tests for the migrated report output: result is non-empty, begins
with the %PDF- signature, extracted text contains the bound company name, and
page count matches expectation. No golden-file byte comparisons, since
rendering output is not byte-stable across versions or platforms.
```
Ruling out byte comparison prevents a whole class of flaky test that would otherwise cost someone an afternoon.
## Where do rendering problems actually live?
Differences between browser and PDF are the most common IronPDF question, and they usually trace to one of three causes: a stylesheet written for screen rather than print media, a web font that had not loaded when the layout was computed, or content produced by JavaScript that was captured too early. Naming the symptom and the file gets a far more useful answer than pasting the whole project.
```text
@Templates/report.html @Services/ReportRenderer.cs @Docs IronPDF
The report renders correctly in Chrome but the PDF drops the logo and splits a
table row across pages. Explain the cause of each before changing anything,
then fix the table break in CSS and the logo in the renderer configuration.
```
Splitting the diagnosis from the fix gives you something to evaluate rather than a change to reverse-engineer. In this case the two problems have different homes: page-break behaviour belongs in the stylesheet, covered by the [page breaks guide](/how-to/html-to-pdf-page-breaks/), while a logo that resolves in a browser and not in the render is usually a base-path question, because a raw HTML string carries no document location to resolve relative URLs against.
Deployment failures are where terminal access earns its place, since the answer usually lives in the container rather than the code.
```text
@Dockerfile @Docs IronPDF
Rendering works on Windows but fails in our Linux container with:
[PASTE FULL EXCEPTION AND STACK TRACE HERE]
Check for missing native dependencies IronPDF's Chromium engine needs on
Debian-based images. Explain the cause, then propose the Dockerfile change.
Don't modify C# code unless the cause is there.
```
The instruction not to touch application code is deliberate. A missing shared library in an image is not a C# problem, and an agent given a free hand will sometimes wrap the call in a try/catch that hides the failure rather than fixing it. The [Docker deployment guide](/get-started/ironpdf-docker/) documents the current requirements, which change between releases.
## What should you set up first?
The grounding, before anything else. Indexing the IronPDF documentation and committing one scoped project rule takes about fifteen minutes, applies to every prompt afterward, and is the whole difference between this workflow and pasting questions into a general chat assistant. Everything after that, the inline edits, the mentions, the planning, the agents, is ordinary editor usage that happens to work better once the grounding is in place.
The verification habit stays the same regardless of which model is answering: build early, open the PDF, and check the API names against the documentation before anything ships. The reproducible version of that check, run start to finish with a published result, lives on the [AI coding assistants guide](/ai-agents/ai/), alongside the guides for [ChatGPT Codex](/ai-agents/chatgpt-codex/), [GitHub Copilot](/ai-agents/github-copilot/), and [Google Antigravity](/ai-agents/antigravity/).
---
## Troubleshooting
- [Apply a license key in IronPDF](/troubleshooting/apply-a-license-key-in-ironpdf/): if generated code produces watermarked output
- [Initializing RenderingOptions Correctly](/troubleshooting/rendering-options-initialization/): if a suggested option name does not resolve
- [What version of IronPDF should I use?](/troubleshooting/what-version-of-ironpdf-should-i-use/): to pin a version in your project rule
- [How to Run IronPDF in a Docker Container](/get-started/ironpdf-docker/): if a render works locally and fails inside a container
---
## Questions?
If you have any questions, reach out to [support@ironsoftware.com](mailto:support@ironsoftware.com)
Ask any AI assistant to write IronPDF code and it will produce something that looks right. Sometimes it is. Other times it calls a method that has never existed, and you find out at the build rather than the review. The model is not malfunctioning. It is filling a gap in what it knows with something plausible-shaped, which is the same instinct that makes it useful and dangerous in equal measure.
Cursor is an AI-first code editor built on VS Code, and its most valuable feature for library work is not the chat box. It is the ability to index a library's documentation and to commit project rules to the repository, so the editor answers from real IronPDF APIs and follows your team's conventions without being told twice. IronPDF renders HTML, CSS, and JavaScript to PDF through an embedded Chromium engine. Neither tool knows about the other, and there is no integration to install. What you set up instead is context, and that setup is what the first half of this guide covers.
One distinction before you begin, because two similar topics get confused. This guide is about using an AI editor to build software with IronPDF. It is not about using AI models to read or analyze the contents of PDF files, which the AI-powered PDF processing tutorial covers separately.
Quickstart
Install with NuGet
PM > Install-Package IronPdf
Install-Package IronPdf
Install IronPDF by running the command above in the NuGet Package Manager Console, or search for the package in the NuGet Package Manager.
Open a C# project in Cursor and prompt against the indexed documentation rather than the model's memory:
@Docs IronPDFIn this C# project, create Program.cs that renders "<h1>Hello from IronPDF</h1>"to hello.pdf. Read the license key from the IRONPDF_LICENSE_KEY environmentvariable. Use only methods that appear in the indexed documentation.
@Docs IronPDF
In this C# project, create Program.cs that renders "<h1>Hello from IronPDF</h1>"
to hello.pdf. Read the license key from the IRONPDF_LICENSE_KEY environment
variable. Use only methods that appear in the indexed documentation.
Text
Cursor writes the few lines that matter: construct a ChromePdfRenderer, call RenderHtmlAsPdf on the markup, and SaveAs the result to disk. The @Docs mention is what separates this from the same request typed into a general chat window, and setting it up is the first real section below.
A short safety note. An agent with file-write and terminal access should never be handed a license key inline, so keep it in an environment variable or a configuration file that is excluded from source control. The license key guide covers the supported options.
Add the IronPDF documentation as a custom source so @Docs can reach it
Commit a project rule pinning the IronPDF version and your conventions
Reference indexed docs and specific files with @ mentions when prompting
Build, open the PDF, and check every API name against the API reference
What is actually running behind the chat box?
Cursor is the one tool in this series that does not come with a model attached. It ships its own, and it also lets you point the same editor at somebody else's.
Composer is Cursor's in-house agentic model, built to be fast and closely wired into the editor. Fusion is the model behind Tab, the inline completion that finishes a line and predicts the next edit. Alongside those, the model picker reaches frontier models from Anthropic, OpenAI, and Google, and you can switch between them inside a single session.
For PDF work that has one practical consequence worth planning around. Most of a document session is cheap, repetitive work: adjust a margin, rebuild, look at the output, adjust again. Occasionally a table breaks across a page for a reason no compiler will explain, and that is the moment to move up to a model that thinks longer before it edits. Expect the document to shift with the choice, too. The same prompt handed to two models returns two layouts that differ in spacing and page breaks while still hitting whatever you specified explicitly, which is the argument for pinning the page count, the header text, and the footer format rather than trusting a default.
It also means this series overlaps here. Run a Claude model inside Cursor and the observations in the Claude Code guide still apply to its output, because the model is the same even though the surface is not.
How do you index the IronPDF documentation so Cursor stops guessing?
Cursor can index external documentation and make it available in prompts through the @Docs mention. You add a URL as a custom documentation source in Cursor's settings, under the docs and indexing section, and the editor crawls and indexes those pages. Adding IronPDF's documentation is the single highest-value setup step in this guide, because it replaces recall with retrieval.
The reasoning is worth stating plainly for anyone new to this. A model asked about a specific library draws on whatever it absorbed during training, which may be a year stale and was never verified against the current release. An indexed documentation source gives the editor something to look at. The difference shows up immediately in method names: an ungrounded model invents renderer.ConvertHtmlToPdfDocument(), and it reads perfectly well until the compiler disagrees.
Once indexed, the source is referenced in a prompt the same way a file is:
@Docs IronPDFWhat are the options for adding a footer with page numbers to a rendered PDF?Show the exact class and property names from the documentation, and link thepage you took them from.
@Docs IronPDF
What are the options for adding a footer with page numbers to a rendered PDF?
Show the exact class and property names from the documentation, and link the
page you took them from.
Text
Asking for the source page is a cheap verification habit. If the editor cannot point at a real documentation page for the API it just recommended, that is a signal to check before writing code against it.
Tips: This pays off again later, on the unfamiliar classes. Ask the editor to summarize the rendering options type and list which ones your project already sets, and the API reference becomes something you query instead of scroll.
How do you write project rules that encode your IronPDF conventions?
Cursor project rules live in a .cursor/rules directory at the repository root and are version-controlled, so they are committed alongside the code and every developer inherits the same behaviour without configuring anything.
Rules are .mdc files: markdown with YAML frontmatter carrying description, globs, and alwaysApply. Cursor reads them recursively, so subdirectories work. A plain .md file in that folder is ignored, because it has no frontmatter to activate. A rule for IronPDF conventions looks like this:
---description: IronPDF conventions for PDF generation in this projectglobs: ["**/Services/**/*.cs", "**/Pdf/**/*.cs"]alwaysApply: false---# IronPDF conventions- Use ChromePdfRenderer for all HTML-to-PDF conversion.- Target the IronPDF version pinned in Directory.Packages.props. Do not upgrade it as part of an unrelated change.- Never inline a license key. Read it from configuration or the IRONPDF_LICENSE_KEY environment variable.- Prefer the shared PdfDocumentService helper over constructing a renderer per call. A ChromePdfRenderer instance is reusable.- Use the async rendering methods in web request paths.- Do not invent IronPDF API names. If a method is uncertain, say so and cite the documentation instead of guessing.
---
description: IronPDF conventions for PDF generation in this project
globs: ["**/Services/**/*.cs", "**/Pdf/**/*.cs"]
alwaysApply: false
---
# IronPDF conventions
- Use ChromePdfRenderer for all HTML-to-PDF conversion.
- Target the IronPDF version pinned in Directory.Packages.props. Do not upgrade it
as part of an unrelated change.
- Never inline a license key. Read it from configuration or the
IRONPDF_LICENSE_KEY environment variable.
- Prefer the shared PdfDocumentService helper over constructing a renderer
per call. A ChromePdfRenderer instance is reusable.
- Use the async rendering methods in web request paths.
- Do not invent IronPDF API names. If a method is uncertain, say so and cite
the documentation instead of guessing.
Text
That last line does more work than it looks. Telling the model that admitting uncertainty is acceptable reduces invented APIs, and putting it in a committed rule means you stop repeating it in every prompt.
The globs line is the part worth copying deliberately. Everything marked alwaysApply: true loads into every request and spends context budget, so scoping the IronPDF rule to the paths where PDF code actually lives keeps it out of requests that have nothing to do with rendering.
Please note: Cursor also reads a plain AGENTS.md at the project root, the same file ChatGPT Codex and Google Antigravity read. It carries no frontmatter, so it has no globs and always applies. Reach for .cursor/rules when you want scoping, and for AGENTS.md when you want one instructions file that several tools honour.
One limit surprises people: rules apply to agent and chat interactions, not to Tab completion or inline edits. A convention encoded in a rule shapes what the agent writes and will not stop Tab from suggesting something else. Worth knowing before concluding that a rule is being ignored.
Which mode fits the change?
Cursor exposes more distinct ways to make an edit than anything else in this series, and picking the wrong one is the most common way to waste time. The useful instinct is scale.
Mode
Reach for it when
Typical PDF task
Tab
You are already typing and the next edit is predictable
Finishing a rendering-options property you have set before
Inline edit
The change fits in one sentence and lives in one file
Adding a margin, a footer, or a page-size setting
Agent
The work spans files, or needs a build and a fix loop
Wiring a renderer into a service and getting it compiling
Plan first
A rewrite is large enough that reviewing it after the fact would be worse than agreeing on it first
Migrating a report generator off another PDF library
Background
The task does not need watching and blocks nothing
Writing a test suite around PDF output
An inline edit on a renderer is the clearest illustration, because you describe the change and review a diff in place rather than reading a new file:
Add a 25mm top margin and an HTML footer showing "{page} of {total-pages}",centred, max height 15mm.
Add a 25mm top margin and an HTML footer showing "{page} of {total-pages}",
centred, max height 15mm.
Text
What lands in the file is short enough to check at a glance:
var renderer = new ChromePdfRenderer();// Footers occupy space the page content does not automatically yield,// so the margin and the footer are set together or the two collide.renderer.RenderingOptions.MarginTop = 25;renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter{MaxHeight = 15,HtmlFragment = "<center>{page} of {total-pages}</center>"};
var renderer = new ChromePdfRenderer();
// Footers occupy space the page content does not automatically yield,
// so the margin and the footer are set together or the two collide.
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
MaxHeight = 15,
HtmlFragment = "<center>{page} of {total-pages}</center>"
};
C#
{page} and {total-pages} are IronPDF's own merge fields rather than string placeholders you substitute yourself, which is the kind of detail an indexed documentation source gets right and an ungrounded guess usually does not.
What does an @ mention actually change?
Context mentions tell the editor exactly what to look at. Naming the file that builds a PDF produces a far better result than describing it, because a description is lossy and a file reference is not.
@Services/InvoiceRenderer.cs @Templates/invoice.html @Docs IronPDFThe footer overlaps the last line of the invoice table. Fix it in the rendererconfiguration, not the template. Explain which setting causes the overlap.
@Services/InvoiceRenderer.cs @Templates/invoice.html @Docs IronPDF
The footer overlaps the last line of the invoice table. Fix it in the renderer
configuration, not the template. Explain which setting causes the overlap.
Text
Alongside files, Cursor takes folders for work spanning a module, the wider codebase when you do not know which file matters, indexed documentation, and the web. Combining a file with a documentation source, as above, is the pattern that keeps IronPDF work accurate: the file supplies what your code currently does, and the docs supply what the library actually offers.
That particular prompt also illustrates why grounding matters. A footer configured without a corresponding margin overlaps the body, because the footer occupies space the content does not surrender on its own. It is a renderer setting rather than a CSS problem, and the headers and footers guide documents the relationship.
How do you plan and run a migration to IronPDF?
Migrations are where an unreviewed multi-file rewrite becomes expensive, because unpicking one is harder than writing it. Planning before implementation exists for exactly this: it takes the goal, asks clarifying questions, and produces an editable plan before any code is written.
@Reports/ @Docs IronPDFThis folder builds PDFs by positioning text at coordinates with another library.Plan a migration to IronPDF using HTML templates.Summarize what the current output looks like, covering page size, sections, andfonts, then propose the template structure and the files that change. Keepexisting public method signatures so callers don't change. Don't write code yet.
@Reports/ @Docs IronPDF
This folder builds PDFs by positioning text at coordinates with another library.
Plan a migration to IronPDF using HTML templates.
Summarize what the current output looks like, covering page size, sections, and
fonts, then propose the template structure and the files that change. Keep
existing public method signatures so callers don't change. Don't write code yet.
Text
Review the plan, correct it in a sentence or two, and hand it back to be implemented. Agent mode reads the codebase, edits across files, runs terminal commands, reads the output, and iterates, so the follow-up is short:
Implement the approved plan. Then run dotnet build, fix what breaks, andshow me the diff. Don't add new packages.
Implement the approved plan. Then run dotnet build, fix what breaks, and
show me the diff. Don't add new packages.
Text
Constraining the agent to the approved plan and forbidding new packages matters more than it looks. Agents left unconstrained tend to treat a migration as an invitation to redesign the calling convention as a bonus.
Work that needs no supervision can run in the background while you continue elsewhere. A test suite around PDF output is a good candidate, because the tests assert on the document rather than the implementation and do not need the migration finished first:
Write xUnit tests for the migrated report output: result is non-empty, beginswith the %PDF- signature, extracted text contains the bound company name, andpage count matches expectation. No golden-file byte comparisons, sincerendering output is not byte-stable across versions or platforms.
Write xUnit tests for the migrated report output: result is non-empty, begins
with the %PDF- signature, extracted text contains the bound company name, and
page count matches expectation. No golden-file byte comparisons, since
rendering output is not byte-stable across versions or platforms.
Text
Ruling out byte comparison prevents a whole class of flaky test that would otherwise cost someone an afternoon.
Where do rendering problems actually live?
Differences between browser and PDF are the most common IronPDF question, and they usually trace to one of three causes: a stylesheet written for screen rather than print media, a web font that had not loaded when the layout was computed, or content produced by JavaScript that was captured too early. Naming the symptom and the file gets a far more useful answer than pasting the whole project.
@Templates/report.html @Services/ReportRenderer.cs @Docs IronPDFThe report renders correctly in Chrome but the PDF drops the logo and splits atable row across pages. Explain the cause of each before changing anything,then fix the table break in CSS and the logo in the renderer configuration.
@Templates/report.html @Services/ReportRenderer.cs @Docs IronPDF
The report renders correctly in Chrome but the PDF drops the logo and splits a
table row across pages. Explain the cause of each before changing anything,
then fix the table break in CSS and the logo in the renderer configuration.
Text
Splitting the diagnosis from the fix gives you something to evaluate rather than a change to reverse-engineer. In this case the two problems have different homes: page-break behaviour belongs in the stylesheet, covered by the page breaks guide, while a logo that resolves in a browser and not in the render is usually a base-path question, because a raw HTML string carries no document location to resolve relative URLs against.
Deployment failures are where terminal access earns its place, since the answer usually lives in the container rather than the code.
@Dockerfile @Docs IronPDFRendering works on Windows but fails in our Linux container with:[PASTE FULL EXCEPTION AND STACK TRACE HERE]Check for missing native dependencies IronPDF's Chromium engine needs onDebian-based images. Explain the cause, then propose the Dockerfile change.Don't modify C# code unless the cause is there.
@Dockerfile @Docs IronPDF
Rendering works on Windows but fails in our Linux container with:
[PASTE FULL EXCEPTION AND STACK TRACE HERE]
Check for missing native dependencies IronPDF's Chromium engine needs on
Debian-based images. Explain the cause, then propose the Dockerfile change.
Don't modify C# code unless the cause is there.
Text
The instruction not to touch application code is deliberate. A missing shared library in an image is not a C# problem, and an agent given a free hand will sometimes wrap the call in a try/catch that hides the failure rather than fixing it. The Docker deployment guide documents the current requirements, which change between releases.
What should you set up first?
The grounding, before anything else. Indexing the IronPDF documentation and committing one scoped project rule takes about fifteen minutes, applies to every prompt afterward, and is the whole difference between this workflow and pasting questions into a general chat assistant. Everything after that, the inline edits, the mentions, the planning, the agents, is ordinary editor usage that happens to work better once the grounding is in place.
The verification habit stays the same regardless of which model is answering: build early, open the PDF, and check the API names against the documentation before anything ships. The reproducible version of that check, run start to finish with a published result, lives on the AI coding assistants guide, alongside the guides for ChatGPT Codex, GitHub Copilot, and Google Antigravity.
Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.