인터페이스는 현지화되어 있으며, Skill 소개와 설명 문서는 선택한 언어로 AI가 자동 번역합니다. 코드·명령어·경로·전문 용어는 원문을 유지하며 원작자 문서가 우선합니다.
Skills 둘러보기
데이터 및 연구 · SKILL.md

scaffold-shiny-app

scaffold-shiny-app

Scaffold a new Shiny application using golem (production R package), rhino (enterprise), or vanilla (quick prototype) structure. Covers framework selection, project initialization, and first module creation. Use when starting a new interactive web application in R, creating a dashboard or data explorer prototype, setting up a production Shiny app as an R pa…

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill 문서

GitHub

name: scaffold-shiny-app locale: caveman source_locale: en source_commit: 82c77053 fence_basis_commit: 82c77053 translator: "Julius Brussee homage — caveman" translation_date: "2026-05-03" description: > Scaffold a new Shiny application using golem (production R package), rhino (enterprise), or vanilla (quick prototype) structure. Covers framework selection, project initialization, and first module creation. Use when starting a new interactive web application in R, creating a dashboard or data explorer prototype, setting up a production Shiny app as an R package with golem, or bootstrapping an enterprise Shiny project with rhino. license: MIT allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: shiny complexity: basic language: R tags: shiny, golem, rhino, scaffold, web-app, reactive

Scaffold Shiny App

Make new Shiny app with prod-ready structure. Use golem, rhino, or vanilla scaffolding.

When Use

  • Start new interactive web app in R
  • Make dashboard or data explorer prototype
  • Set up prod Shiny app as R package (golem)
  • Bootstrap enterprise Shiny project (rhino)

Inputs

  • Required: App name
  • Required: Framework choice (golem, rhino, vanilla)
  • Optional: Module scaffolding (default: yes)
  • Optional: renv for dep management (default: yes)
  • Optional: Deploy target (shinyapps.io, Posit Connect, Docker)

Steps

Step 1: Choose Framework

Judge project needs to pick framework.

FrameworkBest ForStructure
golemProduction apps shipped as R packagesR package with DESCRIPTION, tests, vignettes
rhinoEnterprise apps with JS/CSS build pipelinebox modules, Sass, JS bundling, rhino::init()
vanillaQuick prototypes and learningSingle app.R or ui.R/server.R pair

Got: Clear framework decision based on scope, team needs.

If fail: Unsure? Default to golem — most structure, can simplify later. Vanilla only for throwaway prototypes.

Step 2: Scaffold Project

Golem Path

golem::create_golem("myapp", package_name = "myapp")

Creates.

myapp/
├── DESCRIPTION
├── NAMESPACE
├── R/
│   ├── app_config.R
│   ├── app_server.R
│   ├── app_ui.R
│   └── run_app.R
├── dev/
│   ├── 01_start.R
│   ├── 02_dev.R
│   ├── 03_deploy.R
│   └── run_dev.R
├── inst/
│   ├── app/www/
│   └── golem-config.yml
├── man/
├── tests/
│   ├── testthat.R
│   └── testthat/
└── vignettes/

Rhino Path

rhino::init("myapp")

Creates.

myapp/
├── app/
│   ├── js/
│   ├── logic/
│   ├── static/
│   ├── styles/
│   ├── view/
│   └── main.R
├── tests/
│   ├── cypress/
│   └── testthat/
├── .github/
├── app.R
├── dependencies.R
├── rhino.yml
└── renv.lock

Vanilla Path

Create app.R.

library(shiny)
library(bslib)

ui <- page_sidebar(
  title = "My App",
  sidebar = sidebar(
    sliderInput("n", "Sample size", 10, 1000, 100)
  ),
  card(
    card_header("Output"),
    plotOutput("plot")
  )
)

server <- function(input, output, session) {
  output$plot <- renderPlot({
    hist(rnorm(input$n), main = "Random Normal")
  })
}

shinyApp(ui, server)

Got: Project dir made with all scaffolding files.

If fail: Golem? Ensure golem package installed: install.packages("golem"). Rhino? Install from GitHub: remotes::install_github("Appsilon/rhino"). Vanilla? Ensure shiny + bslib installed.

Step 3: Configure Dependencies

Golem/Vanilla

# Initialize renv
renv::init()

# Add core dependencies
usethis::use_package("shiny")
usethis::use_package("bslib")
usethis::use_package("DT")         # if using data tables
usethis::use_package("plotly")     # if using interactive plots

# Snapshot
renv::snapshot()

Rhino

Deps managed in dependencies.R.

# dependencies.R
library(shiny)
library(bslib)
library(DT)

Got: All deps recorded in DESCRIPTION (golem) or dependencies.R (rhino), locked with renv.

If fail: renv::init() fails? Check write perms. Packages fail to install? Check R version compat.

Step 4: Create First Module

Golem

golem::add_module(name = "dashboard", with_test = TRUE)

Creates R/mod_dashboard.R and tests/testthat/test-mod_dashboard.R.

Rhino

Make app/view/dashboard.R.

box::use(
  shiny[moduleServer, NS, tagList, h3, plotOutput, renderPlot],
)

#' @export
ui <- function(id) {
  ns <- NS(id)
  tagList(
    h3("Dashboard"),
    plotOutput(ns("plot"))
  )
}

#' @export
server <- function(id) {
  moduleServer(id, function(input, output, session) {
    output$plot <- renderPlot({
      plot(1:10)
    })
  })
}

Vanilla

Add module functions to separate file R/mod_dashboard.R.

dashboardUI <- function(id) {
  ns <- NS(id)
  tagList(
    h3("Dashboard"),
    plotOutput(ns("plot"))
  )
}

dashboardServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    output$plot <- renderPlot({
      plot(1:10)
    })
  })
}

Got: Module file made with UI + server functions using proper namespacing.

If fail: Ensure module uses NS(id) for all input/output IDs in UI function. Without namespacing, IDs collide when module used multiple times.

Step 5: Run Application

# Golem
golem::run_dev()

# Rhino
shiny::runApp()

# Vanilla
shiny::runApp("app.R")

Got: App launches in browser without errors.

If fail: Check R console for error msgs. Common: missing packages (install), port in use (specify different port port = 3839), syntax errors in UI/server.

Checks

  • App dir has correct structure for chosen framework
  • shiny::runApp() launches without errors
  • At least one module scaffolded with UI + server functions
  • Deps recorded (DESCRIPTION or dependencies.R)
  • renv.lock captures all package versions
  • Module uses NS(id) for proper namespace isolation

Pitfalls

  • Choose vanilla for prod: Vanilla lacks testing, docs, deploy tooling. Use golem or rhino for anything beyond prototypes.
  • Missing namespace in modules: Every inputId and outputId in module UI must be wrapped with ns(). Forget = silent ID collisions.
  • golem without devtools workflow: golem apps are R packages. Use devtools::load_all(), devtools::test(), devtools::document() — not source().
  • rhino without box: rhino uses box for module imports. Do not fall back to library() calls — use box::use() for explicit imports.

See Also

  • build-shiny-module — make reusable Shiny modules with proper namespace isolation
  • test-shiny-app — set up shinytest2 and testServer() tests
  • deploy-shiny-app — deploy to shinyapps.io, Posit Connect, Docker
  • design-shiny-ui — bslib theming + responsive layout design
  • create-r-package — R package scaffolding (golem apps are R packages)
  • manage-renv-dependencies — detailed renv dep management
저장한 Skills