フッターコンテンツにスキップ
移行ガイド

C#でNReco PDFジェネレーターからIronPDFへ移行する方法

なぜNReco PDFジェネレーターからIronPDFへ移行するのか

NRecoPDFジェネレータの重大なセキュリティ問題

NReco PDF Generatorは、非推奨のwkhtmltopdfバイナリをラップし、そのセキュリティ脆弱性をすべて継承しています。 これは机上の空論ではありません。wkhtmltopdfが2020年に放棄されて以来、20以上のCVEが文書化されており、パッチは提供されていません:

  • CVE-2020-21365:サーバー側リクエストフォージェリ(SSRF)
  • CVE-2022-35583: HTMLインジェクションによるローカルファイルの読み取り
  • CVE-2022-35580:リモートコード実行の可能性

基礎となるwkhtmltopdfプロジェクトはもはや保守されていないため、これらの脆弱性にパッチを当てることはできません。

追加の NReco PDF ジェネレーターの制限

1.透かし入り無料バージョン:実稼働環境で使用するには、価格が不明瞭な有料ライセンスが必要で、営業担当者に問い合わせる必要があります。

2.非推奨のレンダリング エンジン: WebKit Qt (2012 年頃) は、限定的な最新の Web サポートを提供します。

  • CSSグリッドやFlexboxを使用しない
  • 最新のJavaScript(ES6+)は使用しないでください。
  • 貧弱なウェブフォントサポート
  • CSS変数やカスタムプロパティを使用しない

3.外部バイナリ依存関係:プラットフォームごとに wkhtmltopdf バイナリ ( wkhtmltopdf.exewkhtmltox.dll ) を管理する必要があります。

4.アクティブな開発なし:ラッパーは、基盤となるエンジンの更新なしでメンテナンスを受けます。

5.非同期サポートの制限:同期 API は Web アプリケーション内のスレッドをブロックします。

NReco PDF GeneratorとIronPDFの比較

アスペクト NReco PDFジェネレータ IronPDF
レンダリングエンジン WebKit Qt (2012) クロミウム(現在)
セキュリティ 20以上のCVE、パッチなし アクティブなセキュリティアップデート
CSSサポート CSS2.1、限定的なCSS3 フルCSS3、グリッド、フレックスボックス
JavaScript 基本的なES5 完全なES6+、async/await
依存関係 外部wkhtmltopdfバイナリ 自己完結型
非同期サポート 同期のみ 完全なasync/await
ウェブフォント 制限的 フルGoogleフォント、@font-face
ライセンス 価格は不明です。 透明性のある価格設定
無料トライアル 透かし入り 全機能

2025年、2026年まで.NET 10とC# 14の採用を計画しているチームにとって、IronPDFはアクティブな開発と最新のレンダリング機能を備えた将来性のある基盤を提供します。


始める前に

前提条件

  1. .NET 環境: .NET Framework 4.6.2+ または .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGetアクセス: NuGetパッケージをインストールする機能
  3. IronPDFライセンス: ironpdf.comからライセンスキーを取得します。

NuGetパッケージの変更

# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator

# Install IronPDF
dotnet add package IronPdf
# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator

# Install IronPDF
dotnet add package IronPdf
SHELL

また、配備からwkhtmltopdfバイナリを削除してください:

  • wkhtmltopdf.exewkhtmltox.dllをプロジェクトから削除してください。
  • wkhtmltopdfインストールスクリプトの削除
  • プラットフォーム固有のバイナリフォルダの削除

ライセンス構成

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

NRecoPDFジェネレーターの使用法を特定する

# Find all NReco.PdfGenerator references
grep -r "NReco.PdfGenerator\|HtmlToPdfConverter\|GeneratePdf" --include="*.cs" .
# Find all NReco.PdfGenerator references
grep -r "NReco.PdfGenerator\|HtmlToPdfConverter\|GeneratePdf" --include="*.cs" .
SHELL

完全な API リファレンス

コア クラス マッピング

NReco PDFジェネレータ IronPDF ノート
HtmlToPdfConverter ChromePdfRenderer メインレンダラー
ページマージン 個々のマージン特性 MarginTop、MarginBottomなど。
ページの向き PdfPaperOrientation 列挙
ページサイズ PdfPaperSize 列挙

レンダリング メソッド マッピング

NReco PDFジェネレータ IronPDF ノート
GeneratePdf(html)を実行してください。 RenderHtmlAsPdf(html)を使用してください。 PdfDocument を返します。
GeneratePdfFromFile(url, output)</code>|RenderUrlAsPdf(url)`を使用してください。 直接URLサポート
GeneratePdfFromFile(htmlPath, output)</code>|RenderHtmlFileAsPdf(path)`を実行してください。 ファイルパス
(非同期はサポートされていません)_。 RenderHtmlAsPdfAsync(html) 非同期バージョン
(非同期はサポートされていません)_。 RenderUrlAsPdfAsync(url)を使用してください。 非同期バージョン

ページ構成マッピング

NReco PDFジェネレータ IronPDF ノート
ページ幅 = 210 RenderingOptions.PaperSize=PdfPaperSize.A4 enum または SetCustomPaperSize を使用してください。
PageHeight = 297 RenderingOptions.SetCustomPaperSizeinMilimeters(w, h). カスタムサイズ
Orientation = PageOrientation.Landscape です。 RenderingOptions.PaperOrientation=PdfPaperOrientation.Landscape 風景
サイズ = PageSize.A4 RenderingOptions.PaperSize=PdfPaperSize.A4 用紙サイズ列挙

マージン マッピング

NReco PDFジェネレータ IronPDF ノート
マージン.トップ = 10 RenderingOptions.MarginTop = 10. 単位:ミリメートル
Margins.Bottom = 10. RenderingOptions.MarginBottom = 10. 単位:ミリメートル
Margins.Left = 10. RenderingOptions.MarginLeft = 10. 単位:ミリメートル
Margins.Right = 10. RenderingOptions.MarginRight = 10. 単位:ミリメートル
new PageMargins { ... } 個々のプロパティ マージンなし

ヘッダー/フッター プレースホルダー マッピング

NReco PDFジェネレータ(wkhtmltopdf) IronPDF ノート
[ページ]|{ページ}` 現在のページ番号
[トップページ] {総ページ数} 総ページ数
[日付] `{date} 現在の日付
[時間]|{時間}` 現在の時間
[タイトル] `{html-title} 文書タイトル

出力処理のマッピング

NReco PDFジェネレータ IronPDF ノート
byte[] pdfBytes = GeneratePdf(html). PdfDocument pdf = RenderHtmlAsPdf(html). オブジェクトを返します
File.WriteAllBytes(path, bytes). pdf.SaveAs(path)のようにします。 直接保存
pdfBytesを返す pdf.BinaryDataを返す バイト配列を取得
new MemoryStream(pdfBytes). pdf.Stream` ストリーム

コード移行の例

例1: 基本的なHTMLからPDFへ

翻訳前 (NReco PDF Generator):

// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
        var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
        var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
$vbLabelText   $csharpLabel

翻訳後(IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

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

基本的な違いは、戻り値の型と保存パターンです。 NReco PDF GeneratorのHtmlToPdfConverter.GeneratePdf()は、Byte[]を返すので、File.WriteAllBytes()を使って手動でディスクに書き込む必要があります。 IronPDFのChromePdfRenderer.RenderHtmlAsPdf()は組み込みのSaveAs()メソッドを持つPdfDocumentオブジェクトを返します。

このオブジェクト指向のアプローチは、保存する前にPDFを操作(透かしを追加したり、文書をマージしたり、セキュリティを追加したり)できるという、さらなる利点を提供します。 既存のコードとの互換性のために生のバイトが必要な場合は、pdf.BinaryDataを使用してください。 その他のレンダリングオプションについては、HTML to PDF documentationを参照してください。

例2: 余白を使ったカスタムページサイズ

翻訳前 (NReco PDF Generator):

// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        htmlToPdf.PageWidth = 210;
        htmlToPdf.PageHeight = 297;
        htmlToPdf.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
        var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
        var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
        File.WriteAllBytes("custom-size.pdf", pdfBytes);
    }
}
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        htmlToPdf.PageWidth = 210;
        htmlToPdf.PageHeight = 297;
        htmlToPdf.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
        var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
        var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
        File.WriteAllBytes("custom-size.pdf", pdfBytes);
    }
}
$vbLabelText   $csharpLabel

翻訳後(IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("custom-size.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("custom-size.pdf");
    }
}
$vbLabelText   $csharpLabel

NReco PDF Generatorは、数値寸法(PageWidth = 210, PageHeight=297)とPageMarginsオブジェクトを使用します。 IronPDFはPdfPaperSize列挙型(A4、レター、リーガルのような標準サイズを含む)とRenderingOptionsオブジェクトの個々のマージンプロパティを使用します。

主な移行の変更点

  • PageWidth/PageHeightRenderingOptions.PaperSize=PdfPaperSize.A4。です。
  • new PageMargins { Top = 10, ... }→ 個々のプロパティ:RenderingOptions.MarginTop = 10 です。

列挙でカバーされていないカスタム用紙サイズについては、RendereringOptions.SetCustomPaperSizeinMilimeters(width, height)を使用してください。 ページ構成オプションの詳細については、こちらをご覧ください。

例3: URLからPDFへの変換

翻訳前 (NReco PDF Generator):

// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        var pdfBytes = htmlToPdf.GeneratePdfFromFile("https://www.example.com", null);
        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        var pdfBytes = htmlToPdf.GeneratePdfFromFile("https://www.example.com", null);
        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
$vbLabelText   $csharpLabel

翻訳後(IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

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

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

NReco PDF Generatorは、GeneratePdfFromFile()という紛らわしい名前のメソッドを、ローカルファイルとURLの両方に、NULL可能な第2引数付きで使用します。 IronPDFは専用のメソッドを提供します:RenderUrlAsPdf()はURLに対して、RenderHtmlFileAsPdf()はローカルのHTMLファイルに対してです。

IronPdfのアプローチはよりすっきりしていて直感的です。非同期ウェブアプリケーションでは、await renderer.RenderUrlAsPdfAsync(url) を使ってスレッドのブロックを避けてください。


重要な移行に関する注意事項

ズーム値変換

NReco PDF Generatorは浮動小数点数(0.0-2.0)を使用し、IronPDFはパーセント整数を使用します:

// NReco PDF Generator: Zoom = 0.9f (90%)
// IronPDF: Zoom = 90

// Conversion formula:
int ironPdfZoom = (int)(nrecoZoom * 100);
// NReco PDF Generator: Zoom = 0.9f (90%)
// IronPDF: Zoom = 90

// Conversion formula:
int ironPdfZoom = (int)(nrecoZoom * 100);
$vbLabelText   $csharpLabel

プレースホルダーの構文の更新

すべてのヘッダー/フッターのプレースホルダーを更新する必要があります:

NReco PDFジェネレータ IronPDF
[ページ] {ページ}
[トップページ] {総ページ数}
[日付] `{date}
[タイトル]` {html-title}
// NReco PDF Generator:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

// IronPDF:
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    MaxHeight = 20
};
// NReco PDF Generator:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

// IronPDF:
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    MaxHeight = 20
};
$vbLabelText   $csharpLabel

返品タイプの変更

NReco PDF Generatorはbyte[]を直接返します; IronPDFはPdfDocumentを返します:

//NReco PDFジェネレータpattern:
byte[] pdfBytes = converter.GeneratePdf(html);
File.WriteAllBytes("output.pdf", pdfBytes);

//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
//NReco PDFジェネレータpattern:
byte[] pdfBytes = converter.GeneratePdf(html);
File.WriteAllBytes("output.pdf", pdfBytes);

//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
$vbLabelText   $csharpLabel

スレッドの安全性と再利用性

NReco PDF Generatorは通常、呼び出しごとに新しいコンバータを作成します。 IronPDFのChromePdfRendererはスレッドセーフで再利用可能です:

//NReco PDFジェネレータpattern (creates new each time):
public byte[] Generate(string html)
{
    var converter = new HtmlToPdfConverter();
    return converter.GeneratePdf(html);
}

//IronPDFpattern (reuse renderer, thread-safe):
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

public byte[] Generate(string html)
{
    return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
//NReco PDFジェネレータpattern (creates new each time):
public byte[] Generate(string html)
{
    var converter = new HtmlToPdfConverter();
    return converter.GeneratePdf(html);
}

//IronPDFpattern (reuse renderer, thread-safe):
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

public byte[] Generate(string html)
{
    return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
$vbLabelText   $csharpLabel

非同期サポート (新機能)

IronPDFはNReco PDF Generatorが提供できない非同期/待機パターンをサポートしています:

// NReco PDF Generator: No async support available

// IronPDF: Full async support
public async Task<byte[]> GenerateAsync(string html)
{
    var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
// NReco PDF Generator: No async support available

// IronPDF: Full async support
public async Task<byte[]> GenerateAsync(string html)
{
    var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
$vbLabelText   $csharpLabel

トラブルシューティング

問題 1: HtmlToPdfConverter が見つかりません

問題:IronPDFにHtmlToPdfConverterクラスが存在しません。

解決策: ChromePdfRendererを使用する:

// NReco PDF Generator
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();
// NReco PDF Generator
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

問題2: GeneratePdfが間違った型を返す

問題:コードはbyte[]を期待しますが、 PdfDocumentを取得します。

解決策: .BinaryDataプロパティにアクセスします。

// NReco PDF Generator
byte[] pdfBytes = converter.GeneratePdf(html);

// IronPDF
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
// NReco PDF Generator
byte[] pdfBytes = converter.GeneratePdf(html);

// IronPDF
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
$vbLabelText   $csharpLabel

問題 3: PageMargins オブジェクトが見つかりません

問題:IronPDFにPageMarginsクラスが存在しません。

解決策:個別のマージンプロパティを使用します。

// NReco PDF Generator
converter.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };

// IronPDF
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
// NReco PDF Generator
converter.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };

// IronPDF
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
$vbLabelText   $csharpLabel

課題4:ページ番号が表示されない

問題: [page]および[topage]プレースホルダーが機能しません。

解決策:IronPDFプレースホルダー構文を更新します。

// NReco PDF Generator
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

// IronPDF
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    MaxHeight = 20
};
// NReco PDF Generator
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

// IronPDF
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    MaxHeight = 20
};
$vbLabelText   $csharpLabel

移行チェックリスト

移行前

  • コードベース内のすべてのNReco.PdfGenerator使用状況をインベントリする
  • CustomWkHtmlArgsCustomWkHtmlPageArgsすべての値を文書化します
  • プレースホルダーを含むすべてのヘッダー/フッター HTML テンプレートを一覧表示します
  • 非同期要件(Web コントローラー、サービス)を特定する
  • ズームと余白の設定を確認する
  • 比較のために既存のPDF出力をバックアップする
  • IronPDFライセンスキーを取得する

パッケージの変更

  • NReco.PdfGenerator NuGet パッケージを削除します
  • IronPdf NuGet パッケージをインストールします: dotnet add package IronPdf
  • 名前空間のインポートをusing NReco.PdfGenerator;からusing IronPdf;に更新します。

コードの変更

  • 起動時にライセンスキー設定を追加する -HtmlToPdfConverter`ChromePdfRendererに置き換える
  • GeneratePdf(html)RenderHtmlAsPdf(html)に置き換えます
  • GeneratePdfFromFile(url, null)RenderUrlAsPdf(url)に置き換えます
  • PageMarginsオブジェクトを個別の余白プロパティに変換します
  • ズーム値を浮動小数点数からパーセンテージに更新
  • プレースホルダー構文を更新:[ページ]{ページ}[トップページ]{total-pages}
  • File.WriteAllBytes()pdf.SaveAs()に置き換えます
  • 有益な場合は同期呼び出しを非同期に変換する

移行後

  • プロジェクト/デプロイメントからwkhtmltopdfバイナリを削除します
  • Dockerファイルを更新してwkhtmltopdfのインストールを削除します
  • PDF出力を比較する回帰テストを実行する
  • ヘッダー/フッターのプレースホルダーが正しくレンダリングされることを確認する
  • すべてのターゲットプラットフォーム(Windows、Linux、macOS)でテスト
  • CI/CD パイプラインを更新して wkhtmltopdf ステップを削除します
  • CVE の削除を確認するためにセキュリティスキャンを更新します

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。