---
title: "How to build a .NET MAUI PDF viewer with the Nutrient SDK"
canonical_url: "https://www.nutrient.io/blog/how-to-build-a-dotnet-maui-pdf-viewer/"
md_url: "https://www.nutrient.io/blog/how-to-build-a-dotnet-maui-pdf-viewer.md"
last_updated: "2026-08-11T02:52:57.354Z"
description: "Learn how to build a cross-platform .NET MAUI PDF viewer with the native Nutrient MAUI SDK, running on Android, iOS, macOS, and Windows from one codebase."
---

**TL;DR**

You can add a PDF viewer to a.NET MAUI app with the native [Nutrient MAUI SDK](https://www.nutrient.io/guides/maui.md):

- Install the `Nutrient.MAUI.SDK` NuGet package and register it in `MauiProgram.cs`.

- Add the `PDFView` control to your XAML and load a document in its `Initialized` handler.

- Run the same codebase on Android, iOS, macOS, and Windows.

In this post, you’ll learn how to build a cross-platform PDF viewer in a.NET MAUI app using [Nutrient MAUI SDK](https://www.nutrient.io/guides/maui.md) — a native SDK that exposes a `PDFView` control you can drop straight into your XAML.

[.NET MAUI](https://learn.microsoft.com/en-us/dotnet/maui/what-is-maui) stands for.NET Multi-platform App UI. It’s Microsoft’s framework for building native cross-platform mobile and desktop applications from a single codebase using.NET.

An earlier version of this post embedded Nutrient Web SDK in a MAUI Blazor app. That workaround is no longer necessary: The native Nutrient MAUI SDK now integrates directly through XAML. If you have a specific reason to use the Web SDK in a Blazor hybrid app instead, [let us know](https://www.nutrient.io/support/request/).

## Architecture and features.NET MAUI is the successor to Microsoft’s Xamarin project, which reached end of life in May 2024. It was architected from the ground up to offer:

- Unification of projects — A single multitargeted setup out of the box.

- Truly native applications — They run on the native infrastructure of each supported platform.

- Optimized compilation —.NET for iOS does ahead-of-time (AOT) compilation to produce ARM binaries for the App Store, while.NET for Android uses a mix of just-in-time (JIT) and AOT compilation on the device.

- A single codebase that targets Android, iOS, macOS, and Windows.![Diagram of the.NET MAUI cross-platform architecture](@/assets/images/blog/2022/how-to-build-a-dotnet-maui-pdf-viewer-with-pspdfkit/arch.png)

It also ships with MVVM and XAML support, a set of layouts, and a large library of cross-platform views and controls.![Overview of.NET MAUI layouts, views, and controls](@/assets/images/blog/2022/how-to-build-a-dotnet-maui-pdf-viewer-with-pspdfkit/controls.png)

## Requirements

To follow along, you’ll need:

- For Windows — Visual Studio 2022 17.3 or greater, with the **.NET Multi-platform App UI development** workload installed.

- For Mac — Visual Studio Code with the.NET MAUI prerequisites installed.

[Nutrient MAUI SDK](https://www.nutrient.io/guides/maui.md) supports four platforms from a single codebase: Android, iOS, macOS (through Mac Catalyst), and Windows.

## Creating a new MAUI project

If you already have a MAUI project, skip ahead to [adding the Nutrient dependency](#adding-the-nutrient-dependency). Otherwise, create one.

In Visual Studio, choose **Create a new project**, select **.NET MAUI App**, and then set the project name and target framework.

From the command line, run:

```bash

dotnet new maui -n "Nutrient Demo"
cd "Nutrient Demo"

```

## Adding the Nutrient dependency

1. Open your project file and change the first line from `<Project Sdk="Microsoft.NET.Sdk">` to `<Project Sdk="Microsoft.NET.Sdk.Razor">`. Then save.

2. Add the [`Nutrient.MAUI.SDK` NuGet package](https://www.nuget.org/packages/Nutrient.MAUI.SDK) — either through the NuGet Package Manager in Visual Studio or from the command line:

   ```bash

   dotnet add package Nutrient.MAUI.SDK
   ```

3. Open `MauiProgram.cs` and call `RegisterPSPDFKitSdk()` on the builder:

   ```csharp

   public static MauiApp CreateMauiApp()
   {
      var builder = MauiApp.CreateBuilder();
      builder.UseMauiApp<App>().RegisterPSPDFKitSdk().ConfigureFonts(fonts =>
         {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
         });

   #if DEBUG

      builder.Logging.AddDebug();
   #endif

      return builder.Build();
   }
   ```

## Displaying a PDF

1. In the `Resources/Raw` folder, create an `Assets` folder and add a PDF file named `demo.pdf`.

   The folder has to be named `Assets`. PDFs in this folder can be loaded with the [`LoadDocumentFromAssetsAsync`](https://www.nutrient.io/guides/maui/open-a-document/from-app-assets/) API.

2. Open `MainPage.xaml`, remove the existing content of `ContentPage`, and add the `PDFView` control along with its namespace:

   ```xml

   <ContentPage xmlns:pspdfkit="clr-namespace:PSPDFKit.Sdk;assembly=Sdk">
      <pspdfkit:PDFView x:Name="PDFView" Initialized="OnPDFViewInitialized" />
   </ContentPage>
   ```

3. If you’ve purchased a license and [assigned it to a bundle ID](https://www.nutrient.io/guides/maui/troubleshooting/what-is-a-bundle-id.md), set it per platform. Omitting the `License` property initializes `PDFView` in trial mode:

   ```xml

   <pspdfkit:PDFView x:Name="PDFView"
               License="{OnPlatform
                  Android={StaticResource AndroidLicenseKey},
                  iOS={StaticResource iOSLicenseKey},
                  MacCatalyst={StaticResource MacCatalystLicenseKey},
                  WinUI={StaticResource WindowsLicenseKey}}" />
   ```

4. In `MainPage.xaml.cs`, handle the `Initialized` event and load `demo.pdf`:

   ```csharp

   private async void OnPDFViewInitialized(object sender, EventArgs e)
   {
      try
      {
         var configuration = PDFView.Controller.CreateViewerConfiguration();
         await PDFView.Controller.LoadDocumentFromAssetsAsync("demo.pdf", configuration);
      }
      catch (Exception ex)
      {
         // Handle exception.
      }
   }
   ```

   Wait for the `PDFView` to finish initializing before using `PDFView.Controller`. Loading a document earlier will fail.

## Running on each platform

With the document wired up, build and run the same project on any supported platform.

In Visual Studio, choose the platform in the **Debug** toolbar and select **Build** > **Build Solution**. Then start the app. From the command line, target each framework directly:

```bash

dotnet build -t:Run -f net10.0-android              # Android

dotnet build -t:Run -f net10.0-ios                  # iOS

dotnet build -t:Run -f net10.0-maccatalyst          # macOS

dotnet build -t:Run -f net10.0-windows10.0.19041.0  # Windows

```

You’ll see `demo.pdf` rendered in the Nutrient UI on each target.

## Open source options vs. Nutrient

For _generating_ PDFs in.NET, open source libraries like **QuestPDF** and **PDFsharp** work well — they create documents programmatically from code. What they don’t provide is a way to display, annotate, or let users interact with PDFs inside a MAUI app, and.NET MAUI has no built-in PDF viewer of its own.

That’s the gap the native Nutrient MAUI SDK fills: a XAML `PDFView` control with viewing, annotation, form filling, and signing across Android, iOS, macOS, and Windows. Use an open source generator if you only need to produce PDFs on the server or in code; reach for Nutrient when your app needs to render and edit them.

## Conclusion

With.NET MAUI and the native Nutrient MAUI SDK, you can add PDF viewing, annotation, and editing to a single codebase that runs on Android, iOS, macOS, and Windows. For a complete sample, see the [Nutrient MAUI example project on GitHub](https://github.com/PSPDFKit/pspdfkit-maui-catalog).

To go further, follow the [getting started guide](https://www.nutrient.io/sdk/maui/getting-started.md) and explore [annotations](https://www.nutrient.io/guides/maui/annotations.md) and [UI customization](https://www.nutrient.io/guides/maui/user-interface.md).

## Links

Here are some additional links worth checking out:

- [.NET MAUI on GitHub](https://github.com/dotnet/maui)

- [.NET MAUI Community Toolkit](https://github.com/CommunityToolkit/Maui)

- [Build mobile and desktop apps with.NET MAUI](https://learn.microsoft.com/en-us/training/paths/build-apps-with-dotnet-maui/)

- [Learn.NET MAUI — full course for beginners](https://www.youtube.com/watch?v=DuNLR_NJv8U)

## FAQ

#### How do I integrate a PDF viewer in a.NET MAUI app?

Add the `Nutrient.MAUI.SDK` NuGet package, register it in `MauiProgram.cs`, and place the `PDFView` control in your XAML.

#### Does Nutrient support multiplatform.NET MAUI development?

Yes. Nutrient MAUI SDK runs on Android, iOS, macOS (through Mac Catalyst), and Windows from a single codebase.

#### What are the requirements for using Nutrient MAUI SDK?

On Windows, you need Visual Studio 2022 17.3 or greater with the.NET MAUI workload. On Mac, you need Visual Studio Code with the.NET MAUI prerequisites.

#### Can I build the PDF viewer UI with XAML?

Yes. `PDFView` is a native XAML control, so you can add it directly to your pages and bind to it like any other MAUI control.

#### Which file types does Nutrient MAUI SDK support?

It supports PDF documents and common image formats, including PNG, JPEG, JPG, TIFF, and TIF.

#### How do I migrate a Xamarin PDF viewer to.NET MAUI?.NET MAUI is the successor to Xamarin, which reached end of life in May 2024. To move a Xamarin PDF viewer to MAUI, add the `Nutrient.MAUI.SDK` NuGet package, register it in `MauiProgram.cs`, and place the `PDFView` control in your XAML. The same native viewer then runs on Android, iOS, macOS, and Windows from a single codebase.
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Best Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Extraction Confidence Scores](/blog/document-extraction-confidence-scores.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [How To Build A Javascript Pdf Viewer](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [or](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [or](/blog/how-to-convert-html-to-pdf-using-react.md)
- [How To Convert Html To Pdf Using Wkhtmltopdf And Csharp](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-csharp.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [How To Merge Pdfs Using Javascript](/blog/how-to-merge-pdfs-using-javascript.md)
- [How To Ocr Pdfs In Linux](/blog/how-to-ocr-pdfs-in-linux.md)
- [How To Print Pdf In Csharp](/blog/how-to-print-pdf-in-csharp.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Javascript Pdf Editors](/blog/javascript-pdf-editors.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [or](/blog/merge-pdfs.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [Building WCAG 2.2, Section 508, and PDF/UA-compliant PDFs with an SDK](/blog/pdf-accessibility.md)
- [Pdf Data Extraction Developer Guide](/blog/pdf-data-extraction-developer-guide.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Extraction Document Case Studies](/blog/pdf-extraction-document-case-studies.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdfjs Accessibility Structtree Printing](/blog/pdfjs-accessibility-structtree-printing.md)
- [Pdfjs Advanced Loading Streaming Workers](/blog/pdfjs-advanced-loading-streaming-workers.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Document Outline Bookmarks Metadata](/blog/pdfjs-document-outline-bookmarks-metadata.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [macOS](/blog/pdfjs-file-format-conversion-to-pdf.md)
- [macOS](/blog/pdfjs-generating-pdf-thumbnails-pdf2pic.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [or](/blog/sample-blog-updated.md)
- [Sdk Product Updates Q2 2026](/blog/sdk-product-updates-q2-2026.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [Define the HTML part of the document.](/blog/top-10-ways-to-generate-pdfs-in-python.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [or](/blog/top-js-pdf-libraries.md)
- [Convert an HTML file to PDF.](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-processing.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

