Portable Shiny app deployment for restricted Windows environments
Documentation · Get Started · Report Issue
ShareBridge is a local deployment framework for packaging and distributing Shiny apps in restricted Windows environments.
It is designed for teams that:
- do not have admin rights
- want to avoid traditional installers like Inno Setup or MSI packaging
- need a simple SharePoint or OneDrive based distribution workflow
- want portable Shiny app delivery with bundled packages and optional bundled R
ShareBridge lets a publisher package a Shiny app into a single deployable folder, place it in SharePoint, and have end users sync and run it locally. No Shiny Server, no admin rights, and no R installation required on user machines when portable R is bundled.
ShareBridge provides:
- a local Publisher UI for packaging Shiny apps
- automatic package detection and bundling
- optional offline package repository creation
- optional portable R bundling
- optional Pandoc support for R Markdown rendering
- optional writable directory provisioning
- hidden background publishing with live logs
- a clean end-user launcher experience
- local app launch through a friendly loopback URL such as:
http://sharebridge-my_app.localhost:3670
- Open the ShareBridge Publisher (double-click
PublishApp.hta) - Select the source Shiny app folder
- Enter the app name
- Review detected packages and add extras if needed
- Choose the output folder
- Optionally enable:
- zip output
- offline repo
- Pandoc support stub
- writable app directories
- Click Build deployment
- Copy the completed output folder to SharePoint or another synced location
- Sync the published folder locally through OneDrive or SharePoint sync
- Double-click
LaunchApp.hta - Optionally create a desktop shortcut to
LaunchApp.hta
ShareBridge/
|-- build/
| |-- publisher_ui/
| | `-- app.R # Publisher Shiny UI
| |-- build_packages.R # Package bundler
| |-- publish_app.R # Main build orchestrator
| `-- run_hidden.vbs # Hidden process launcher
|-- logs/
| `-- publisher/ # Publisher and strip_r logs
|-- LaunchApp.hta # User-facing app launcher
|-- PublishApp.hta # Publisher launcher (HTA)
|-- publish.bat # Publisher launcher (batch fallback)
|-- run.bat # App runtime launcher
|-- run.R # App runtime entry point
|-- strip_r.R # Portable R builder
`-- ShareBridge.Rproj
| File | Purpose |
|---|---|
PublishApp.hta |
Hidden launcher for the publisher app |
publish.bat |
Batch fallback launcher |
build/publisher_ui/app.R |
Shiny-based packaging interface |
build/publish_app.R |
Builds the final deployable app folder |
build/build_packages.R |
Bundles app package dependencies |
strip_r.R |
Creates the portable R master copy |
build/run_hidden.vbs |
Launches background processes without a console window |
| File | Purpose |
|---|---|
LaunchApp.hta |
Hidden launcher for deployed apps |
run.bat |
Starts the local runtime |
run.R |
Loads bundled dependencies and launches the Shiny app |
app_meta.cfg |
App metadata such as name, ID, preferred port |
req.txt |
Required package list |
VERSION |
Build metadata and R version details |
The Publisher UI supports:
- selecting a Shiny app source folder (with native Windows folder picker)
- auto-detecting packages used in the app code
- adding optional extra packages manually
- choosing an output directory
- optionally creating a zip file
- optionally building an offline package repo
- optionally enabling Pandoc support stub
- optionally selecting writable app directories to provision
- showing a live build log during the build
- building in the background with no console window (via VBScript + processx)
- saving publisher logs under
logs/publisher/ - viewing and deleting saved publisher logs from the UI
- creating portable R directly from the Publisher UI (Strip R tab)
- clearing the form for a new build without refreshing
ShareBridge supports either:
Single-file app:
app.R
Split app:
ui.R+server.R
It also supports common supporting folders such as:
www/, R/, modules/, data/, config/, and helper .R files.
During publishing, ShareBridge:
- Validates the source app structure (checks for
app.Rorui.R+server.R) - Copies the source app into the output folder under
app/ - Detects package dependencies via
renv::dependencies()with regex fallback - Writes
req.txtwith auto-detected packages (always includesshiny) - Merges optional extra packages from the UI or
req_extra.txt - Writes
app_meta.cfgwith app name, ID, preferred port, and host metadata - Copies portable R from the framework into the deployment as
R/when available - Writes
VERSIONwith R version, build timestamp, and package count - Calls
build_packages.Rto build the bundled package library - Optionally creates selected writable directories in the deployment
- Optionally prepares a Pandoc support stub folder
- Optionally builds a local offline repo under
repo/ - Optionally creates a zip archive of the final deployment
MyApp_deploy/
|-- LaunchApp.hta
|-- run.bat
|-- run.R
|-- req.txt
|-- app_meta.cfg
|-- VERSION
|-- README_User.txt
|-- README_Publisher.txt
|-- packages_manifest.tsv
|-- app/ # user's Shiny app code
|-- packages/ # bundled CRAN packages
|-- logs/
|-- build/
| `-- build_packages.R
|-- R/ # optional portable R
|-- pandoc/ # optional Pandoc stub
`-- repo/ # optional offline repo
ShareBridge separates the portable R source from the portable R runtime.
R-portable-master/— master source copy used for publishingR-portable/— runtime copy used for local launching and testing
This split avoids Windows file-locking problems during publishing.
- Install a full version of R on the publisher machine
- Run strip_r.R from the Publisher UI (Strip R tab) or command line:
Rscript strip_r.R --r_source "C:\Path\To\R" - ShareBridge creates
R-portable-master/and optionally refreshesR-portable/
- Publishing should copy from a cold source tree
- Runtime and testing may lock DLLs in a live tree
- Separating master and runtime makes builds more reliable
Documentation, test suites, Tcl/Tk runtime, C headers, translations, and help/vignette files from all base packages. All runtime code, DLLs, NAMESPACE, and DESCRIPTION files are preserved.
ShareBridge detects packages automatically from app source code.
Detected patterns:
library(pkg)andrequire(pkg)pkg::function()andpkg:::function()
Files scanned: .R, .Rmd, .qmd
Primary scanner: renv::dependencies() (if renv is installed)
Fallback scanner: built-in regex parser
What static scanning can miss:
- Dynamic loading:
lapply(pkgs, library, character.only = TRUE) - String-constructed names:
library(paste0("data", ".table")) - Packages loaded in externally sourced scripts outside the app folder
For these cases, publishers can add extra packages manually in the Publisher UI or via a req_extra.txt file.
ShareBridge can optionally ensure selected app subdirectories exist in the deployment.
This is useful for apps that expect writable folders such as data/, uploads/, cache/, or tmp/.
Important:
- This only provisions directories in the deployment output
- It does not modify the Shiny app code
- The app itself must still reference and use those folders
- Directories that already exist in the source app are detected and offered for selection
ShareBridge supports an optional Pandoc preparation mode.
When the Include Pandoc option is enabled:
- ShareBridge creates a
pandoc/folder in the deployment output - ShareBridge writes a
README_Pandoc.txtinto that folder - ShareBridge adds relevant R Markdown support packages to
req.txt
By default, ShareBridge does not copy a Pandoc installation automatically. This keeps deployment size smaller. If your app needs PDF generation or R Markdown rendering, place a local Pandoc installation into pandoc/ with pandoc/pandoc.exe. At runtime, ShareBridge will use that local Pandoc folder if present.
End users launch apps through LaunchApp.hta, which starts the local runtime without showing a console window.
Apps open in a browser using a friendly local loopback URL such as:
http://sharebridge-my_app.localhost:3670
If the preferred port is already in use, ShareBridge falls back to a random local port.
Each app gets a deterministic preferred port derived from its app ID, in the range 3400–4400. This ensures two different apps published through ShareBridge default to different ports without manual configuration.
If the preferred port is unavailable at launch time, run.R falls back to a random port via httpuv::randomPort().
Stored in logs/publisher/. Each build and strip_r operation creates a timestamped log file. Logs older than 30 days are cleaned automatically.
These logs help diagnose failed builds, dependency issues, portable R copy problems, and package bundling issues. They can be viewed and deleted from within the Publisher UI.
Deployed apps create logs during launch via run.bat. Logs are typically written to a temp location (%TEMP%\{APP_ID}_logs\), with fallback to the local logs/ folder. Logs older than 7 days are cleaned automatically.
Use PublishApp.hta (recommended) or publish.bat. Do not launch publish.bat directly unless you specifically want to see console output.
End users should use LaunchApp.hta. This hides the console window and reads the app name from app_meta.cfg for the window title.
- Windows
- R available via one of:
R-portable/in the ShareBridge root- A system R installation
Rscript.exeon PATH
- Required R packages:
shiny,processx,jsonlite
- Windows
- SharePoint or OneDrive sync available
- No admin rights required (if R and packages are bundled)
- No R installation required (if portable R is bundled)
- Build the deployment locally using the Publisher UI
- Copy the output folder to SharePoint or a synced network location
- Have users sync the folder locally
- Tell users to open
LaunchApp.hta
This avoids admin installs, MSI packaging, per-user R setup, and direct package installation on user machines.
- OneDrive sync lag: Users may launch before all files are synced. The app may fail with "package not found" until sync completes.
- Path length limits: Deeply nested synced folders can hit Windows' 260-character path limit. Keep app folder names short.
- HTA restrictions: Some environments block
.htafiles via Group Policy. Userun.batas a fallback. - Writable data in synced folders: Frequently written app data should not live inside the synced deployment folder. Use a shared network drive path via
DATA_DIRinapp_meta.cfg. - Pandoc not bundled automatically: If your app needs Pandoc for PDF output, publishers must place Pandoc into the deployment
pandoc/folder.
- Runtime detection and message when local Pandoc is missing but expected
- Runtime feature/config file written into each deployment for app-side behavior
- Publisher UI summary panel showing what will be bundled (portable R, offline repo, Pandoc stub, writable dirs)
- Runtime version check between bundled R and expected R version at startup
- Deployment validation step after build
- Copy-to-SharePoint helper or post-build shortcut
- Custom app icon and branding in the launch window
- Update notification against a central manifest
- Optional self-test mode that opens the deployment after build
- Publisher export/import profiles for repeatable builds
- Standalone
.exepublisher wrapper (no R needed on publisher machine)
ShareBridge is an internal deployment framework. If you bundle R and CRAN packages, retain the applicable third-party license notices and attribution requirements for redistributed components. R itself is licensed under GPL-2 | GPL-3.