What is an optional package?
So you have a Universal Windows App. Over a period of time you added more and more functionality to the app. Now instead of bloating your base app, wouldn’t it be awesome if you could ship another app(s) that seamlessly plugs into your base app giving you the ability to componentize your Universal app? For example, let's say that you built a Piano app that lets users play their favorite tunes on their tablet or phones. Over time, you might want to add more functionality for example, add a song pack that let's users learn to play popular songs. Being able to customize that list of songs outside of your primary app and being able to monetize that separately would be awesome, right! Now you might think, well I could use other means to distribute a song pack such as your website, but what if there was a way to separate content out into its own appx package that gives you the benefit of being able to distribute it via the Windows Store or your choice of distribution and the Windows platform knows how to install the package and offers users a first class way to manage content on their device via Settings, so you can focus on building your app and getting the content ready. If you are trying to do this, componentizing portions of your base app into optional packages could be your solution!
Now you may be thinking about another UWP technology to extend your application - app extensions. The key difference is the level of trust. App extensions are meant for 3rd parties to build add-on experiences to your application which you may not trust fully. With optional packages the trust model is very different. The optional packages that you build all run with the identity of your base app. This makes it possible to load content from your optional packages in the process of your base app, making it very performant. Also optional packages is not just for content, you also have the ability to code in-proc!
In terms of distribution, given this is a separate package, you can license the app separate from your main app making this a great way to monetize your suite of apps. The platform also exposes APIs that allow you to download optional packages from within your app making it possible to provide an in-app purchase experience. Users are in control of the optional packages and can manage the optional packages i.e. uninstall them or move them to a separate drive via the Storage settings. Since optional packages is really part of your main application, uninstalling the main application also uninstalls the related optional packages.
What are the different scenarios where you would consider creating an optional package?
Back to our piano app example, distributing the song pack as an optional packages makes sense as you want to load the songs in your base app process giving you the ability to synchronize two audio channels in a performant way. As the base app and optional all have the same identity, your app has full access to the contents of the optional package as though the app is accessing files from its own install location making the interaction seamless.
Loading code & Related Sets
Let's say that now you want to add another feature to your piano app - a music synthesizer giving users the ability to modulate piano tones to create funky music! Optional packages let's you do that! You can load code from an optional package and load it in the main app process. If you are trying to load code out of an optional packages however, the platform requires a strict versioning between the main app and its optional packages we call this related sets. We will cover the specifics of how to define this tight relationship in an up coming blog but if you do not do this, you cannot load code from an optional package. If your main and optional packages are in a related set, the platform will enforce this relationship while it installs and updates the packages, ensuring that the versioning that you defined is always true. To illustrate, in the diagram below, your piano app and the music synthesizer are part of a related set and this lets you define a tight versioning construct that you may have when you need to load code. The content only song pack remains untouched and continues to work with your piano app.
Note that optional package cannot be managed code in the current release and has to be native code due to a .Net limitation. The related sets is not limited to just code optional packages. You can also decide that you have content optional packages that must be in sync with the main application.
Optional Packages targeting multiple apps
You can also produce optional packages that work with more than one main application. This is limited to content only optional packages. Back to the piano app example, you can make your song pack optional package work with another base app that you could build - for example a guitar app!
Cross Publisher Scenarios
Taking this a step further the platform supports the ability for the optional package and base package to be from different publishers if you want to co-develop with other publishers. I want to high light that these are publishers that you trust and the base app controls what optional packages it works with as you are loading content/ code in proc.
Optional packages are hence an amazing way for you to componentize your app. To drive users to your optional packages, you can build an in app install experience. For the Windows Store, the platform exposes StoreContext.RequestDownloadAndInstallStorePackagesAsync that lets you enumerate optional packages that are on the Store and install them. If you are installing optional packages deployed on http or a UNC file share, you can use PackageCatalog.AddOptionalPackageAsync()
Note that Optional packages is only open to a managed list of partners on the Windows Store today, however these scenarios are fully supported for sideloading or line of business apps!
Check out the following links for more advanced topics
- Building your first optional package
- Loading code from an optional package - introducing related sets
- Tooling to create related sets
Senior Program Manager