shinyelectron now requires R 4.5.0 or newer, since it verifies downloaded
runtimes with tools::sha256sum(), which was added in R 4.5.0. The README
and sitrep_electron_system() now report this minimum. Apps built with the
system strategy still accept R 4.4.0 or newer on the end user's machine.
Installer and artifact file names change. They now come from the slug and
always include the architecture, as in my-app-1.0.0-arm64.dmg,
my-app-Setup-1.0.0-x64.exe, and my-app-1.0.0-x86_64.AppImage, so
building several architectures into one dist/ no longer overwrites
installers. Update release scripts that look for the old names.
The installed app now carries the display name instead of the slug: the
macOS app bundle and App menu, the Windows Start Menu shortcut and Apps &
Features entry, and the installer window. export() now also takes the
display name from app.name in _shinyelectron.yml when no app_name is
given, as documented, instead of from the directory name. The slug, which
is the app's identity, keeps coming from app.slug, then the app_name
argument, then the directory name, so installed copies keep updating. The
Windows executable keeps the slug as well, and updates reuse the existing
install folder, so pinned shortcuts and existing installs carry over. On
macOS, reinstalling from the disk image leaves the old <slug>.app in
Applications to delete by hand.
export() now builds for build.platforms and build.architectures in
_shinyelectron.yml when its platform and arch arguments are not
given, for single apps and multi-app suites alike. Each argument overrides
only its own list. Before, the lists had no effect: the build, the choice
of icon, and the signing and Windows installer checks all used the current
machine. Check the lists in your configuration files. Earlier versions of
wizard() suggested mac and wrote it to build.platforms, so a file
written with them on Windows or Linux may list platforms: mac; change or
remove platforms there. wizard() now leaves platforms out unless you
name some, so each build targets the machine it runs on. If you copied the
Getting Started or Configuration Guide example that paired
runtime_strategy: "bundled" with platforms: [mac, win], remove
platforms, since a bundled or auto-download build stops when the
targets name more than one platform or architecture. A list with no valid
value means the current platform or architecture, and a value listed twice
is built once.
export() now checks the targets before converting anything. It stops
when a target is mac and the build machine is not a Mac: macOS apps
build only on macOS, and such an export used to report success without
making an installer. A bundled or auto-download build for more than
one target now stops before any files are copied, and an invalid
platform or arch argument stops the export even with build = FALSE.
app_check() reports these problems too, and wizard() asks for a single
platform when you choose the bundled or auto-download strategy.
New lifecycle.startup_timeout sets how long, in milliseconds, an app waits
for its R, Python, or container server to start (default 180000, three
minutes). R and Python apps used to give up after 60 seconds and container
apps after 120. This timeout and lifecycle.shutdown_timeout must be whole
numbers from 1000 to 2147483647; any other value warns and falls back to the
default. Before, a shutdown_timeout such as "10s" built an app that could
not launch.
installer.allow_to_change_installation_directory: true adds a page to the
Windows setup wizard where users choose the installation folder. It requires
installer.one_click: false; otherwise reading the configuration fails with
an error.
installer.per_machine: true installs the Windows app for all users. Every
install and update then needs administrator rights.
Bundled R builds now leave out files that a running app does not use: the
test suites (tests/, testme/, tinytest/) of every embedded package, and
the portable R's own regression tests, PDF and HTML manuals, and news and FAQ
files. Package examples, demos, NEWS files, and headers are kept, as are R's
license notices. Pruning is on by default; set dependencies.r.prune: false
in _shinyelectron.yml to ship the runtime unchanged. A quoted "true" or
"false" is read with a warning, and any other value stops the build before
anything is downloaded.
dependencies.r.local_packages installs R packages that are not on a
repository, such as in-house packages, into the R library of a bundled
build. List package source folders or .tar.gz source tarballs relative to
the app directory. Each package is built and installed with the bundled R
after its dependencies, and the build stops unless it loads.
New app.description, app.author, app.homepage, and app.copyright
settings describe the app. They fill the generated package.json and the
installer metadata, and Help > About shows them, with buttons to visit the
homepage or email the author. app.author takes an npm-style
"Name <email> (url)" string or a map with name, email, and url,
and app.homepage must be an http:// or https:// URL. On macOS, the
App menu's About panel shows the same name, version, copyright,
description, and author. Straight double quotes in the app name, author,
and copyright become typographic quotes in the installer metadata, and a
$ in the app name, description, author, or copyright, which the Windows
installer cannot hold, stops a Windows build.
With auto-updates enabled, Help > About offers Check for Updates on Windows and Linux. It reports that the app is up to date, offers to download a newer version, or explains why the check failed.
export() shows the app's slug next to its display name and says when
app.slug could choose another. init_config() and wizard() write the
slug into the new configuration, and init_config() warns when a
configuration it replaces gave a different slug.
shinyelectron now imports rlang. cli builds cli_abort() and cli_warn() on
rlang but only suggests it. Without rlang installed, errors from
cli_abort() showed "there is no package called 'rlang'" instead of their
own message, and warnings from cli_warn() became that same error, stopping
operations meant to continue, such as a Node.js install whose checksum list
could not be downloaded.
The situation reports (sitrep_shinyelectron() and friends) no longer
report Node.js, npm or Python as missing when the withr package is not
installed. withr is only a suggested dependency, and the probe used to fail
without it.
The Security Considerations guide gains a "Secrets and per-user credentials"
section. It covers which environment variables and .Renviron files reach an
app's R, Python, or container process, and how to give each user their own
token without bundling it.
Keys in _shinyelectron.yml that shinyelectron does not recognize, such as a
misspelled widht or a key placed in the wrong section, now trigger a
warning of class shinyelectron_unknown_config_key that names each one by
its dotted path (for example window.widht). They were previously ignored
without notice.
The top-level logging section documented in the Configuration Guide now
takes effect; its log_dir and log_level were previously ignored. If you
copied the guide's earlier example, drop its log_dir: "/var/log/my-app"
line: log_dir should be an absolute path that the app's user can write
to, and without it logs go to the app's userData/logs folder.
app.log_dir and app.log_level still work. When both set a key to
different values, logging wins with a warning of class
shinyelectron_logging_conflict. init_config() now suggests the
logging form.
init_config() no longer suggests nodejs.auto_install, which has no effect
yet.
App names and other settings that contain quotes or backslashes no longer
break the generated app. Settings placed in JavaScript strings in main.js
or in the splash and preloader page are now escaped, so a name like
"Children's Dashboard" or a Windows log_dir such as C:\Users\me\logs
works, and the About and quit dialogs and the tray tooltip show & instead
of &.
App names and descriptions in a multi-app suite that contain <!--
followed by <script> no longer break the launcher page.
Help > Documentation opens help URLs with query strings correctly instead
of turning & into &.
Help > Documentation appears only when menu.help_url is set, instead of
in every app with a link that opened nothing.
R and Python apps whose UI takes several seconds to render no longer fail to start. The startup check used to request the app's page, which ran the UI code on every attempt; it now requests a path the app does not serve, so the UI is rendered once, when the window loads it.
When an app does not start in time, only its own R or Python process or container is stopped, and the error screen stays up with its Retry and Quit buttons. For a container, the error names the container and its details show the container's logs. Going back to the launcher while an app is still starting no longer leaves that start running, where it could later stop the next app's process or container or replace the window with the abandoned app, and switching between container apps no longer shows the previous container's shutdown messages.
An R or Python app killed by a signal while starting (a segfault, or the system running out of memory), or one that exits before its server answers, now shows the error at once instead of after the startup timeout.
Restarting to install a downloaded update now stops the app's R or Python process (or its container) and waits for it to exit before the installer runs. If the update cannot be installed, a dialog asks you to restart the app. Pressing Esc in the Update Ready dialog now means Later.
Signed builds no longer fail when _shinyelectron.yml sets
signing.win.certificate_file. The certificate settings were written where
electron-builder 26 no longer accepts them, so its configuration check
stopped the build for every platform, macOS and Linux included. They now go
under win.signtoolOptions, where electron-builder 26 reads them. The
certificate password still comes from CSC_KEY_PASSWORD and is never
written to package.json.
The Windows credential checks in export() and app_check() now follow
electron-builder's lookup order: the certificate from
signing.win.certificate_file, then WIN_CSC_LINK, then CSC_LINK, and
the password from WIN_CSC_KEY_PASSWORD, then CSC_KEY_PASSWORD. Setting
only the WIN_CSC_* variables no longer draws a misleading warning, and a
WIN_CSC_* variable that is set but empty now warns, because
electron-builder stops there instead of falling back to CSC_*.
A signed build now passes signing.mac.team_id to electron-builder as
APPLE_TEAM_ID, the only place electron-builder reads the notarization team
ID. Before, when the team ID was set only in _shinyelectron.yml, builds
that notarize with an Apple ID failed with "APPLE_TEAM_ID env var needs to
be set". A team ID already set in APPLE_TEAM_ID still wins.
export(sign = TRUE) and app_check(sign = TRUE) now check the signing
credentials even when signing.sign is off in _shinyelectron.yml. The
macOS checks also follow electron-builder: an App Store Connect API key
(APPLE_API_KEY, APPLE_API_KEY_ID, APPLE_API_ISSUER) or
APPLE_KEYCHAIN_PROFILE counts as notarization credentials, a missing team
ID is reported only when notarizing with an Apple ID, and each warning says
whether notarization will fail or be skipped.
Bundled R builds now install packages with the portable R's own startup
files. The install no longer runs a project .Rprofile or .Renviron from
the working directory, such as renv's autoloader, and ignores R_ENVIRON
and R_PROFILE set for the calling R. A site profile chosen that way
skipped the portable R's macOS library fix-up, so installed binary packages
could crash when loaded. ~/.Renviron and ~/.Rprofile still apply.
Python dependencies are now read in full from pyproject.toml. In a
dependencies list that spanned several lines, a ] inside an entry, such
as the extras in "uvicorn[standard]>=0.30", or in a comment ended the
list, so the packages after it were not installed. Single-quoted entries are
now read, commented-out entries are skipped, and only the dependencies of
the [project] table are used, so development tools listed in other tables,
such as Hatch's [tool.hatch.envs.*] environments, are no longer installed
with the app. A pyproject.toml with no packages in that list now draws a
warning.
Python packages listed with the version in parentheses, as in
"shiny (>=1.0)", are now read as shiny from pyproject.toml and
requirements.txt. Poetry 2 writes pyproject.toml entries this way. They
were read as shiny (, which pip rejects, so none of the app's Python
packages were installed.
installer.one_click, installer.allow_to_change_installation_directory,
and installer.per_machine are checked when the configuration is read. A
quoted "true" or "false" (or "yes" or "no") is read as the matching
value with a warning; any other value that is not true or false stops
the build with an error that names the key.
installer.license_file no longer fails every build with electron-builder's
"unknown property 'license'" error. The file is resolved relative to the app
directory, copied into the build, and shown as the Windows installer's
license page. A UTF-8 text license gets a byte order mark in the copy so
the installer shows characters such as the copyright sign correctly.
app_check() now fails on configuration errors that stop export()
instead of listing them as warnings, and it checks that
installer.license_file exists.
Paths in _shinyelectron.yml are now resolved against the app directory
(the suite root for a multi-app suite) as documented, not the working
directory, so export() finds them from anywhere. This covers icon,
icons, splash.image, tray.icon, signing.win.certificate_file, and
the path and icon of each apps entry; launcher icons are now copied
into the build so the launcher can show them. ~ and absolute paths work.
The icon argument of export() stays relative to the working directory.
The app icon now reaches every platform that can use it. The generated
package.json pointed Windows, macOS, and Linux at assets/icon.ico,
assets/icon.icns, and assets/icon.png, but the build copies only the
icon's own file, so a platform whose file was missing quietly got the
default Electron icon: a PNG icon, as the documentation recommends,
reached Linux only, and an .icns icon never reached Windows. Every
platform now uses the copied file, which electron-builder converts from a
PNG or .icns icon as needed. An .ico icon serves Windows only.
electron-builder also stops the build when the image is too small: a PNG
needs at least 512x512 pixels for macOS and 256x256 for Windows, and
Windows needs a 256x256 image in an .icns or .ico file. A platform
that cannot use the icon, because of its format or its size, now gets the
default icon instead, and export() names it in a warning before anything
is built; app_check() reports it too. A tray.icon file named like the
copy, such as icon.png, is now copied under another name instead of
replacing it.
export() and app_check() now warn about the icons entries that an
export leaves out. One export gives one app icon, the icons entry for its
first target platform, to every platform, so a different entry for another
target platform is not used. Export each platform separately to give it
its own icon.
A configured splash image, tray icon, or launcher icon that does not exist
now gives a warning naming the key and the path checked, instead of being
skipped silently, and the build uses the default. A missing configured app
icon stops export(), as a missing icon argument does, and a missing
signing.win.certificate_file warns when a Windows build is signed.
app_check() checks these files the same way and reports a missing icon as
an error.
The system tray icon is no longer blank when tray.icon is not set and the
app icon is not a PNG. The tray looked for an icon.png that only a PNG app
icon provides; it now loads the app icon itself, such as an .ico file on
Windows. Where Electron cannot read the file (an .icns file, or an .ico
file on macOS or Linux), or when no icon is set, the tray shows a built-in
icon of a window outline instead. export() warns about a tray icon that a
target platform cannot read, with a warning of class
shinyelectron_tray_icon_unsupported that suggests setting tray.icon to a
PNG.
With updates.auto_download on, the update notification now says the new
version is downloading, instead of asking the user to click to download.
An app_name with no ASCII letters or digits, such as one written only in
Chinese characters, no longer stops export() late in the build; the slug
comes from the directory name instead. When no slug can be derived, or
app.slug is invalid, export() now stops before converting the app, and
show_config() no longer fails on a non-ASCII app.name.
export(), build_electron_app(), init_config(), and show_config()
now name the app after its folder when the app directory is a relative
path such as "." or "..". The app was named "." or "..", and
export() and build_electron_app() stopped because they could not
derive an app slug. When appdir is the path of a symbolic link,
app_check(), init_config(), and wizard() now take the slug from the
link's name, as export() does, instead of from the folder it points to.
app_check() also uses the link's name in its report, and wizard()
offers it as the default app name.
Examples for functions that install a runtime, launch an app, or clear the cache now run only in interactive sessions.
The Download Prebuilt Demos guide moved from a bundled vignette to the package website, and outdated external documentation links were refreshed.
wizard() now requires the appdir argument instead of defaulting to the
working directory.
This release grows shinyelectron from an R shinylive exporter into a general Shiny-to-desktop toolkit, adding Python apps, five runtime strategies, and multi-app suites.
app_type now takes only "r-shiny", "py-shiny", or NULL (autodetected),
and shinylive is a runtime_strategy rather than an app type. The old
"r-shinylive" and "py-shinylive" values still work with a deprecation
warning and will be removed in a future release.app_type autodetects
"r-shiny" or "py-shiny" from appdir, so export(appdir, destdir) works
with no other arguments.runtime_strategy selects how an app runs, and all five strategies work with
both languages: shinylive (the default; compiled to WebAssembly and run
offline in the browser), bundled (embeds a portable R or Python runtime),
system (uses an installed interpreter), auto-download (fetches the runtime
on first launch), and container (runs in Docker or Podman).apps array in _shinyelectron.yml lists them, and each app can set its
own runtime_strategy.export() and build_electron_app() gain a sign argument for macOS signing
and notarization and Windows Authenticode, driven by the usual CSC_* and
APPLE_* environment variables.enable_auto_updates(), disable_auto_updates(), and
check_auto_update_status() manage electron-updater configuration.install_r_portable(), install_python_standalone(), and install_nodejs()
download and cache portable runtimes, and cache_dir(), cache_info(), and
cache_remove() inspect and prune the cache.dependencies.r.version, dependencies.python.version, and
dependencies.electron.version pin the versions a build uses; each accepts
null, "latest", or an exact version.library() and require() calls for R and requirements.txt or
pyproject.toml for Python._shinyelectron.yml.app_check() validates an app before building, wizard() generates a config
interactively, show_config() prints the merged configuration, and
available_examples() and example_app() browse the bundled demos.app_dependencies() reports the R or Python packages a Shiny app or multi-app
suite uses, which helps install an app's dependencies before a shinylive build._brand.yml for theming.runtime_strategy argument overrides a suite's build.runtime_strategy
for apps that set no per-app strategy, so a suite built as shinylive really
is shinylive rather than falling back to the config default._brand.yml that names palette colors (for example primary: plum) resolves
those references before theming the shell.shinylive::export() compiles
the WebAssembly bundle from installed packages.build_electron_app() refuses to overwrite protected directories such as ~,
/, and R.home().convert_shiny_to_shinylive() removes its temporary copy on every exit path.export() cleans up partial output when a build fails, so a retry no longer
needs overwrite = TRUE, for single apps and multi-app suites alike.export() no longer aborts or deletes a finished build when a run_after or
open_after step fails; those steps now only warn.init_config() escapes app names so the generated YAML round-trips, and
build.type may be omitted and autodetected.run_electron_app() reports the real exit code and stderr on failure and
returns NULL when interrupted.sitrep_shinyelectron() also checks the Python shinylive CLI and shiny
package.LD_LIBRARY_PATH, fixing a Linux
No module named shinylive error.tar on macOS and Linux and bsdtar
on Windows, handling archives R's internal tar cannot read.system strategy checks for R >= 4.4.0 or Python >= 3.9.0 and fails with
an actionable message.splash.width, splash.height,
preloader.enabled, lifecycle.splash_min_duration) are removed, and
menu.template accepts only "default" and "minimal".r-shinylive support._shinyelectron.yml.electron-updater.