Using IronXL with AI Coding Assistants
IronXL is a .NET library from Iron Software for working with Excel files. It creates, reads, and edits XLSX and legacy XLS workbooks, imports CSV and TSV files, evaluates formulas, and draws charts, all without Microsoft Office installed. IronXL has shipped on NuGet since 2019, and its tutorials use WorkBook and WorkSheet throughout.
The class names do not show how release 2026.10.1 treats your data. Give IronXL the string "8.27" as a cell value and it stores August 27 of the current year. Import a CSV with field conversion on and an OrderId of 000417 comes back as the number 417. Save without calling EvaluateAll and the file can hold a formula result from before the last edit. None of these stops a build.
This page sets up any assistant for that kind of work.
- Chat-style assistants rewrite the code you select or answer from the editor.
- Agents such as ChatGPT Codex, Google Antigravity, Claude Code, and Cursor take a whole task, then build and run the code they wrote.
The setup is the same for both, whether the job is reading a CSV export, editing formulas, adding a chart, or encrypting a workbook.
How to Use IronXL with an AI Coding Assistant
- Get the IronXL.Excel package from NuGet
- Assign
IronXL.License.LicenseKeyfromIRONXL_LICENSE_KEYbefore the first workbook call - Hand the assistant IronXL's
llms.txtindex at the start of the session - Keep the IronXL rules in the instructions file your assistant loads
- Open a new session and send the one-shot setup prompt
- Build and run the program, then send the self-check prompt
Can't My AI Assistant Handle Excel on Its Own?
From memory alone, an assistant writes the IronXL it saw in training, which can include members the current release does not have. IronXL publishes its documentation in a form tools can read, so the assistant can work from the current API instead.
Writing a grid of numbers to XLSX is the easy part. The differences between libraries appear with formulas, legacy XLS inputs, supplier CSV files, and workbooks that have to stay closed to outsiders.
- Office Interop ties code to one desktop: An assistant that reaches for Interop needs Excel installed wherever the code runs, while the IronXL package runs on Windows, Linux, and macOS servers.
- Rewriting the CSV parser costs tokens: An agent that replaces IronXL's CSV import with a hand-written splitter after one bad import pays for every attempt, and the new parser still has to learn quoting rules IronXL already handles.
- The package name and the namespace differ: The NuGet ID is
IronXL.Exceland the namespace isIronXL. A guessed ID can resolve to a lookalike package published to catch that guess, the attack called slopsquatting. Write the exact ID into the prompt.
Step 1: Install IronXL
With the package referenced, the assistant can inspect IronXL's real types.
Add the IronXL.Excel package from NuGet and restore the project.
Then tell me which version the project file references.
To pin a release from the terminal instead, name it.
dotnet add package IronXL.Excel --version 2026.10.5
IronXL.Excel 2026.10.5 depends only on IronSoftware.Common and IronSoftware.System.Drawing.
Step 2: Apply Your License Key
IronXL does not fall back to a watermarked or limited mode. Without a key, creating, loading, or importing a workbook throws IronSoftware.Exceptions.LicensingException with the message Production License Required. With a mistyped key, the first call fails with License Key Not Recognized instead. A free trial key is below, and the licensing page gives the developer, location, and project counts for each perpetual license tier.
Start using IronXL in your project today with a free trial.
Set the key once when the program starts, before any other IronXL call, and pull it from the IRONXL_LICENSE_KEY environment variable, which keeps it out of source control.
IronXL.License.IsLicensed returns true after a valid key is applied, and IronXL.License.IsValidLicense reports whether a given key is valid and unexpired. The exception type is internal, so a catch clause that names it does not compile and reports CS0122. Check IsLicensed at startup, or catch Exception and read the message.
Web.config or appsettings.json instead.Step 3: Point Your Assistant at IronXL's LLM Documentation
llms.txtis a linked index with one line per page, and it belongs at the start of every session.- Abstracts of 94 pages arrive in one file in
llms-full.txt, which suits broad questions. llms-full-catalog.txtadds every blog post to the index, for comparisons and blog walkthroughs.- The API Reference lists every namespace, type, and member.
- Tools that load skill files can take
skill.md, which covers install, licensing, recipes, and common failures. - The AI Product Fact Sheet gives one page of background.
Fetch https://ironsoftware.com/excel/csharp/llms.txt before you write any spreadsheet code.
Stick to IronXL members that the index documents.
- Open workbooks with WorkBook.Load or WorkBook.Create.
- Import delimited text with WorkBook.LoadCSV and an explicit delimiter.
- Save with SaveAs.
Look up any member the index lacks at https://ironsoftware.com/excel/csharp/object-reference/api/.
If it's missing there too, tell me instead of making one up.
When a task depends on one guide, ask the assistant to open that page.
Step 4: Add IronXL Context to Your Project
Chat instructions disappear when the chat closes. A project file is read again whenever a session opens, so add the IronXL rules to the one your team already keeps. Claude Code reads CLAUDE.md, ChatGPT Codex reads AGENTS.md, and GitHub Copilot reads .github/copilot-instructions.md. Cursor reads .mdc files in .cursor/rules/, or AGENTS.md. Google Antigravity reads AGENTS.md or GEMINI.md. The rules read the same in every file.
## Spreadsheets with IronXL
All Excel, CSV, and TSV work in this repo uses IronXL.
The NuGet package is `IronXL.Excel`. Its namespace is `IronXL`.
Number formats live in `IronXL.Formatting` and charts in `IronXL.Drawing.Charts`.
- Read the docs index at https://ironsoftware.com/excel/csharp/llms.txt.
- Read the skill file at https://ironsoftware.com/excel/csharp/skill.md.
- Set `IronXL.License.LicenseKey` from IRONXL_LICENSE_KEY at startup.
- Never write the key into a file.
- Import CSV with `WorkBook.LoadCSV`, passing the path, an XLSX format, and the delimiter.
- Choose `convertFieldValues` on purpose. Conversion strips leading zeros from ID columns.
- A numeric string such as "8.27" assigned to `Value` becomes a date.
- Write numbers as numbers and dates as `DateTime`.
- Call `EvaluateAll` before `SaveAs` so the file stores current formula results.
- Encrypt with `WorkBook.Password` or `SaveAs` with a password. `ProtectSheet` only locks editing.
- Save XLSX unless a task names XLS.
- Before calling a change done, reload every saved workbook.
- Compare the reloaded values with the source data.
- Add no Office Interop and no second spreadsheet library.
- If IronXL lacks a feature, ask before adding anything.
The skill file gets encryption, sheet protection, and EvaluateAll right. It does not warn about the leading zeros or the date conversion, so keep those two lines in your own file. Its single-file example still pins 2026.8.1, three releases behind the 2026.10.5 package on NuGet, so update the pin to the release your project uses.
Step 5: One-Shot Setup Prompt
Steps 1 to 4 fit into one message. Send it when a project starts or in any new session.
Set this project up for spreadsheet work with IronXL.
Store the rules below in the instructions file your later sessions load.
- Reference the IronXL.Excel NuGet package. Its namespace is plain IronXL.
- Read IRONXL_LICENSE_KEY into IronXL.License.LicenseKey at startup, before any WorkBook call.
- Never copy the key into a file.
- Before writing code, fetch https://ironsoftware.com/excel/csharp/llms.txt.
- Build only on members it documents.
- Look up anything else in the API reference before you rely on it.
- If you support skill files, load https://ironsoftware.com/excel/csharp/skill.md.
- When the compiler and the skill disagree, believe the compiler.
- Whenever code saves a workbook, open the saved file again.
- Compare the reopened file's cells and formula results with the data that went in.
Step 6: Prompt Patterns That Produce Working Code
Name the sheet, the cells, and the format. The assistant cannot guess which cells matter or which file format the job needs.
Vague Turn our orders into an Excel report with IronXL.
Better Create the workbook with
WorkBook.Create(ExcelFileFormat.XLSX), write the orders to a sheet named Orders with a bold, frozen header row, applyBuiltinFormats.Currency2to the UnitPrice column, and put a SUMIF per region on a Summary sheet.
Give the release and the framework. Behavior changes between versions, and an assistant without a version can mix old and new.
Better Target .NET 9 and IronXL.Excel 2026.10.5.
Ask for whole files. A fragment loses its using directives, which matters because BuiltinFormats lives in IronXL.Formatting and ChartType in IronXL.Drawing.Charts.
Better Return the complete
Program.cswith every using directive and the license assignment, so it compiles as it stands.
Step 7: Verify What You Get Back
Each of these mistakes reproduces on 2026.10.1.
- An ambiguous
Range: With implicit usings, assigning a sheet range such asA1:B2to aRangevariable matches bothIronXL.RangeandSystem.Rangeand fails with CS0104. WriteIronXL.Range, or add an alias. - Cell members called on a range: Indexing a single cell such as
A1still returns anIronXL.Range, so callingAddCommenton that result fails with CS1061. CallFirstto reach theCell. - The wrong reader for a semicolon file:
WorkBook.Loadsplit a comma file into columns, but it put each whole line of a semicolon file in column A and threw FileLoadException on a semicolon file with quoted fields. Pass the delimiter toWorkBook.LoadCSV, as the CSV reading guide does.
Let the Agent Verify Its Own Work
Rebuild in Release and run the program. Then check the result yourself:
- Name the documentation page behind each IronXL member you used.
- Print IronXL.License.IsLicensed.
- Reopen every workbook the program saved.
Give me a table of file, cell, value expected, value found, and whether they agree.
CSV Field and Cell Value Conversion
Type conversion happens in two places. These results are from IronXL.Excel 2026.10.1 on .NET 9.
WorkBook.LoadCSV takes a convertFieldValues flag, and it defaults to true.
| Field in the CSV | Conversion on | Conversion off |
|---|---|---|
| 000417 (ID) | number 417 | text 000417 |
| 12.50 (price) | number 12.5 | text 12.50 |
| 2026-08-30 (date) | text | text |
| 2 after "Monitor 27"" matte" | text | text |
| "Bolt; M8 zinc" | one field | one field |
Quoting works as RFC 4180 describes, and UTF-8 names such as Cafe with an accent survived the import with or without a byte order mark. The row with an escaped quote kept its next number as text, and SUM and SUMIF skip text, while a formula that multiplied the same cells still worked.
The second place is the Value setter. A string assigned as a cell value is parsed, and strings shaped like a month and day become dates. In our tests "1.5" was stored as January 5, 2026 and "2026-08-30" as August 30, 2026, while "12.50" and "000417" stayed text.
So an import that copies CSV fields across as strings can turn a price of 8.27 into a date serial near 46,261. The safe pattern is to import with conversion off, parse each column with the invariant culture, and assign int, decimal, double, or DateTime values.
Formula Results in the Saved File
IronXL calculates formulas when you read them, so a check that reloads the workbook through IronXL always sees a current answer. The saved file is a different matter. Readers that do not calculate, such as openpyxl and pandas, see only the results the file stores.
In our tests, a formula that was never read or evaluated before SaveAs was written with no stored result. A formula read once, followed by a change to its input and a save, kept the old result in the file. IronXL reported the new total of 43 after reloading, while openpyxl read the stored 5. After EvaluateAll and then SaveAs, every formula carried its current value. The formula editing guide calls EvaluateAll for the same reason.
Cross-sheet references work as expected. A SUMIF on a Summary sheet over ranges of the Orders sheet evaluated correctly, saved, and reloaded as a formula with its value.
Formula Text Returned by IronXL
A check that every Orders row holds its Revenue formula can compare formula text, but IronXL does not hand back the string it was given. We assigned =E2*F2 on cell G2 with 2026.10.1, and the Formula property returned E2*F2 with no equals sign, both before the save and after a reload. That is the content of the formula element in the sheet XML. IronXL's own XML documentation for Cell.Formula gives =A2+A2+A3+A4 as its example, and the formula editing guide writes formulas but reads back only their results.
A formula written without the equals sign reads back unchanged, and one assigned through Value loses its equals sign the same way. A cell holding a plain number returns null. IronXL keeps the case and spacing it was given, so =e5 * f5 reads back as e5 * f5.
So a self-check that compares formula text with =E2*F2 fails on a correct workbook. In the prompt below, a false failure of that kind would send the agent back into step 11 to change report code that was already right.
Whole columns have a second trap. The Formula property on a multi-cell range returns null unless every cell holds the same formula. The range G2:G5 was null for four correct per-row formulas, the same answer it gave for E2:E5, which holds no formula at all. Test IsFormula on each Cell, and compare formula text only after removing the = from the expected string.
XLS Output Limits
Older order and accounting systems still export XLS, and IronXL reads and writes it. Writing it has limits that XLSX does not.
| Operation | XLSX | XLS in 2026.10.1 |
|---|---|---|
| Rows | 1,048,576, then throws | 65,536, then ArgumentException |
| Charts | works | Exception, message recommends XLSX |
Password, Encrypt, or SaveAs with a password | encrypts | ArgumentException, only .xlsx, .xlsm, .xltx |
| Text 000501 | text | text |
DateTime | date | date, IsDateTime true after reload |
An XLS file that IronXL writes is a genuine Excel 97-2003 workbook. Its first eight bytes are D0 CF 11 E0 A1 B1 1A E1, the compound file signature, which is a quick way to confirm an assistant did not save XLSX content under an .xls name.
Sheet Protection and File Encryption
Ask for a "password-protected workbook" and an assistant may pick either of two IronXL features. They behave differently.
| Saved with | First bytes | No password | Wrong password |
|---|---|---|---|
ProtectSheet with Q3-review on each sheet | 50 4B 03 04 (ZIP) | opens | opens |
WorkBook.Password, SaveAs with a password, or Encrypt, then SaveAs | D0 CF 11 E0 (encrypted) | ArgumentNullException | SecurityException, Invalid password |
All four open with the correct password. ProtectSheet is meant to stop edits inside Excel, and it encrypts nothing. When the requirement is that outsiders cannot read the file, ask for encryption by name, as the workbook password guide does. Encrypt also returns the encrypted workbook as a stream and stores the password on the workbook, which is why the SaveAs that follows writes an encrypted file. WorkBook.Load with a password opens the result.
A Result You Can Reproduce
The test is one prompt and no code from you. Open a fresh session in an empty folder, paste the prompt, and compare what comes back with the pass list under it.
IRONXL_LICENSE_KEY.The prompt
Write a .NET 9 console program that merges two order exports into a regional sales workbook.
The working directory should be empty.
If a project or any source file is already there, tell me and stop.
Nobody can answer questions, so write, build, run and repair the program yourself.
Note every assumption you settle on, and put all deliverables in the project root.
1. Install the IronXL.Excel NuGet package pinned to version 2026.10.1.
Don't add any other release.
2. Use https://ironsoftware.com/excel/csharp/llms.txt and the guides it links as your reference.
Call no IronXL member they leave out.
3. At startup, assign IronXL.License.LicenseKey from the IRONXL_LICENSE_KEY environment variable.
Don't let the key appear in any file in the project folder.
The program reads that variable itself, so never print its value.
Don't list environment variables either.
If IronXL.License.IsLicensed is false, say so and exit.
4. Write a generator for the two input files.
Use random seed 2026, and create the inputs only when they're absent.
Every order in both files follows these rules:
- OrderIds are six digits with leading zeros.
- They count up from 000101 and never repeat across the two files.
- Dates fall between July 1 and September 30, 2026.
- Regions are North, South, East, and West in unequal shares.
- Quantity is 1 to 40.
- Every UnitPrice has cents other than .00.
Products come from a catalog of eight or more names.
At least two names contain each of these:
- A semicolon.
- A double quote.
- A letter outside ASCII. An accented e or a German sharp s will do.
orders.csv holds 200 orders in this shape:
- It's UTF-8 and semicolon-delimited.
- Its header is OrderId;Date;Region;Product;Quantity;UnitPrice.
- It quotes the fields with those characters in RFC 4180 style.
legacy.xls is a genuine Excel 97-2003 workbook written by IronXL.
It holds 50 further orders under the same six headers, stored like this:
- OrderId cells are text.
- Date cells are dates.
- Quantity and UnitPrice cells are numbers.
Then write manifest.csv from the generator's in-memory records:
- It's comma-delimited and quoted in the same RFC 4180 style.
- Each order gets one row with its source file and all six values.
5. Measure the inputs before the first load.
Whenever a figure falls outside its range, fix the generator and generate the inputs again.
orders.csv needs exactly 200 data rows.
Count these three kinds of rows in it separately. Each count must be 15 or more:
- Rows with a semicolon in Product.
- Rows with a double quote.
- Rows with a non-ASCII letter.
Then measure these figures:
- OrderIds that start with 0: all 250.
- Prices with cents other than .00: 225 or more.
- The first eight bytes of legacy.xls: D0 CF 11 E0 A1 B1 1A E1.
- Order counts per region: four different numbers.
- Revenue per region: every two regions at least 1,000 apart.
Once the program has loaded the inputs for the first time, orders.csv and legacy.xls are frozen.
Don't rewrite or edit them.
6. Load both inputs and save sales-report.xlsx.
Its Orders sheet holds all 250 orders under the six input headers plus Revenue:
- OrderId is text.
- OrderId, Region and Product are identical to the input.
- Date is a date, and Quantity and UnitPrice are numbers.
- Revenue is a formula multiplying Quantity by UnitPrice in every row.
The Summary sheet has the columns Region, Units, and Revenue:
- It has one row per region with Units and Revenue as SUMIF formulas over the Orders sheet.
- A Total row of SUM formulas follows the region rows.
- Add a column chart of revenue by region to Summary.
Give Revenue a currency format.
Make the header row bold and frozen on both sheets.
The saved file must hold every formula's current result.
That way a reader that never calculates formulas sees the same figures.
7. The import is one fixed procedure.
The procedure has these rules:
- Use one IronXL load call with set options per file.
- Don't parse any input file by hand.
- Apply one conversion rule per column to every row.
Loading and report code may not do any of these things:
- Open manifest.csv.
- Hold an OrderId, product name, quantity or price as a literal.
- Compare a cell with an expected value.
- Patch individual rows.
Only the round-trip code reads the manifest.
Changing the procedure between runs is your job and never the program's.
8. Save sales-report-protected.xlsx, a copy that no one can open without the password Q3-review.
Encrypt the file. Locking sheets doesn't count.
9. Build in Release and run.
10. Reload both workbooks through IronXL and write roundtrip.md.
Start with each step 5 measurement as a number, then describe the import procedure.
After that, add a table with the columns check, expected, actual, and match.
The table has 16 rows, in this order:
- The Orders row count.
- Units for each region, then revenue for each region.
- Total units and total revenue.
- How many OrderIds and how many product names in Orders match the input exactly, 250 each.
- The number of charts on Summary.
- Whether the protected copy refuses both no password and a wrong one.
- Whether Q3-review opens it with 250 orders.
Expected figures come from the manifest, and actual figures from the reloaded workbooks.
Money must agree to the cent and the rest exactly.
11. Repair the program while any of the 16 rows fails.
Each time, read the failing rows and change the import or report code.
Then build and execute the program once more.
If the eighth execution still leaves failures, stop.
List those rows, every import procedure you tried, and your explanation of the cause.
When you're done, tell me these things, even if you stopped at step 11:
- The build result.
- The number of rows matched.
- The import procedure.
- The step 5 figures.
- Your assumptions.
We calibrated the prompt with a reference program on IronXL 2026.10.1 and seed 2026. Importing through LoadCSV with an XLSX format, a semicolon delimiter, and field conversion on, then copying the converted values, matched 9 of 16 rows. All 200 CSV OrderIds lost their leading zeros, and every region's units came up short because 48 quantities after an escaped quote stayed text. Importing with conversion off and copying the strings matched 8 of 16, because the prices 8.27 and 10.11 became dates, which pushed North's revenue to 3.9 times its true value and South's to 2.9 times. Parsing each column explicitly and writing typed values matched 16 of 16 on seeds 2026, 77, 4101, and 12345. An earlier draft of this prompt passed 9 of 9 on IronXL 2026.9.2 with plain ASCII product names, bare numeric IDs, and legacy totals read by the same code that built the report, so it tested little.
Output
This picture is a rendering of the Summary sheet in the run's sales-report.xlsx, drawn from the values and the chart the saved file stores, and not a screenshot taken in Excel. The run's unedited round-trip table holds every step 5 measurement, the import procedure, and the 16 rows.
- The program's first execution stopped at the step 5 check, because North and South both had 90 orders and their revenues were 921.94 apart. Claude Code widened the region shares, generated the inputs again, and matched all 16 rows on the next execution, so the repair loop in step 11 never ran.
- On this run's
orders.csv, a load with conversion on kept none of the 200 OrderIds as text with a leading zero and left 38 quantities as text, so the obvious import would have failed here too. - Before it wrote the program, Claude Code tried IronXL's CSV import in a scratch folder and picked the safe procedure up front. It loads the XLS with
WorkBook.Loadand gives each column one rule that tests the cell's own type. - The inputs measured 200 CSV orders, with 43 products holding a semicolon, 38 an escaped quote, and 48 a non-ASCII letter, and 9 of 9 step 5 measurements fell in range.
- Summary holds 8 SUMIF and 2 SUM formulas with stored totals of 5,337 units and $549,169.80, plus one column chart. The encrypted copy opens with Q3-review to 250 orders.
- Some steps ran differently from the page. Claude Code counted the CSV rows from the file itself but took the figures that span both files from the generator's records, while
roundtrip.mdsays they came from the input files. It loaded both inputs throughLoadingOptions, which no pagellms.txtlinks documents, and it checked the key withenv | grep -c, which lists the environment variables into a count. The Step 1, 3, 5, and 7 prompts followed in the same session. The install kept the 2026.10.1 pin. The documentation prompt foundPhysicalRowCountonly in the API reference and replacedLoadingOptionswithWorkBook.LoadCSVandWorkBook.Load, so the published round-trip file describes that import. It matched 16 of 16 again. The setup prompt wrote the rules toCLAUDE.mdand savedskill.mdas a project skill. The self-check named a documentation page for each member, found 69 of 69 sampled cells in agreement, and matched all 250 rows of each workbook with the manifest. We measured every pass criterion again on the saved files without IronXL, and a fresh Release build of the program produced the same table.
What passes
- The project builds in Release with no manual edits.
- All 16 rows of
roundtrip.mdmatch, and its regional and total figures equal the totals of the input files. - A search of the project folder finds the license key in no file.
The run record
- The runs use one Windows 11 x64 desktop with a Core i9-14900KF and 64 GB of memory.
- Every project targets .NET 9.
- Every guide uses
IronXL.Excel2026.10.1 as its only IronXL package, except the Claude Code guide, whose run installed 2026.10.5. ChatGPT Codex addedMicrosoft.Extensions.DependencyInjection9.0.20 to its converter, and the Codex, Copilot, Cursor, and Antigravity test projects run on xUnit. - A guide's duration is the sum of the logged times of the prompts on its page, and this guide's row counts the acceptance prompt alone.
- Last tested: October 15, 2026, with this guide's run. Google Antigravity was tested on October 14. Claude Code and GitHub Copilot were tested on October 13, Cursor on October 9, and ChatGPT Codex on October 7, 2026.
| Guide | Assistant and version | Model | Duration (minutes) |
|---|---|---|---|
| This guide | Claude Code 2.1.277, one session, permission prompts off | Claude Opus 5 | 16.4 |
| Claude Code | Claude Code 2.1.277, prompt 3 in plan mode | Claude Sonnet 5, with Claude Opus 5 for prompt 3 | 53.8 |
| ChatGPT Codex | Codex CLI 0.160.0 | GPT-6 Luna | 59.0 |
| GitHub Copilot | GitHub Copilot CLI 1.0.97 | GPT-6 Luna, routed by Auto | 14.5 |
| Cursor | Cursor 3.23.23 desktop app | Grok 4.7 | 53.1 |
| Google Antigravity | Antigravity CLI 1.3.5 | Gemini 3.8 Flash (High) | 44.9 |
Agent-Specific Guides
Each guide below applies the steps above to one tool and one spreadsheet job.
- Use IronXL with Claude Code for reading million-row workbooks with forward-only streaming, with memory and time measured against a full workbook load
- Use IronXL with ChatGPT Codex for converting a folder of mixed XLS, XLSX, CSV, and TSV files to CSV, JSON, and XML, with a results row for each input and handling for corrupt or protected files
- Use IronXL with GitHub Copilot for styling the output of an existing reporting solution, with tests that reload each workbook and assert its formats
- Use IronXL with Cursor for moving workbook editing code off Office Interop, under rules that keep Interop and EPPlus calls out
- Use IronXL with Google Antigravity for an ASP.NET Core page that previews, validates, and cleans an uploaded workbook, proven by uploads in a live browser session
Troubleshooting
- IronXL File Size Limits when an XLS workbook runs out of rows
- Apply a License Key in IronXL once the first workbook call throws LicensingException
- FileNotFoundException for IronXL.XmlSerializers on .NET 10 when a debugger breaks inside the save call although the file is written
Questions?
If you have any questions, reach out to support@ironsoftware.com
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.