Skip to content
Skip to content
Menu
A cup of dev
  • Home
  • About
  • Contact
  • Books and ink
A cup of dev

Package and deploy SPfx solutions using PnP PowerShell

By Eli H. Schei on Monday, 15 December 2025, 8:00Thursday, 11 December 2025, 13:00

Back in 2021, when I had just started this blog, I wrote a post explaining how to package and deploy SPFx solutions. It quickly became one of my most read articles, and it’s still on my top 10 most popular blogposts year after year. Most of the process is still the same today, but with SPFx version 1.22.0 introducing Heft as the new build system (replacing Gulp), a few things have change. And there have also been some changes to PnP PowerShell during the last 4 years. So I figured it was time to write an updated blogpost about this topic.

Related blogposts

  • 1
    Create an Entra ID App Registration for Interactive Login with PnP PowerShell When Working with SPFx Solutions
  • 2
    Package and deploy SPfx solutions using PnP PowerShell (this blogpost)
Prerequesites:

You need to have the PnP Powershell module installed to use the pnp powershell cmdlets used in this blogpost.

You also need to have an app registration setup to use for authentication when working with PnP PowerShell, as described in this blogpost

Building and packaging the code

The first step is to prepare your solution for deployment by creating a .sppkg file. To generate a .sppkg package file, navigate to your solution’s main directory and run the following commands.

For SPfx v 1.22.0 and forward

heft build
heft package-solution --production

For previous SPfx versions

gulp build
gulp bundle --ship
gulp package-solution --ship

Not much has changed in the build process with the move to heft. The main difference is that the separate bundle step has been removed, as the heft build command now handles both building and bundling.
Once the package-solution step completed, you’ll find the .sppkg file inside the SharePoint/Solutions folder. Tip: Keep this folder (or the path to the folder) handy, you’ll reference this file during deployment.

Deploying your solution to the app catalog using PnP PowerShell

If you would rather deploy your solution manually this page in the Microsoft Docs covers how to do it.

The destination for your SPFx solutions is the App Catalog. Each tenant can have only one tenant-wide App Catalog. A tenant administrator must create this before you can deploy any solutions. Microsoft provides detailed instructions on how to do this in their documentation.

Note: It is also possible to create site-specific App Catalogs, but solutions deployed there are only available within that particular site collection. This can be useful for testing purposes.

  • If an App Catalog exists, the command will return its URL.
  • If nothing is returned, it means there is currently no App Catalog in your tenant.

Deploy the app to the tenant App Catalog

1. Connect to SharePoint

First, connect to your SharePoint admin site using your Tenant ID, Client ID, and the admin URL.
Tip: You can find both the Tenant ID and Client ID in your app registration within Entra ID.

# Replace the placeholders with your actual values
$tenantId = "<YOUR_TENANT_ID>"
$appId    = "<YOUR_CLIENT_ID>"

# Connect to your SharePoint admin site
Connect-PnPOnline -Url "https://<YOUR_DOMAIN>-admin.sharepoint.com/" -ClientId $appId -Tenant $tenantId -Interactive

This command will prompt you to log in. Make sure to use an account with SharePoint admin permissions to ensure you have access. Once authenticated, you can run your PnP PowerShell commands against your tenant—but only with the permissions granted to your app registration. (Read more about app permissions in the previous blog post.)

2. Deploy the app to your tenant app catalog

If you’re unsure whether your tenant already has an App Catalog, you can check by connecting to your tenant and running:

Get-PnPTenantAppCatalogUrl

This will return the URL to your tenant app catalog – if there is one. If nothing is returned you need to create a tenant app catalog, or ask an administrator to do so for you.

To actually deploy the package you use the Add-PnPApp cmdlet

Tip, navigate into the solution folder before you run the Add-PnPApp cmlet, then you don’t have to worry about the path to the sppkg file, because you are allready there.

Add-PnPApp -Path .\YOUR_SOLUTION_PACKAGE.sppkg -Publish

Make the solution available tenant wide

To update the solution, use the same command as when you added it, but include the -Overwrite parameter. As the name suggests, this will replace the app if it already exists in the app catalog. To make the app available across the entire tenant, you can also include the -SkipFeatureDeployment parameter with Add-PnPApp, which ensures the solution is deployed to all sites.

# Make the solution available across the tenant
Add-PnPApp -Path .\YOUR_SOLUTION_PACKAGE.sppkg -Publish -SkipFeatureDeployment

# Update exisiting solution
Add-PnPApp -Path .\YOUR_SOLUTION_PACKAGE.sppkg -Publish -Overwrite

Deploy the solution to a site collection app catalog

Sometimes you may want to deploy a solution to a specific site collection rather than the tenant-wide app catalog. This is useful if the app is only relevant to one team or department, or if you want to test it in isolation before a full deployment.

# Connect to the site collection where you have an app catalog
Connect-PnPOnline -Url "https://<YOUR_DOMAIN>.sharepoint.com/sites/<NAME_OF_SITE>" -ClientId $appId -Tenant $tenantId -Interactive

Once connected, you can check if a site collection app catalog already exists using:

Get-PnPSiteCollectionAppCatalog


If there isn’t an app catalog, you can easily create one with:

Add-PnPSiteCollectionAppCatalog -Site "https://<YOUR_DOMAIN>.sharepoint.com/sites/<NAME_OF_SITE>"

After the app catalog is available, you can deploy your solution by adding it with Add-PnPApp, just like you would in the tenant-wide catalog, but you need to add the parameter -Scope Site .

Add-PnPApp -Path .\YOUR_SOLUTION_PACKAGE.sppkg -Scope Site

Summary

In this blogpost I covered the lifecycle of deploying a SharePoint Framework (SPFx) solution. You learned how to build the .sppkg package using Heft (or Gulp), deploy it tenant-wide to make it available across all sites, and how to deploy it to a site collection app catalog for targeted distribution.

The blog also explains how to connect to a specific site collection, verify or create a site collection app catalog, and upload your package using PnP PowerShell with the -Scope Site parameter.

Resources

  • SharePoint Framework Documentation (Microsoft docs)
  • SharePoint Framework v1.22: What’s in the Latest SPFx Update (Voitanos, article)
  • PnP PowerShell documentation
  • PnP cmdlets documentation (used in this blogpost):
    • Connect-PnPOnline
    • Get-PnPTenantAppCatalogUrl
    • Add-PnPApp
    • Get-PnPSiteCollectionAppCatalog
    • Add-PnPSiteCollectionAppCatalog

If you are interested in Microsoft 365 Development you might also like my other blogposts in this category.

Also, if you have any feedback or questions, please let me know in the comments below. 🙂

Thank you for reading, and happy coding!

/Eli

If you want to support my content you can

Share this:

  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on X (Opens in new window) X

Post navigation

Create an Entra ID App Registration for Interactive Login with PnP PowerShell When Working with SPFx Solutions

Leave a ReplyCancel reply

Eli H. Schei

I'm a front-end developer who mainly work in the Microsoft 365-sphere. As a developer I read a lot of blogs. And in my experience I can read multiple different blogposts about exactly the same topic, and only one of them makes sense to me. Therefore I’m adding my voice to the mix, and hopefully one of my blogposts will be the one that makes sense of a topic for you. You can learn more about me here.

Recent Posts

  • Package and deploy SPfx solutions using PnP PowerShell
  • Create an Entra ID App Registration for Interactive Login with PnP PowerShell When Working with SPFx Solutions
  • How to create columns in Dataverse using PowerShell
  • React in ListViewCommandSet – how to fix the “Cannot read properties of undefined (reading ‘id’)” error
  • How to Get Site-ID with Graph Explorer (and other SharePoint info)

Categories

  • Azure
    • Azure CLI
    • Azure functions
  • Level
    • Beginner
    • Intermediate
  • Microsoft 365 Development
    • Microsoft Authentication Library
    • Microsoft Graph
    • Microsoft Teams
    • PNP powershell
    • SharePoint Framework
    • SharePoint Online
  • Power Platform
    • Dataverse
    • PowerApps
      • PowerApps Component Framework
  • Tech Lead
  • Web development
    • Accessibility
    • Soft skills
    • Tips and tricks

Tags

accessibility app permissions ARIA azure Azure CLI azure functions Content creation custom themes dataverse Entra ID favorites git github ListViewCommandSet M365 CLI M365 development MS Graph PCF PnPjs PnP powershell power apps PowerApps Component Framework powershell quicktip react resources SharePoint Online Sideloading SPfx Teams teams app dev Teams apps Tech lead tools wcag webdev Windows terminal
©2025 A cup of dev | WordPress Theme by SuperbThemes.com