Changelog

All notable changes to tauri-plugin-widgets and tauri-plugin-widgets-api.

0.8.0

Added

  • Live activities: startActivity / updateActivity / endActivity / listActivities, templates with data-only updates (registerActivityTemplate), push tokens, state and content events. iOS Lock Screen and Dynamic Island, Android ongoing notifications.
  • Desktop Dynamic Island: a live activity as a pill at the camera notch on macOS, and the same pill on Windows and Linux (activitySurface: "island"); compact around the notch, expanded on hover.
  • Local state: state defaults and set on button / toggle / link ("$toggle", "$inc", "$dec") change the widget in place without the app; setWidgetState / getWidgetState, widget-state-changed event.
  • Data without the layout: setWidgetData(widgetId, data) with {{data.path}} bindings; source lets the widget fetch JSON from a URL itself.
  • Dynamic content: when conditions, repeat lists from arrays, reusable templates / use, localized strings, requires for newer configs on older apps.
  • Scheduled entries (entries: [{ at, small, … }]) switched without the app, and the transition hint (opacity, slide, numeric).
  • Instances: one widget placed several times with its own config and data (setWidgetInstances, getActiveWidgets, Apple "Edit Widget" choice).
  • Android: widget scheduler, configuration activity, loading / error / preview layouts, Samsung widget info.
  • getWidgetPushToken for widget push updates on iOS.
  • Docs: Features section with recordings, a standalone widget constructor page, animated home page.

Changed

  • The resolve contract (bindings, conditions, state) is shared and tested across Rust, TS, Swift and Kotlin (contract v3).
  • Windows Adaptive Cards: exact colours, unique ids, progress bars, shape and image sizes, ZStack sizing closer to the other renderers.
  • Element types (ContentMode, ChartType, …) are generated from the schema (guest-js/generated); ContentMode adds stretch / center, ChartType adds point.

Fixed

  • Rendering differences between platforms found by golden screenshots on iOS, Android, macOS, Windows, Linux and the desktop renderer.

0.7.0

Breaking

  • Rust: WidgetsPluginConfig::transport is Option<TransportKind> (unset = platform default).
  • macOS: with transport unset the host writes into the widget extension's container (widgetContainer), not the App Group. Sandboxed Mac App Store hosts set "transport": "appGroup".
  • Android: WidgetActionReceiver removed (taps go through the action callback queue).

Setup is simpler

  • No plugins.widgets block needed: appGroup defaults to group.<identifier>, transport to widgetContainer on macOS and appGroup on iOS. JS group is optional (defaults to the App Group), widgetId defaults to "default".
  • init-macos writes tauri.macos.conf.json (Linux / Windows builds no longer run build-widget.sh); the Swift package path is resolved on every build instead of baked into project.yml.
  • init-ios adds the widget extension target and the TauriWidgets package to gen/apple/project.yml (XcodeGen) and keeps app entitlements: no manual Xcode steps. Widget code lives in src-tauri/ios-widget.
  • init detects platforms from the host OS and gen/apple; --platforms overrides.

Fixed

  • macOS: Developer ID builds showed "No configuration" (the sandboxed extension cannot open a group.* container without a provisioning profile). Default transport is now widgetContainer.
  • Widget taps lost or delivered twice: cross-process lock on the Apple store; Android queues every tap and notifies a running app (widget-action-pending); Windows clears drained actions on disk.
  • iOS widget pinned to a stale copy in its own container.
  • Android: plugin commands off the UI thread (remote images loaded, no NetworkOnMainThreadException); reload throttle removed; builds with AGP 9 / Kotlin 2 apps from the current tauri android init; button labels centered.
  • Images downsampled before decode (Swift, Android); image prefetch walks List.children, caches failures, evicts old entries.
  • set_widget_config no longer blocks the main thread; set_widget_config_from_path reads regular files up to 4 MB only.
  • createWidgetWindow: works without group, reuses a window with the same label.
  • Linux layer-shell window closes with closeWidgetWindow.
  • Trace JSON fields are camelCase (matched the TS types).
  • startWidgetUpdater: several updaters per widget, throwing handlers no longer drop the batch.
  • Render library: several renderWidget hosts no longer share timers and handlers.
  • CLI: Windows data paths (Roaming), clean covers Linux and the macOS container, preview --open on Windows, runs from inside src-tauri, reads tauri.conf.json5 / platform confs.

Changed

  • Docs site moved from VitePress to Nuxt (Nuxt UI + Nuxt Content), same URLs. JS reference, Tauri commands, permissions and changelog pages are generated from the sources at build time; diagrams are committed SVGs instead of client-side mermaid. Element anchors are now #vstack (was #el-vstack).

0.6.2

Fixed

  • tauri-widgets --version reads package.json (was hardcoded 0.5.0)
  • exports exposes ./schemas/*; ./render has CJS + default
  • renderWidget no longer reads location.search / #root at import; group / widgetId are session options
  • tauri-widgets tools errors on npm installs (scripts/ is not published)

Changed

  • npm package description covers all host platforms

0.6.1

Fixed

  • Keep gtk 0.18 as a direct Linux dependency (layer-shell remap, GTK main-thread checks, CI libgtk-3-dev). Do not bump to 0.19: gtk-sys links = "gtk-3" clashes with Tauri 2.
  • Guest @tauri-apps/api range is ^2 again (wide Tauri 2 support; not >=2.12.1).
  • Playwright desktop tests pin locale + timezoneId so date-timer geometry does not depend on the host TZ.

Changed

  • Compatible lock/tooling bumps (Tauri 2.12.1, TypeScript 5.9, Playwright, Rollup, mermaid 12). TypeScript 7 skipped (@rollup/plugin-typescript). Breaking crates (base64 0.23, resvg 0.48, schemars 1, ureq 3, x11rb 0.14) left on current majors.

0.6.0

Added

  • JS render library: tauri-plugin-widgets-api/render (renderWidget in a host div, no Tauri)
  • Docs widget constructor (schema inspector, click-to-insert outline, Up/Down/Duplicate)
  • set_widget_config_from_path / setWidgetConfigFromPath (permission in widgets:default)
  • ListElement.children in generated TS / schema (rich list rows)
  • Stress / probe visual cases and light-theme goldens

Changed

  • Desktop widget-src split: library host vs chrome IIFE (widget.html)
  • Docs Playground/Constructor render in-page; dropped iframe sandbox copy pipeline
  • VitePress 2 + mermaid renderer

0.5.0

Mega-refactor toward one IR SoT and aligned renderers.

Added

  • Host-side normalize() before store write (textStyle, semantic colors, stack spacing defaults, capability degradations)
  • Desktop widget sources as TypeScript (widget-src/) bundled into widget.html
  • Consumer CLI (tauri-widgets) with tools proxy to maintainer stands
  • Wire catalogs: Swift Generated/WireCatalog.swift, Android WireTypes.kt via gen-native
  • Measured schemas/capabilities.coverage.json (CI; omitted from publish)
  • Light-theme visual cases (desktop / iOS / macOS)

Changed

  • Split renderers into layout/text/media/data/interactive/spacing groups (Android Glance, SwiftUI, Adaptive Cards, desktop HTML)
  • Split guest-js into api/* barrel; docs generator into scripts/.../generate/*
  • Publish packaging: npm schemas whitelist; crates.io excludes goldens/docs/scripts (~10 MB → ~1.4 MB)

Fixed

  • Desktop theme resolution (?theme= → data-theme → matchMedia)
  • Android unit tests via JDK 17 wrapper (scripts/sh/android-gradle.sh)

0.4.3

Fixes

  • docs.rs build: stop passing --cfg docsrs via rustc-args (it infected dependencies and broke winnow on current nightly); detect docs.rs via DOCS_RS in build.rs

0.4.1

Breaking (Apple host transport)

  • macOS host no longer fan-outs writes across three channels at runtime
  • Choose one driver in plugins.widgets.transport: appGroup | userDefaults | widgetContainer | auto
  • Require plugins.widgets.appGroup; wrong/missing config fails plugin init (loud)
  • Override with WIDGET_TRANSPORT; iOS accepts appGroup only
  • Unchanged setItems values skip disk write / nonce bump

Cleanup

  • Removed Mac-side SVG Adaptive Cards compositor (gen-windows-goldens) and fake tests/golden/windows/*.png; keep tests/snapshots/adaptive/ + PreviewHost for real WinUI3 pixels
  • rasterize no longer in default features (opt-in resvg)
  • Dropped empty Cargo features windows / macos / ios / android / all-platforms — backends follow target_os
  • gtk is optional under feature linux
  • Removed dead Kotlin helpers (sparkline, countRenderableChildren, maxRenderableItems)

0.4.0

First public cut of the redesign (unpublished drafts were never released separately).

Breaking (data / identity / actions)

  • Required widgetId on setWidgetConfig, getWidgetConfig, startWidgetUpdater, and built-in createWidgetWindow
  • Storage keys: config:{widgetId}, pending_actions, __meta_nonce__, __meta_updated_at__
  • Action envelope: { action, payload?, ts, widgetId, group }
  • iOS rejects groups that do not start with group.
  • Option IR fields omit null on serialize (skip_serializing_if)
  • startWidgetUpdater default intervalMs is 5000
  • No public Rust fluent builder module — author via JS / serde JSON
  • Removed unused WidgetItem type

IR SoT / DX

  • Rust models.rs is IR source of truth; TS types from IR_SPEC emitter (pnpm codegen)
  • Capability matrix (Core vs Extended) + validate_config warnings on config change
  • JSON Schema schemas/widget-config.v1.json; golden fixtures + core layout snapshots

Transport / platforms

  • Config hash per (group, widgetId); Apple multi-transport fan-out + freshest-by-nonce read
  • iOS pollPendingActions; mobile drains pending actions on Ready/Resumed; updater also polls
  • Android: live setWidgetConfig, image preprocess, appWidgetId → widgetId mapping, targeted Glance sync
  • Desktop poll_pending_actions; transparent widget windows (macOS needs macos-private-api)

Render parity (selected)

  • Android: spacer flex, canvas density, gauge aspect, bar baseline, zstack alignment, capsule 2s×s, textStyle>fontSize, list caps
  • Swift/HTML: vertical divider in hstack, text alignment, frame-before-background, zstack alignment, timer cleanup

Tooling

  • CI: cargo test --lib, android/ios cargo check --lib, codegen drift, pnpm build
  • Dropped library [profile.release] override; android/.gradle / local.properties gitignored

Known / deferred

  • macOS UserDefaults transport still write-mostly; {app_id}.widgetkit own-container hardcode; 500ms macOS action poller redesign