diff --git a/samples/UnoSample/.editorconfig b/samples/UnoSample/.editorconfig
new file mode 100644
index 00000000..b947be64
--- /dev/null
+++ b/samples/UnoSample/.editorconfig
@@ -0,0 +1,167 @@
+; This file is for unifying the coding style for different editors and IDEs.
+; More information at http://editorconfig.org
+
+# This file is the top-most EditorConfig file
+root = true
+
+##########################################
+# Common Settings
+##########################################
+
+[*]
+indent_style = space
+end_of_line = crlf
+trim_trailing_whitespace = true
+insert_final_newline = true
+charset = utf-8
+
+##########################################
+# File Extension Settings
+##########################################
+
+[*.{yml,yaml}]
+indent_size = 2
+
+[.vsconfig]
+indent_size = 2
+end_of_line = lf
+
+[*.sln]
+indent_style = tab
+indent_size = 2
+
+[*.{csproj,proj,projitems,shproj}]
+indent_size = 2
+
+[*.{json,slnf}]
+indent_size = 2
+end_of_line = lf
+
+[*.{props,targets}]
+indent_size = 2
+
+[*.xaml]
+indent_size = 2
+charset = utf-8-bom
+
+[*.xml]
+indent_size = 2
+end_of_line = lf
+
+[*.plist]
+indent_size = 2
+indent_style = tab
+end_of_line = lf
+
+[*.manifest]
+indent_size = 2
+
+[*.appxmanifest]
+indent_size = 2
+
+[*.{json,css,webmanifest}]
+indent_size = 2
+end_of_line = lf
+
+[web.config]
+indent_size = 2
+end_of_line = lf
+
+[*.sh]
+indent_size = 2
+end_of_line = lf
+
+[*.cs]
+# EOL should be normalized by Git. See https://github.com/dotnet/format/issues/1099
+end_of_line = unset
+
+# See https://github.com/dotnet/roslyn/issues/20356#issuecomment-310143926
+trim_trailing_whitespace = false
+
+tab_width = 4
+indent_size = 4
+
+# Sort using and Import directives with System.* appearing first
+dotnet_sort_system_directives_first = true
+
+# Avoid "this." and "Me." if not necessary
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_auto_properties = true:silent
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:silent
+dotnet_style_prefer_conditional_expression_over_return = true:silent
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+
+csharp_indent_labels = one_less_than_current
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_prefer_braces = true:silent
+csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+csharp_style_prefer_primary_constructors = true:suggestion
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
diff --git a/samples/UnoSample/.gitignore b/samples/UnoSample/.gitignore
new file mode 100644
index 00000000..ef88c205
--- /dev/null
+++ b/samples/UnoSample/.gitignore
@@ -0,0 +1,403 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+
+# Single Target Config
+solution-config.props
+# Publish Profiles
+!**/Properties/PublishProfiles/*.pubxml
\ No newline at end of file
diff --git a/samples/UnoSample/.vscode/extensions.json b/samples/UnoSample/.vscode/extensions.json
new file mode 100644
index 00000000..a63ad400
--- /dev/null
+++ b/samples/UnoSample/.vscode/extensions.json
@@ -0,0 +1,5 @@
+{
+  "recommendations": [
+    "unoplatform.vscode"
+  ],
+}
diff --git a/samples/UnoSample/.vscode/launch.json b/samples/UnoSample/.vscode/launch.json
new file mode 100644
index 00000000..87a59c21
--- /dev/null
+++ b/samples/UnoSample/.vscode/launch.json
@@ -0,0 +1,35 @@
+{
+  // Use IntelliSense to find out which attributes exist for C# debugging
+  // Use hover for the description of the existing attributes
+  // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "Uno Platform Mobile",
+      "type": "Uno",
+      "request": "launch",
+      // any Uno* task will do, this is simply to satisfy vscode requirement when a launch.json is present
+      "preLaunchTask": "Uno: android | Debug | android-x64"
+    },
+    {
+      // Use IntelliSense to find out which attributes exist for C# debugging
+      // Use hover for the description of the existing attributes
+      // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
+      "name": "Uno Platform Desktop (Debug)",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "build-desktop",
+      // If you have changed target frameworks, make sure to update the program path.
+      "program": "${workspaceFolder}/UnoSample/bin/Debug/net8.0-desktop/UnoSample.dll",
+      "args": [],
+      "launchSettingsProfile": "UnoSample (Desktop)",
+      "env": {
+        "DOTNET_MODIFIABLE_ASSEMBLIES": "debug"
+      },
+      "cwd": "${workspaceFolder}/UnoSample",
+      // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
+      "console": "internalConsole",
+      "stopAtEntry": false
+    },
+  ]
+}
diff --git a/samples/UnoSample/.vscode/settings.json b/samples/UnoSample/.vscode/settings.json
new file mode 100644
index 00000000..23133fc7
--- /dev/null
+++ b/samples/UnoSample/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+  "explorer.fileNesting.enabled": true,
+  "explorer.fileNesting.expand": false,
+  "explorer.fileNesting.patterns": {
+    "*.xaml": "$(capture).xaml.cs"
+  }
+}
diff --git a/samples/UnoSample/.vscode/tasks.json b/samples/UnoSample/.vscode/tasks.json
new file mode 100644
index 00000000..ff3537ca
--- /dev/null
+++ b/samples/UnoSample/.vscode/tasks.json
@@ -0,0 +1,31 @@
+{
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "label": "build-desktop",
+      "command": "dotnet",
+      "type": "process",
+      "args": [
+        "build",
+        "${workspaceFolder}/UnoSample/UnoSample.csproj",
+        "/property:GenerateFullPaths=true",
+        "/property:TargetFramework=net8.0-desktop",
+        "/consoleloggerparameters:NoSummary"
+      ],
+      "problemMatcher": "$msCompile"
+    },
+    {
+      "label": "publish-desktop",
+      "command": "dotnet",
+      "type": "process",
+      "args": [
+        "publish",
+        "${workspaceFolder}/UnoSample/UnoSample.csproj",
+        "/property:GenerateFullPaths=true",
+        "/property:TargetFramework=net8.0-desktop",
+        "/consoleloggerparameters:NoSummary"
+      ],
+      "problemMatcher": "$msCompile"
+    }
+  ]
+}
diff --git a/samples/UnoSample/.vsconfig b/samples/UnoSample/.vsconfig
new file mode 100644
index 00000000..6cd65ee4
--- /dev/null
+++ b/samples/UnoSample/.vsconfig
@@ -0,0 +1,23 @@
+{
+  "version": "1.0",
+  "components": [
+    "Microsoft.VisualStudio.Component.CoreEditor",
+    "Microsoft.VisualStudio.Workload.CoreEditor",
+    "Microsoft.NetCore.Component.SDK",
+    "Microsoft.NetCore.Component.DevelopmentTools",
+    "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
+    "Microsoft.VisualStudio.Component.TextTemplating",
+    "Microsoft.VisualStudio.Component.Windows10SDK.19041",
+    "Microsoft.VisualStudio.ComponentGroup.MSIX.Packaging",
+    "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites",
+    "Microsoft.VisualStudio.Component.Debugger.JustInTime",
+    "Microsoft.VisualStudio.Workload.ManagedDesktop",
+    "Microsoft.Component.NetFX.Native",
+    "Microsoft.VisualStudio.Component.Graphics",
+    "Microsoft.VisualStudio.Component.Merq",
+    "Microsoft.VisualStudio.Component.MonoDebugger",
+    "Microsoft.VisualStudio.ComponentGroup.Maui.All",
+    "Microsoft.VisualStudio.Workload.NetCrossPlat",
+    "Microsoft.VisualStudio.Workload.NetCoreTools"
+  ]
+}
diff --git a/samples/UnoSample/Directory.Build.props b/samples/UnoSample/Directory.Build.props
new file mode 100644
index 00000000..c23d7362
--- /dev/null
+++ b/samples/UnoSample/Directory.Build.props
@@ -0,0 +1,23 @@
+
+  
+    enable
+    enable
+    true
+
+    
+    $(NoWarn);NU1507;NETSDK1201;PRI257
+  
+
+  
+  
+    4.1.23
+    6.0.24
+    5.0.13
+    5.2.14
+  
+
diff --git a/samples/UnoSample/Directory.Build.targets b/samples/UnoSample/Directory.Build.targets
new file mode 100644
index 00000000..f75adf7e
--- /dev/null
+++ b/samples/UnoSample/Directory.Build.targets
@@ -0,0 +1,2 @@
+
+
diff --git a/samples/UnoSample/Directory.Packages.props b/samples/UnoSample/Directory.Packages.props
new file mode 100644
index 00000000..939ebb0d
--- /dev/null
+++ b/samples/UnoSample/Directory.Packages.props
@@ -0,0 +1,13 @@
+
+  
+  
+  
+  
+    
+    
+  
+
\ No newline at end of file
diff --git a/samples/UnoSample/README.md b/samples/UnoSample/README.md
new file mode 100644
index 00000000..09e409e3
--- /dev/null
+++ b/samples/UnoSample/README.md
@@ -0,0 +1,62 @@
+# Uno with Velopack
+
+This solution contains an Uno Desktop application that targets both Windows and macOS. Because Velopack does not currently support mobile or web platforms, those are not included.
+
+## Prerequisites
+This solution will publish the application out to the Velopack Flow service. To test the full publish you will need to create a [Velopack Flow account](https://app.velopack.io).
+
+The solution assumes that you have downloaded and installed the Velopack CLI (`vpk`) global tool. This tool can be installed by running `dotnet tool install -g vpk`. You will then need ot authenticate with the Velopack Flow servie by running `vpk login` and signing in with your Velopack Flow account.
+
+## The Application
+Inside of `Presentation` the `MainPage.xaml` contains the main UI for viewing the current version, checking for updates, and applying the latest update.
+The `MainViewModel.cs` contains the logic for checking for updates and applying them. The key piece of the setup is the initialization of the `UpdateManager` with the `VelopackFlowUpdateSource` which provides the interaction with the Velopack Flow service.
+
+The `Main` methods in the `Platforms\Desktop\Program.cs` has been updated to contain the [Velopack application startup hook](https://docs.velopack.io/integrating/overview).
+
+The `Main` methods in the `Platforms\MacCatalyst\Main.maccatalyst.cs` has been updated to contain the [Velopack application startup hook](https://docs.velopack.io/integrating/overview).
+
+Finally, for the WinUI platform, a little more work is needed as the `Main` method is auto-generated by default.
+First, the generation of the `Main` method needs to be disabled by defining `DISABLE_XAML_GENERATED_MAIN` constant in the csproj.
+```xml
+
+  $(DefineConstants);DISABLE_XAML_GENERATED_MAIN
+
+```
+Next the `Main` method needs to be added so a new `Platforms\Windows\Program.cs` file is added with a standard content, and the [Velopack application startup hook](https://docs.velopack.io/integrating/overview):
+```csharp
+[STAThread]
+public static void Main(string[] args)
+{
+    // It's important to Run() the VelopackApp as early as possible in app startup.
+    VelopackApp.Build()
+        .WithFirstRun((v) => { /* Your first run code here */ })
+        .Run();
+
+    WinRT.ComWrappersSupport.InitializeComWrappers();
+
+    Application.Start((p) =>
+    {
+        var context = new DispatcherQueueSynchronizationContext(
+            DispatcherQueue.GetForCurrentThread());
+        SynchronizationContext.SetSynchronizationContext(context);
+        new App();
+    });
+}
+```
+
+### Updating the Project file
+There are two properties to set in the `csproj` file to enable the Velopack Flow integration. These are:
+```xml
+true
+Velopack.UnoSample
+```
+
+`VelopackPackId` is the unique identifier for the application. This is used to identify the application in the Velopack Flow service. It must be unique among all applications.
+`VelopackPushOnPublish` is a boolean value that determines if the application should be pushed to the Velopack Flow service when it is published. This should be set to `true` to enable the integration.
+
+### Building installers
+To build the local installers run the following command replacing `` with the desired version number.
+The `-f` option is used to specify the target framework. This can be any of the desktop frameworks specified in the `csproj` file.
+```bash
+dotnet publish -c Release -f net8.0-desktop -p:Version=
+```
diff --git a/samples/UnoSample/UnoSample.sln b/samples/UnoSample/UnoSample.sln
new file mode 100644
index 00000000..1e12cd07
--- /dev/null
+++ b/samples/UnoSample/UnoSample.sln
@@ -0,0 +1,33 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.11.34929.205
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnoSample", "UnoSample\UnoSample.csproj", "{F9ACED52-AE70-46F6-8C7C-2EF629084661}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{29980CC9-DC41-4944-966D-F088C84D1C7B}"
+	ProjectSection(SolutionItems) = preProject
+		.gitignore = .gitignore
+		Directory.Build.props = Directory.Build.props
+		Directory.Build.targets = Directory.Build.targets
+		Directory.Packages.props = Directory.Packages.props
+		global.json = global.json
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F9ACED52-AE70-46F6-8C7C-2EF629084661}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F9ACED52-AE70-46F6-8C7C-2EF629084661}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F9ACED52-AE70-46F6-8C7C-2EF629084661}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F9ACED52-AE70-46F6-8C7C-2EF629084661}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {2FA3FC94-E895-443E-AAA8-9A7F956F9E92}
+	EndGlobalSection
+EndGlobal
diff --git a/samples/UnoSample/UnoSample/App.xaml b/samples/UnoSample/UnoSample/App.xaml
new file mode 100644
index 00000000..d4a63169
--- /dev/null
+++ b/samples/UnoSample/UnoSample/App.xaml
@@ -0,0 +1,28 @@
+
+
+    
+        
+            
+                
+                
+                
+                    
+                    
+                
+            
+        
+    
+
+    
+
+
diff --git a/samples/UnoSample/UnoSample/App.xaml.cs b/samples/UnoSample/UnoSample/App.xaml.cs
new file mode 100644
index 00000000..2a881e1e
--- /dev/null
+++ b/samples/UnoSample/UnoSample/App.xaml.cs
@@ -0,0 +1,110 @@
+using Uno.Resizetizer;
+
+namespace UnoSample;
+public partial class App : Application
+{
+    /// 
+    /// Initializes the singleton application object. This is the first line of authored code
+    /// executed, and as such is the logical equivalent of main() or WinMain().
+    /// 
+    public App()
+    {
+        this.InitializeComponent();
+    }
+
+    protected Window? MainWindow { get; private set; }
+    protected IHost? Host { get; private set; }
+
+    protected async override void OnLaunched(LaunchActivatedEventArgs args)
+    {
+        var builder = this.CreateBuilder(args)
+            // Add navigation support for toolkit controls such as TabBar and NavigationView
+            .UseToolkitNavigation()
+            .Configure(host => host
+#if DEBUG
+                // Switch to Development environment when running in DEBUG
+                .UseEnvironment(Environments.Development)
+#endif
+                .UseLogging(configure: (context, logBuilder) =>
+                {
+                    // Configure log levels for different categories of logging
+                    logBuilder
+                        .SetMinimumLevel(
+                            context.HostingEnvironment.IsDevelopment() ?
+                                LogLevel.Information :
+                                LogLevel.Warning)
+
+                        // Default filters for core Uno Platform namespaces
+                        .CoreLogLevel(LogLevel.Warning);
+
+                    // Uno Platform namespace filter groups
+                    // Uncomment individual methods to see more detailed logging
+                    //// Generic Xaml events
+                    //logBuilder.XamlLogLevel(LogLevel.Debug);
+                    //// Layout specific messages
+                    //logBuilder.XamlLayoutLogLevel(LogLevel.Debug);
+                    //// Storage messages
+                    //logBuilder.StorageLogLevel(LogLevel.Debug);
+                    //// Binding related messages
+                    //logBuilder.XamlBindingLogLevel(LogLevel.Debug);
+                    //// Binder memory references tracking
+                    //logBuilder.BinderMemoryReferenceLogLevel(LogLevel.Debug);
+                    //// DevServer and HotReload related
+                    //logBuilder.HotReloadCoreLogLevel(LogLevel.Information);
+                    //// Debug JS interop
+                    //logBuilder.WebAssemblyLogLevel(LogLevel.Debug);
+
+                }, enableUnoLogging: true)
+                .UseConfiguration(configure: configBuilder =>
+                    configBuilder
+                        .EmbeddedSource()
+                        .Section()
+                )
+                // Enable localization (see appsettings.json for supported languages)
+                .UseLocalization()
+                // Register Json serializers (ISerializer and ISerializer)
+                .UseSerialization((context, services) => services
+                    .AddContentSerializer(context)
+                    .AddJsonTypeInfo(WeatherForecastContext.Default.IImmutableListWeatherForecast))
+                .UseHttp((context, services) => services
+                    // Register HttpClient
+#if DEBUG
+                    // DelegatingHandler will be automatically injected into Refit Client
+                    .AddTransient()
+#endif
+                    .AddSingleton()
+                    .AddRefitClient(context))
+                .ConfigureServices((context, services) =>
+                {
+                    // TODO: Register your services
+                    //services.AddSingleton();
+                })
+                .UseNavigation(RegisterRoutes)
+            );
+        MainWindow = builder.Window;
+
+#if DEBUG
+        MainWindow.EnableHotReload();
+#endif
+        MainWindow.SetWindowIcon();
+
+        Host = await builder.NavigateAsync();
+    }
+
+    private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes)
+    {
+        views.Register(
+            new ViewMap(ViewModel: typeof(ShellViewModel)),
+            new ViewMap()
+        );
+
+        routes.Register(
+            new RouteMap("", View: views.FindByViewModel(),
+                Nested:
+                [
+                    new ("Main", View: views.FindByViewModel())
+                ]
+            )
+        );
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Assets/Icons/icon.svg b/samples/UnoSample/UnoSample/Assets/Icons/icon.svg
new file mode 100644
index 00000000..a15af53a
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Assets/Icons/icon.svg
@@ -0,0 +1,42 @@
+
+
diff --git a/samples/UnoSample/UnoSample/Assets/Icons/icon_foreground.svg b/samples/UnoSample/UnoSample/Assets/Icons/icon_foreground.svg
new file mode 100644
index 00000000..8ffc41ae
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Assets/Icons/icon_foreground.svg
@@ -0,0 +1,137 @@
+
+
diff --git a/samples/UnoSample/UnoSample/Assets/Images/back.svg b/samples/UnoSample/UnoSample/Assets/Images/back.svg
new file mode 100644
index 00000000..bcd7851b
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Assets/Images/back.svg
@@ -0,0 +1,3 @@
+
diff --git a/samples/UnoSample/UnoSample/Assets/SharedAssets.md b/samples/UnoSample/UnoSample/Assets/SharedAssets.md
new file mode 100644
index 00000000..1b84a74a
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Assets/SharedAssets.md
@@ -0,0 +1,32 @@
+# Shared Assets
+
+See documentation about assets here: https://github.com/unoplatform/uno/blob/master/doc/articles/features/working-with-assets.md
+
+## Here is a cheat sheet
+
+1. Add the image file to the `Assets` directory of a shared project.
+2. Set the build action to `Content`.
+3. (Recommended) Provide an asset for various scales/dpi
+
+### Examples
+
+```text
+\Assets\Images\logo.scale-100.png
+\Assets\Images\logo.scale-200.png
+\Assets\Images\logo.scale-400.png
+
+\Assets\Images\scale-100\logo.png
+\Assets\Images\scale-200\logo.png
+\Assets\Images\scale-400\logo.png
+```
+
+### Table of scales
+
+| Scale | WinUI       | iOS/MacCatalyst | Android |
+|-------|:-----------:|:---------------:|:-------:|
+| `100` | scale-100   | @1x             | mdpi    |
+| `125` | scale-125   | N/A             | N/A     |
+| `150` | scale-150   | N/A             | hdpi    |
+| `200` | scale-200   | @2x             | xhdpi   |
+| `300` | scale-300   | @3x             | xxhdpi  |
+| `400` | scale-400   | N/A             | xxxhdpi |
diff --git a/samples/UnoSample/UnoSample/Assets/Splash/splash_screen.svg b/samples/UnoSample/UnoSample/Assets/Splash/splash_screen.svg
new file mode 100644
index 00000000..8ffc41ae
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Assets/Splash/splash_screen.svg
@@ -0,0 +1,137 @@
+
+
diff --git a/samples/UnoSample/UnoSample/GlobalUsings.cs b/samples/UnoSample/UnoSample/GlobalUsings.cs
new file mode 100644
index 00000000..c93bf566
--- /dev/null
+++ b/samples/UnoSample/UnoSample/GlobalUsings.cs
@@ -0,0 +1,15 @@
+global using System.Collections.Immutable;
+global using CommunityToolkit.Mvvm.ComponentModel;
+global using CommunityToolkit.Mvvm.Input;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.Extensions.Hosting;
+global using Microsoft.Extensions.Localization;
+global using Microsoft.Extensions.Logging;
+global using Microsoft.Extensions.Options;
+global using UnoSample.DataContracts;
+global using UnoSample.DataContracts.Serialization;
+global using UnoSample.Models;
+global using UnoSample.Presentation;
+global using UnoSample.Services.Caching;
+global using UnoSample.Services.Endpoints;
+global using ApplicationExecutionState = Windows.ApplicationModel.Activation.ApplicationExecutionState;
diff --git a/samples/UnoSample/UnoSample/Models/AppConfig.cs b/samples/UnoSample/UnoSample/Models/AppConfig.cs
new file mode 100644
index 00000000..603e2405
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Models/AppConfig.cs
@@ -0,0 +1,6 @@
+namespace UnoSample.Models;
+
+public record AppConfig
+{
+    public string? Environment { get; init; }
+}
diff --git a/samples/UnoSample/UnoSample/Models/Entity.cs b/samples/UnoSample/UnoSample/Models/Entity.cs
new file mode 100644
index 00000000..ee8bb3bf
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Models/Entity.cs
@@ -0,0 +1,3 @@
+namespace UnoSample.Models;
+
+public record Entity(string Name);
diff --git a/samples/UnoSample/UnoSample/Models/WeatherForecast.cs b/samples/UnoSample/UnoSample/Models/WeatherForecast.cs
new file mode 100644
index 00000000..9869b1dd
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Models/WeatherForecast.cs
@@ -0,0 +1,15 @@
+namespace UnoSample.DataContracts;
+
+/// 
+/// A Weather Forecast for a specific date
+/// 
+/// Gets the Date of the Forecast.
+/// Gets the Forecast Temperature in Celsius.
+/// Get a description of how the weather will feel.
+public record WeatherForecast(DateOnly Date, double TemperatureC, string? Summary)
+{
+    /// 
+    /// Gets the Forecast Temperature in Fahrenheit
+    /// 
+    public double TemperatureF => 32 + (TemperatureC * 9 / 5);
+}
diff --git a/samples/UnoSample/UnoSample/Package.appxmanifest b/samples/UnoSample/UnoSample/Package.appxmanifest
new file mode 100644
index 00000000..656dc6f5
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Package.appxmanifest
@@ -0,0 +1,43 @@
+
+
+
+
+  
+
+  
+    UnoSample
+    UnoSample
+  
+
+  
+    
+    
+  
+
+  
+    
+  
+
+  
+    
+      
+        
+      
+    
+  
+
+  
+    
+  
+
diff --git a/samples/UnoSample/UnoSample/Platforms/Desktop/Program.cs b/samples/UnoSample/UnoSample/Platforms/Desktop/Program.cs
new file mode 100644
index 00000000..3e9601f0
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/Desktop/Program.cs
@@ -0,0 +1,29 @@
+using Uno.UI.Runtime.Skia;
+using Velopack;
+
+namespace UnoSample;
+public class Program
+{
+    [STAThread]
+    public static void Main(string[] args)
+    {
+        // It's important to Run() the VelopackApp as early as possible in app startup.
+        VelopackApp.Build()
+            .WithFirstRun((v) => { /* Your first run code here */ })
+            .Run();
+
+#if (!useDependencyInjection && useLoggingFallback)
+        App.InitializeLogging();
+
+#endif
+        var host = SkiaHostBuilder.Create()
+            .App(() => new App())
+            .UseX11()
+            .UseLinuxFrameBuffer()
+            .UseMacOS()
+            .UseWindows()
+            .Build();
+
+        host.Run();
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Entitlements.plist b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Entitlements.plist
new file mode 100644
index 00000000..24c31036
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+	
+	
+
diff --git a/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Info.plist b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Info.plist
new file mode 100644
index 00000000..1bb02ddc
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Info.plist
@@ -0,0 +1,26 @@
+
+
+
+	
+		UIDeviceFamily
+		
+			2
+		
+		LSApplicationCategoryType
+		public.app-category.utilities
+		UISupportedInterfaceOrientations
+		
+			UIInterfaceOrientationPortrait
+			UIInterfaceOrientationLandscapeLeft
+			UIInterfaceOrientationLandscapeRight
+		
+		XSAppIconAssets
+		Assets.xcassets/icon.appiconset
+
+		
+	
+
diff --git a/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Main.maccatalyst.cs b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Main.maccatalyst.cs
new file mode 100644
index 00000000..0cd78a0e
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Main.maccatalyst.cs
@@ -0,0 +1,19 @@
+using UIKit;
+using Velopack;
+
+namespace UnoSample.MacCatalyst;
+public class EntryPoint
+{
+    // This is the main entry point of the application.
+    public static void Main(string[] args)
+    {
+        // It's important to Run() the VelopackApp as early as possible in app startup.
+        VelopackApp.Build()
+            .WithFirstRun((v) => { /* Your first run code here */ })
+            .Run();
+
+        // if you want to use a different Application Delegate class from "AppDelegate"
+        // you can specify it here.
+        UIApplication.Main(args, null, typeof(App));
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Media.xcassets/LaunchImages.launchimage/Contents.json b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Media.xcassets/LaunchImages.launchimage/Contents.json
new file mode 100644
index 00000000..69555e44
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/MacCatalyst/Media.xcassets/LaunchImages.launchimage/Contents.json
@@ -0,0 +1,58 @@
+{
+  "images": [
+    {
+      "orientation": "portrait",
+      "extent": "full-screen",
+      "minimum-system-version": "7.0",
+      "scale": "2x",
+      "size": "640x960",
+      "idiom": "iphone"
+    },
+    {
+      "orientation": "portrait",
+      "extent": "full-screen",
+      "minimum-system-version": "7.0",
+      "subtype": "retina4",
+      "scale": "2x",
+      "size": "640x1136",
+      "idiom": "iphone"
+    },
+    {
+      "orientation": "portrait",
+      "extent": "full-screen",
+      "minimum-system-version": "7.0",
+      "scale": "1x",
+      "size": "768x1024",
+      "idiom": "ipad"
+    },
+    {
+      "orientation": "landscape",
+      "extent": "full-screen",
+      "minimum-system-version": "7.0",
+      "scale": "1x",
+      "size": "1024x768",
+      "idiom": "ipad"
+    },
+    {
+      "orientation": "portrait",
+      "extent": "full-screen",
+      "minimum-system-version": "7.0",
+      "scale": "2x",
+      "size": "1536x2048",
+      "idiom": "ipad"
+    },
+    {
+      "orientation": "landscape",
+      "extent": "full-screen",
+      "minimum-system-version": "7.0",
+      "scale": "2x",
+      "size": "2048x1536",
+      "idiom": "ipad"
+    }
+  ],
+  "properties": {},
+  "info": {
+    "version": 1,
+    "author": ""
+  }
+}
\ No newline at end of file
diff --git a/samples/UnoSample/UnoSample/Platforms/Windows/Program.cs b/samples/UnoSample/UnoSample/Platforms/Windows/Program.cs
new file mode 100644
index 00000000..bffedb4d
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/Windows/Program.cs
@@ -0,0 +1,26 @@
+using Microsoft.UI.Dispatching;
+using Velopack;
+
+namespace UnoSample;
+public static class Program
+{
+    // https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/migrate-to-windows-app-sdk/guides/applifecycle?WT.mc_id=DT-MVP-5003472#single-instancing-in-main-or-wwinmain
+    [STAThread]
+    public static void Main(string[] args)
+    {
+        // It's important to Run() the VelopackApp as early as possible in app startup.
+        VelopackApp.Build()
+            .WithFirstRun((v) => { /* Your first run code here */ })
+            .Run();
+
+        WinRT.ComWrappersSupport.InitializeComWrappers();
+
+        Application.Start((p) =>
+        {
+            var context = new DispatcherQueueSynchronizationContext(
+                DispatcherQueue.GetForCurrentThread());
+            SynchronizationContext.SetSynchronizationContext(context);
+            new App();
+        });
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-arm64.pubxml b/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-arm64.pubxml
new file mode 100644
index 00000000..d5147f10
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-arm64.pubxml
@@ -0,0 +1,22 @@
+
+
+
+	
+		FileSystem
+		arm64
+		win-arm64
+		bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\
+		true
+		False
+		False
+		True
+		
+		
+	
+
diff --git a/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-x64.pubxml b/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-x64.pubxml
new file mode 100644
index 00000000..4fea954e
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-x64.pubxml
@@ -0,0 +1,22 @@
+
+
+
+	
+		FileSystem
+		x64
+		win-x64
+		bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\
+		true
+		False
+		False
+		True
+		
+		
+	
+
diff --git a/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-x86.pubxml b/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-x86.pubxml
new file mode 100644
index 00000000..928cb25e
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Platforms/Windows/Properties/PublishProfiles/win-x86.pubxml
@@ -0,0 +1,22 @@
+
+
+
+	
+		FileSystem
+		x86
+		win-x86
+		bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\
+		true
+		False
+		False
+		True
+		
+		
+	
+
diff --git a/samples/UnoSample/UnoSample/Presentation/MainPage.xaml b/samples/UnoSample/UnoSample/Presentation/MainPage.xaml
new file mode 100644
index 00000000..a0c2a48a
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Presentation/MainPage.xaml
@@ -0,0 +1,39 @@
+
+
+    
+        
+            
+            
+        
+        
+
+        
+            
+            
+
+            
+            
+            
+        
+    
+
diff --git a/samples/UnoSample/UnoSample/Presentation/MainPage.xaml.cs b/samples/UnoSample/UnoSample/Presentation/MainPage.xaml.cs
new file mode 100644
index 00000000..549bf2ce
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Presentation/MainPage.xaml.cs
@@ -0,0 +1,13 @@
+namespace UnoSample.Presentation;
+
+public sealed partial class MainPage : Page
+{
+    public MainViewModel ViewModel => (MainViewModel)DataContext;
+
+    public bool NotInstalled => ViewModel?.IsInstalled != true;
+
+    public MainPage()
+    {
+        InitializeComponent();
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Presentation/MainViewModel.cs b/samples/UnoSample/UnoSample/Presentation/MainViewModel.cs
new file mode 100644
index 00000000..91ac9b3e
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Presentation/MainViewModel.cs
@@ -0,0 +1,72 @@
+using Velopack;
+using Velopack.Sources;
+
+namespace UnoSample.Presentation;
+
+public partial class MainViewModel : ObservableObject
+{
+    private readonly UpdateManager _updateManager;
+
+    public bool IsInstalled => _updateManager.IsInstalled;
+
+    [ObservableProperty]
+    [NotifyPropertyChangedFor(nameof(HasUpdate))]
+    private UpdateInfo? _latestUpdate;
+
+    public bool HasUpdate => LatestUpdate != null;
+
+    public string CurrentVersion => _updateManager.CurrentVersion?.ToFullString() ?? "";
+
+    [ObservableProperty]
+    private string? _status;
+
+    public MainViewModel(
+        IStringLocalizer localizer,
+        IOptions appInfo)
+    {
+        Title = "Main";
+        Title += $" - {localizer["ApplicationName"]}";
+        Title += $" - {appInfo?.Value?.Environment}";
+
+        _updateManager = new UpdateManager(new VelopackFlowUpdateSource());
+    }
+    public string? Title { get; }
+
+    [RelayCommand(CanExecute = nameof(IsInstalled))]
+    private async Task CheckForUpdates()
+    {
+        if (_updateManager.IsInstalled)
+        {
+            try
+            {
+                Status = "Checking for updates...";
+                LatestUpdate = await _updateManager.CheckForUpdatesAsync();
+                Status = LatestUpdate is null ? "No updates available" : $"{LatestUpdate.TargetFullRelease.Version} - Update available";
+            }
+            catch (Exception ex)
+            {
+                Status = ex.Message;
+            }
+        }
+    }
+
+    [RelayCommand(CanExecute = nameof(IsInstalled))]
+    private async Task DownloadUpdates()
+    {
+        if (_updateManager.IsInstalled && LatestUpdate is { } latestUpdate)
+        {
+            try
+            {
+                Status = $"Downloading {0:p}";
+                
+                await _updateManager.DownloadUpdatesAsync(latestUpdate, progress => Status = $"Downloading {progress / 100.0:p}");
+                Status = "Restarting...";
+                _updateManager.ApplyUpdatesAndRestart(latestUpdate.TargetFullRelease);
+            }
+            catch(Exception ex)
+            {
+                Status = ex.Message;
+            }
+        }
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Presentation/Shell.xaml b/samples/UnoSample/UnoSample/Presentation/Shell.xaml
new file mode 100644
index 00000000..88082443
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Presentation/Shell.xaml
@@ -0,0 +1,36 @@
+
+  
+    
+      
+        
+          
+            
+              
+              
+            
+
+            
+          
+        
+      
+    
+  
+
diff --git a/samples/UnoSample/UnoSample/Presentation/Shell.xaml.cs b/samples/UnoSample/UnoSample/Presentation/Shell.xaml.cs
new file mode 100644
index 00000000..2ba19587
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Presentation/Shell.xaml.cs
@@ -0,0 +1,10 @@
+namespace UnoSample.Presentation;
+
+public sealed partial class Shell : UserControl, IContentControlProvider
+{
+    public Shell()
+    {
+        this.InitializeComponent();
+    }
+    public ContentControl ContentControl => Splash;
+}
diff --git a/samples/UnoSample/UnoSample/Presentation/ShellViewModel.cs b/samples/UnoSample/UnoSample/Presentation/ShellViewModel.cs
new file mode 100644
index 00000000..cf938dcd
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Presentation/ShellViewModel.cs
@@ -0,0 +1,18 @@
+namespace UnoSample.Presentation;
+
+public class ShellViewModel
+{
+    private readonly INavigator _navigator;
+
+    public ShellViewModel(
+        INavigator navigator)
+    {
+        _navigator = navigator;
+        _ = Start();
+    }
+
+    public async Task Start()
+    {
+        await _navigator.NavigateViewModelAsync(this);
+    }
+}
diff --git a/samples/UnoSample/UnoSample/ReadMe.md b/samples/UnoSample/UnoSample/ReadMe.md
new file mode 100644
index 00000000..93482da2
--- /dev/null
+++ b/samples/UnoSample/UnoSample/ReadMe.md
@@ -0,0 +1,7 @@
+# Getting Started
+
+Welcome to the Uno Platform!
+
+To discover how to get started with your new app: https://aka.platform.uno/get-started
+
+For more information on how to use the Uno.Sdk or upgrade Uno Platform packages in your solution: https://aka.platform.uno/using-uno-sdk
\ No newline at end of file
diff --git a/samples/UnoSample/UnoSample/Serialization/WeatherForecastContext.cs b/samples/UnoSample/UnoSample/Serialization/WeatherForecastContext.cs
new file mode 100644
index 00000000..4a630b8d
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Serialization/WeatherForecastContext.cs
@@ -0,0 +1,23 @@
+using System.Collections.Immutable;
+using System.Text.Json.Serialization;
+
+namespace UnoSample.DataContracts.Serialization;
+/// 
+/// Generated class for System.Text.Json Serialization
+/// 
+/// 
+/// When using the JsonSerializerContext you must add the JsonSerializableAttribute
+/// for each type that you may need to serialize / deserialize including both the
+/// concrete type and any interface that the concrete type implements.
+/// For more information on the JsonSerializerContext see:
+/// https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation?WT.mc_id=DT-MVP-5002924
+/// 
+[JsonSerializable(typeof(WeatherForecast))]
+[JsonSerializable(typeof(WeatherForecast[]))]
+[JsonSerializable(typeof(IEnumerable))]
+[JsonSerializable(typeof(IImmutableList))]
+[JsonSerializable(typeof(ImmutableList))]
+[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
+public partial class WeatherForecastContext : JsonSerializerContext
+{
+}
diff --git a/samples/UnoSample/UnoSample/Services/Caching/IWeatherCache.cs b/samples/UnoSample/UnoSample/Services/Caching/IWeatherCache.cs
new file mode 100644
index 00000000..a7d587e7
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Services/Caching/IWeatherCache.cs
@@ -0,0 +1,6 @@
+namespace UnoSample.Services.Caching;
+
+public interface IWeatherCache
+{
+    ValueTask> GetForecast(CancellationToken token);
+}
diff --git a/samples/UnoSample/UnoSample/Services/Caching/WeatherCache.cs b/samples/UnoSample/UnoSample/Services/Caching/WeatherCache.cs
new file mode 100644
index 00000000..84ada638
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Services/Caching/WeatherCache.cs
@@ -0,0 +1,76 @@
+using System.Net;
+
+namespace UnoSample.Services.Caching;
+public sealed class WeatherCache : IWeatherCache
+{
+    private readonly IApiClient _api;
+    private readonly ISerializer _serializer;
+    private readonly ILogger _logger;
+
+    public WeatherCache(IApiClient api, ISerializer serializer, ILogger logger)
+    {
+        _api = api;
+        _serializer = serializer;
+        _logger = logger;
+    }
+
+    private bool IsConnected => NetworkInformation.GetInternetConnectionProfile().GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess;
+
+    public async ValueTask> GetForecast(CancellationToken token)
+    {
+        var weatherText = await GetCachedWeather(token);
+        if (!string.IsNullOrWhiteSpace(weatherText))
+        {
+            return _serializer.FromString>(weatherText);
+        }
+
+        if (!IsConnected)
+        {
+            _logger.LogWarning("App is offline and cannot connect to the API.");
+            throw new WebException("No internet connection", WebExceptionStatus.ConnectFailure);
+        }
+
+        var response = await _api.GetWeather(token);
+
+        if (response.IsSuccessStatusCode && response.Content is not null)
+        {
+            var weather = response.Content;
+            await Save(weather, token);
+            return weather;
+        }
+        else if (response.Error is not null)
+        {
+            _logger.LogError(response.Error, "An error occurred while retrieving the latest Forecast.");
+            throw response.Error;
+        }
+        else
+        {
+            return ImmutableArray.Empty;
+        }
+    }
+
+    private static async ValueTask GetFile(CreationCollisionOption option) =>
+        await ApplicationData.Current.TemporaryFolder.CreateFileAsync("weather.json", option);
+
+    private async ValueTask GetCachedWeather(CancellationToken token)
+    {
+        var file = await GetFile(CreationCollisionOption.OpenIfExists);
+        var properties = await file.GetBasicPropertiesAsync();
+
+        // Reuse latest cache file if offline
+        // or if the file is less than 5 minutes old
+        if (IsConnected || DateTimeOffset.Now.AddMinutes(-5) > properties.DateModified || token.IsCancellationRequested)
+        {
+            return null;
+        }
+
+        return await File.ReadAllTextAsync(file.Path, token);
+    }
+
+    private async ValueTask Save(IImmutableList weather, CancellationToken token)
+    {
+        var weatherText = _serializer.ToString(weather);
+        var file = await GetFile(CreationCollisionOption.ReplaceExisting);
+        await File.WriteAllTextAsync(file.Path, weatherText, token);
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Services/Endpoints/DebugHandler.cs b/samples/UnoSample/UnoSample/Services/Endpoints/DebugHandler.cs
new file mode 100644
index 00000000..ec400849
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Services/Endpoints/DebugHandler.cs
@@ -0,0 +1,44 @@
+namespace UnoSample.Services.Endpoints;
+
+internal class DebugHttpHandler : DelegatingHandler
+{
+    private readonly ILogger _logger;
+
+    public DebugHttpHandler(ILogger logger, HttpMessageHandler? innerHandler = null)
+        : base(innerHandler ?? new HttpClientHandler())
+    {
+        _logger = logger;
+    }
+
+    protected async override Task SendAsync(
+        HttpRequestMessage request,
+        CancellationToken cancellationToken)
+    {
+        var response = await base.SendAsync(request, cancellationToken);
+#if DEBUG
+        if (!response.IsSuccessStatusCode)
+        {
+            _logger.LogDebugMessage("Unsuccessful API Call");
+            if (request.RequestUri is not null)
+            {
+                _logger.LogDebugMessage($"{request.RequestUri} ({request.Method})");
+            }
+            
+            foreach ((var key, var values) in request.Headers.ToDictionary(x => x.Key, x => string.Join(", ", x.Value)))
+            {
+                _logger.LogDebugMessage($"{key}: {values}");
+            }
+
+            var content = request.Content is not null ? await request.Content.ReadAsStringAsync() : null;
+            if (!string.IsNullOrEmpty(content))
+            {
+                _logger.LogDebugMessage(content);
+            }
+
+            // Uncomment to automatically break when an API call fails while debugging
+            // System.Diagnostics.Debugger.Break();
+        }
+#endif
+        return response;
+    }
+}
diff --git a/samples/UnoSample/UnoSample/Services/Endpoints/IApiClient.cs b/samples/UnoSample/UnoSample/Services/Endpoints/IApiClient.cs
new file mode 100644
index 00000000..43fb788a
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Services/Endpoints/IApiClient.cs
@@ -0,0 +1,9 @@
+using Refit;
+
+namespace UnoSample.Services.Endpoints;
+[Headers("Content-Type: application/json")]
+public interface IApiClient
+{
+    [Get("/api/weatherforecast")]
+    Task>> GetWeather(CancellationToken cancellationToken = default);
+}
diff --git a/samples/UnoSample/UnoSample/Strings/en/Resources.resw b/samples/UnoSample/UnoSample/Strings/en/Resources.resw
new file mode 100644
index 00000000..90bf3091
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Strings/en/Resources.resw
@@ -0,0 +1,123 @@
+
+
+  
+  
+    
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    UnoSample-en
+  
+
diff --git a/samples/UnoSample/UnoSample/Strings/es/Resources.resw b/samples/UnoSample/UnoSample/Strings/es/Resources.resw
new file mode 100644
index 00000000..25878269
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Strings/es/Resources.resw
@@ -0,0 +1,123 @@
+
+
+  
+  
+    
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    UnoSample-es
+  
+
diff --git a/samples/UnoSample/UnoSample/Strings/fr/Resources.resw b/samples/UnoSample/UnoSample/Strings/fr/Resources.resw
new file mode 100644
index 00000000..f2d8f36a
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Strings/fr/Resources.resw
@@ -0,0 +1,123 @@
+
+
+  
+  
+    
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    UnoSample-fr
+  
+
diff --git a/samples/UnoSample/UnoSample/Strings/pt-BR/Resources.resw b/samples/UnoSample/UnoSample/Strings/pt-BR/Resources.resw
new file mode 100644
index 00000000..7aa109d2
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Strings/pt-BR/Resources.resw
@@ -0,0 +1,123 @@
+
+
+  
+  
+    
+    
+      
+        
+          
+            
+              
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+              
+            
+          
+          
+            
+              
+                
+                
+              
+              
+              
+              
+              
+            
+          
+          
+            
+              
+                
+              
+              
+            
+          
+        
+      
+    
+  
+  
+    text/microsoft-resx
+  
+  
+    2.0
+  
+  
+    System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+  
+  
+    UnoSample-pt-BR
+  
+
diff --git a/samples/UnoSample/UnoSample/Styles/ColorPaletteOverride.json b/samples/UnoSample/UnoSample/Styles/ColorPaletteOverride.json
new file mode 100644
index 00000000..cd154921
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Styles/ColorPaletteOverride.json
@@ -0,0 +1,76 @@
+{
+    "description": "Default Uno Material colors",
+    "seed": "#5946d2",
+    "coreColors": {
+        "primary": "#5946d2",
+        "secondary": "#6b4ea2"
+    },
+    "extendedColors": [],
+    "schemes": {
+        "light": {
+            "primary": "#5946d2",
+            "surfaceTint": "#5946d2",
+            "onPrimary": "#ffffff",
+            "primaryContainer": "#e5deff",
+            "onPrimaryContainer": "#170065",
+            "secondary": "#6b4ea2",
+            "onSecondary": "#ffffff",
+            "secondaryContainer": "#ebddff",
+            "onSecondaryContainer": "#220555",
+            "tertiary": "#0061a4",
+            "onTertiary": "#ffffff",
+            "tertiaryContainer": "#cfe4ff",
+            "onTertiaryContainer": "#001d36",
+            "error": "#b3261e",
+            "onError": "#ffffff",
+            "errorContainer": "#f9dedc",
+            "onErrorContainer": "#410e0b",
+            "background": "#fcfbff",
+            "onBackground": "#1c1b1f",
+            "surface": "#ffffff",
+            "onSurface": "#1c1b1f",
+            "surfaceVariant": "#f2eff5",
+            "onSurfaceVariant": "#8b8494",
+            "outline": "#79747e",
+            "outlineVariant": "#c9c5d0",
+            "shadow": "#000000",
+            "scrim": "#000000",
+            "inverseSurface": "#e6e1e5",
+            "inverseOnSurface": "#1c1b1f",
+            "inversePrimary": "#2a009f"
+        },
+        "dark": {
+            "primary": "#c7bfff",
+            "surfaceTint": "#c7bfff",
+            "onPrimary": "#2a009f",
+            "primaryContainer": "#4129ba",
+            "onPrimaryContainer": "#e4dfff",
+            "secondary": "#cdc2dc",
+            "onSecondary": "#332d41",
+            "secondaryContainer": "#433c52",
+            "onSecondaryContainer": "#eddfff",
+            "tertiary": "#9fcaff",
+            "onTertiary": "#003258",
+            "tertiaryContainer": "#00497d",
+            "onTertiaryContainer": "#d1e4ff",
+            "error": "#ffb4ab",
+            "onError": "#690005",
+            "errorContainer": "#93000a",
+            "onErrorContainer": "#ffdad6",
+            "background": "#1c1b1f",
+            "onBackground": "#e5e1e6",
+            "surface": "#302d37",
+            "onSurface": "#e6e1e5",
+            "surfaceVariant": "#47464f",
+            "onSurfaceVariant": "#c9c5d0",
+            "outline": "#928f99",
+            "outlineVariant": "#57545d",
+            "shadow": "#000000",
+            "scrim": "#000000",
+            "inverseSurface": "#e6e1e5",
+            "inverseOnSurface": "#1c1b1f",
+            "inversePrimary": "#2a009f"
+        }
+    },
+    "palettes": {}
+}
diff --git a/samples/UnoSample/UnoSample/Styles/ColorPaletteOverride.xaml b/samples/UnoSample/UnoSample/Styles/ColorPaletteOverride.xaml
new file mode 100644
index 00000000..6993f785
--- /dev/null
+++ b/samples/UnoSample/UnoSample/Styles/ColorPaletteOverride.xaml
@@ -0,0 +1,65 @@
+
+
+  
+    
+      #5946D2
+      #5946D2
+      #FFFFFF
+      #E5DEFF
+      #170065
+      #6B4EA2
+      #FFFFFF
+      #EBDDFF
+      #220555
+      #0061A4
+      #FFFFFF
+      #CFE4FF
+      #001D36
+      #B3261E
+      #FFFFFF
+      #F9DEDC
+      #410E0B
+      #FCFBFF
+      #1C1B1F
+      #FFFFFF
+      #1C1B1F
+      #F2EFF5
+      #8B8494
+      #79747E
+      #C9C5D0
+      #E6E1E5
+      #1C1B1F
+      #2A009F
+    
+    
+      #C7BFFF
+      #C7BFFF
+      #2A009F
+      #4129BA
+      #E4DFFF
+      #CDC2DC
+      #332D41
+      #433C52
+      #EDDFFF
+      #9FCAFF
+      #003258
+      #00497D
+      #D1E4FF
+      #FFB4AB
+      #690005
+      #93000A
+      #FFDAD6
+      #1C1B1F
+      #E5E1E6
+      #302D37
+      #E6E1E5
+      #47464F
+      #C9C5D0
+      #928F99
+      #57545D
+      #E6E1E5
+      #1C1B1F
+      #2A009F
+    
+  
+
\ No newline at end of file
diff --git a/samples/UnoSample/UnoSample/UnoSample.csproj b/samples/UnoSample/UnoSample/UnoSample.csproj
new file mode 100644
index 00000000..f7871837
--- /dev/null
+++ b/samples/UnoSample/UnoSample/UnoSample.csproj
@@ -0,0 +1,75 @@
+
+  
+    
+      net8.0-maccatalyst;
+      net8.0-windows10.0.19041;
+      net8.0-desktop;
+    
+
+    Exe
+    true
+
+    true
+    Velopack.UnoSample
+
+    
+    UnoSample
+    
+    com.velopack.UnoSample
+    
+    1.0
+    1
+    
+    
+
+    
+    
+      Material;
+      Dsp;
+      Hosting;
+      Toolkit;
+      Logging;
+      Mvvm;
+      Configuration;
+      Http;
+      Serialization;
+      Localization;
+      Navigation;
+      ThemeService;
+    
+  
+
+  
+  
+    $(DefineConstants);DISABLE_XAML_GENERATED_MAIN
+  
+
+  
+    
+    
+      all
+      runtime; build; native; contentfiles; analyzers; buildtransitive
+    
+  
+
+  
+    
+      Uno
+    
+  
+
+
diff --git a/samples/UnoSample/UnoSample/app.manifest b/samples/UnoSample/UnoSample/app.manifest
new file mode 100644
index 00000000..f0b4cb8c
--- /dev/null
+++ b/samples/UnoSample/UnoSample/app.manifest
@@ -0,0 +1,25 @@
+
+
+  
+
+  
+    
+      
+      
+    
+  
+
+  
+    
+      
+      true/PM
+      PerMonitorV2, PerMonitor
+    
+  
+
diff --git a/samples/UnoSample/UnoSample/appsettings.development.json b/samples/UnoSample/UnoSample/appsettings.development.json
new file mode 100644
index 00000000..2cf8df52
--- /dev/null
+++ b/samples/UnoSample/UnoSample/appsettings.development.json
@@ -0,0 +1,9 @@
+{
+  "AppConfig": {
+    "Environment": "Development"
+  },
+  "ApiClient": {
+    "Url": "https://localhost:5002",
+    "UseNativeHandler": true
+  }
+}
diff --git a/samples/UnoSample/UnoSample/appsettings.json b/samples/UnoSample/UnoSample/appsettings.json
new file mode 100644
index 00000000..aa890ef1
--- /dev/null
+++ b/samples/UnoSample/UnoSample/appsettings.json
@@ -0,0 +1,16 @@
+{
+  "AppConfig": {
+    "Environment": "Production"
+  },
+  "ApiClient": {
+    "UseNativeHandler": true
+  },
+  "LocalizationConfiguration": {
+    "Cultures": [
+      "es",
+      "fr",
+      "pt-BR",
+      "en"
+    ]
+  }
+}
diff --git a/samples/UnoSample/global.json b/samples/UnoSample/global.json
new file mode 100644
index 00000000..7711a32a
--- /dev/null
+++ b/samples/UnoSample/global.json
@@ -0,0 +1,6 @@
+{
+  // To update the version of Uno please update the version of the Uno.Sdk here. See https://aka.platform.uno/upgrade-uno-packages for more information.
+  "msbuild-sdks": {
+    "Uno.Sdk": "5.2.161"
+  }
+}