Shiny for .NET: Cross-Platform Device Services and Background Work
.NET Framework for Backgrounding & Device Hardware Services (iOS, MacOS, tvOS, Android, Windows, Linxux, & Web)
At a glance
- What is it?
- Shiny is a .NET framework for device services, background jobs, transfers, notifications, location, Bluetooth, and related platform capabilities. Its modular package design suits application developers who need a shared API across mobile, desktop, Linux, and Blazor WebAssembly, but platform support remains uneven.
- Who is it for?
- Adopt Shiny when a .NET application spans several supported operating systems and needs shared abstractions for background work, transfers, notifications, location, Bluetooth, or other device services. Do not assume that installing one module guarantees identical behavior everywhere, because Linux scheduling and several other capabilities use managed or platform-specific fallbacks.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Shiny's Scope for Cross-Platform .NET Applications
Shiny addresses a recurring .NET application problem: device capabilities and operating-system services tend to require different APIs and lifecycle handling on each platform. It is for developers building applications that need background jobs, HTTP transfers, notifications, Bluetooth LE, location, geofencing, network discovery, printing, in-app purchases, or related services while retaining a common application API.
The framework is broader than a Bluetooth package or a background-job scheduler. Its foundation covers dependency injection, hosting, key-value and object stores, lifecycle hooks, connectivity, battery state, device information, main-thread access, and screen information. Feature modules build on those platform abstractions. According to the README, foundation components are added automatically when a module needs them, while an implementation registered first is retained.
The stated targets are iOS, Android, tvOS, Mac Catalyst, macOS, Windows, Linux GTK, and Blazor WebAssembly. The repeated qualification "where the platform allows" matters. Shiny can present consistent concepts across targets, but it cannot remove permissions, schedulers, operating-system restrictions, or absent hardware. Each package is also designed for Native AOT and trimming, which is useful for mobile and desktop applications that cannot depend on unrestricted reflection.
The default branch is `v6`, and the README says Blazor WebAssembly support is contained in each package's `net10.0` build rather than separate `*.Blazor` packages. This reduces package selection for WebAssembly, although it does not mean every feature works there.
Module Selection and Dependency Boundaries
Shiny uses separate NuGet packages for distinct service areas instead of making every application depend on every device API. A background-work application can reference `Shiny.Jobs`, while a transfer client can add `Shiny.Net.Http`. Applications using multiple areas combine those packages explicitly. Foundation hosting is provided by `Shiny.Hosting.Maui` for MAUI targets and by `Shiny.Hosting.Native` for native .NET hosts.
The package table draws several useful boundaries. `Shiny.Core` contains shared platform services. Bluetooth is split among `Shiny.BluetoothLE`, `Shiny.BluetoothLE.Hosting`, and `Shiny.Beacons`. Location can be taken as the combined `Shiny.Locations` package or through the narrower `Shiny.Gps` and `Shiny.Geofencing` packages. Data synchronization has its own `Shiny.Data.Sync` package, while commerce features include an application package and an ASP.NET Core server package.
The README states that every package ships under the same version. It also identifies separate `*.Linux` add-ons for components that communicate through D-Bus. This is a deliberate dependency boundary: a WebAssembly application does not receive the Linux D-Bus dependency merely because it references a feature package.
This design reduces unrelated surface area, but it also makes package selection a setup task. A package name matching a desired feature is not enough to confirm platform support. For example, geofencing, push notifications, Bluetooth, and background scheduling all depend on operating-system facilities that differ by target. The relevant package documentation and sample application need to be checked before implementation.
Background Jobs, Transfers, and Synchronization
Shiny assigns background work to the scheduler available on each platform. `Shiny.Jobs` uses `BGTaskScheduler` on iOS and tvOS, `WorkManager` on Android, and COM-activated background tasks on Windows. Linux, macOS, and Blazor WebAssembly use an in-process managed runner. That last path is materially different from an OS-managed queue: execution depends on the host process and the README does not claim native scheduler guarantees for it.
`Shiny.Net.Http` supports background uploads and downloads with pause and resume behavior. Apple targets use `NSURLSession`. Android, Windows, Linux, macOS, and the .NET base use an `HttpClient`-driven loop, with downloads resuming from their current offset through Range requests. Blazor WebAssembly uses Service Worker Background Sync. The README also distinguishes tus uploads from ordinary resumable uploads: tus requests continue from the server offset after a pause, network interruption, or application restart, except on Blazor WebAssembly. Managed uploads otherwise restart after a pause.
This is more than a convenience wrapper around `HttpClient`, but it is not a uniform durability guarantee. The same user action can produce different transfer mechanics depending on the operating system. Projects that require byte-level continuation rules for uploads should inspect the behavior of their selected backend and target rather than relying on the shared interface alone.
`Shiny.Data.Sync` adds a separate synchronization model over HTTP. The README describes an outbox and inbox, batched outbound records, tombstones, conflict resolution, exponential-backoff retries, and AOT-safe serialization through `Shiny.Json`. Its platform tiers also differ, including a foreground service on Android and LocalStorage-backed HTTP behavior for Blazor WebAssembly. Synchronization has its own state and conflict semantics, so it should not be treated as merely another HTTP transfer queue.
Device Services Across Native and Blazor Targets
The module set shows that Shiny is intended to unify service-oriented APIs rather than every possible device function behind one giant interface. `Shiny.Notifications` handles scheduled, repeating, and geofence-triggered local notifications on iOS, macOS, Android, Windows, and Linux. On Linux, scheduled and repeating notifications use an in-process timer because the README states that Linux has no OS scheduler covered by this module. A notification intended to run after the application is no longer alive therefore needs careful review on that target.
Badge APIs make the platform distinction explicit. `TrySetBadge` and `TryGetBadge` operate on iOS and Mac Catalyst application icons and the macOS Dock tile, while they return `false` on Android and Windows because those platforms do not provide the same application-wide badge behavior.
Bluetooth packages cover Bluetooth LE clients, hosting, and beacons. Location packages cover GPS, geofencing, and region geofencing, including a DocumentDB-backed region package. Network modules handle mDNS, SSDP, WS-Discovery, and Wi-Fi. Commerce packages cover App Store and Google Play in-app purchases, a server component, store update checks, links, and review prompts.
Blazor WebAssembly receives support inside each package's `net10.0` build. That packaging choice is convenient, but hardware and operating-system capabilities still depend on what the browser and host expose. The README does not promise parity for every native module on WebAssembly.
Finding the First Shiny Integration
The repository description and README do not provide an exact installation command, package version, or minimal startup snippet, so this article does not invent one. The repository directs users to its documentation at `https://shinylib.net/client/core/`, and its `samples/` directory contains concrete starting points such as `samples/Sample.Maui/`, `samples/Sample.Shared.Maui/`, `samples/Sample.Api/`, `samples/Sample.Blazor/`, and platform-specific projects for iOS, Linux, macOS, and tvOS.
A first integration should therefore begin by selecting the sample that matches the intended host. A MAUI application is the relevant reference when using `Shiny.Hosting.Maui`. Native applications should examine `samples/Sample.Api/` or the matching native sample and `Shiny.Hosting.Native`. A browser-oriented application should examine `samples/Sample.Blazor/` and confirm that the selected feature has suitable WebAssembly behavior.
The first real work is not registering every service. It is selecting one module that solves a concrete requirement, checking its platform declarations and permissions, then examining the matching sample for registration and lifecycle handling. This keeps setup tied to an actual use case. It also exposes the main adoption boundary early: Shiny can centralize an API, but it cannot make an unsupported operating-system function available.
Before copying a configuration, verify whether it targets MAUI, native .NET, or Blazor WebAssembly. Also verify whether a D-Bus-dependent Linux add-on is needed. The repository includes `Directory.Packages.props`, templates, tests, and samples, but the README does not give enough versioned package instructions to reproduce a build reliably.
Compatibility Boundaries and Release History
Shiny's most significant limitation is uneven platform depth. The module list covers many targets, but several mechanisms are native on some systems and managed in-process on others. Background jobs, scheduled Linux notifications, HTTP transfer resume behavior, and Bluetooth support cannot all be assessed solely from their shared .NET interfaces. The README itself uses platform qualifications and explicit fallback paths.
Another boundary is package and framework alignment. The repository's default branch is `v6`, the Blazor support is described under `net10.0`, and Linux-native dependencies are separated into add-on packages. An application must align its target framework, host package, feature package, and native dependencies. The README does not document a migration guide from earlier Shiny versions, rollback procedures, or a compatibility matrix for every module.
Maintenance activity and release history should be considered separately. The repository is not archived, and the last push was on 2026-10-14. The listed releases, however, are `3.1` from 2023-12-11, `3.0` from 2023-10-27, and `2.4` from 2021-11-22. The release list does not explain the relationship between the current `v6` default branch and those versions, so recent commits should not be treated as proof of package release cadence.
The project uses the MIT license. That permits use, modification, distribution, and sublicensing under the license's conditions, but native platforms, mobile stores, Azure services, AWS S3, tus servers, and application dependencies may carry separate terms. The README does not provide legal analysis, so organizations must review those component licenses directly.
Editorial conclusion
Adopt Shiny when a .NET application spans several supported operating systems and needs shared abstractions for background work, transfers, notifications, location, Bluetooth, or other device services. Do not assume that installing one module guarantees identical behavior everywhere, because Linux scheduling and several other capabilities use managed or platform-specific fallbacks. Verify the specific module, target platform, hosting model, native permissions, and Blazor WebAssembly support first; based on the repository, `Shiny.Core`, the relevant feature package, and the correct `Shiny.Hosting.Maui` or `Shiny.Hosting.Native` package form the starting point for implementation review.
Frequently asked questions
Which platforms does Shiny for .NET support?
The README lists iOS, Android, tvOS, Mac Catalyst, macOS, Windows, Linux, and Blazor WebAssembly, with support depending on what each platform permits.
Does Shiny require separate Blazor WebAssembly packages?
No. The README says Blazor WebAssembly support is included in each package's `net10.0` build, and separate `*.Blazor` packages are not used.
How does Shiny handle background jobs on Linux and Blazor WebAssembly?
Shiny uses an in-process managed runner on Linux, macOS, and Blazor WebAssembly rather than the native schedulers used on platforms such as iOS, Android, and Windows.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/shinyorg-shiny)