Getting Started with Shiny

· 5 min read · Updated March 7, 2026 · beginner
shiny web-apps r beginner interactive

Shiny is an R package that makes it incredibly easy to build interactive web applications directly from R. Whether you want to create a data dashboard, share interactive visualizations, or build a tool for your team, Shiny provides the framework to turn your R code into interactive web apps without requiring any HTML, CSS, or JavaScript knowledge.

In this tutorial, you’ll learn the fundamentals of Shiny: what it is, how to install it, the structure of a Shiny app, and how to create and run your first application.

What is Shiny?

Shiny is an R package developed by RStudio (now Posit) that lets you build interactive web applications entirely in R. It bridges the gap between R’s statistical capabilities and web technology, allowing you to:

  • Create interactive data dashboards
  • Build tools for data exploration
  • Share analysis results with non-R users
  • Create reproducible research prototypes
  • Deploy machine learning models as web services

The beauty of Shiny is that you don’t need to learn HTML, CSS, or JavaScript. You write all your logic in R, and Shiny handles the web interface automatically.

Installing Shiny

Getting started with Shiny is straightforward. Install it from CRAN using the install.packages() function:

install.packages("shiny")

Once installed, load the library in your R session:

library(shiny)

You’re now ready to build your first Shiny app.

Your First Shiny App

A minimal Shiny app requires just two components: a user interface (UI) and a server function. Here’s the classic “Hello World” example:

library(shiny)

ui <- fluidPage(
  "Hello, World!"
)

server <- function(input, output, session) {
}

shinyApp(ui, server)

When you run this code, Shiny starts a web server and opens your default browser displaying “Hello World!” Simple as that.

Understanding the UI and Server

Every Shiny app follows the same basic structure: a UI object that defines the layout and inputs, and a server function that contains your R code and defines outputs.

The User Interface (UI)

The UI defines what the user sees and interacts with. Shiny provides various layout functions, the most common being fluidPage(), which creates a responsive layout that adjusts to different screen sizes.

ui <- fluidPage(
  titlePanel("My First App"),
  
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins", 
                  "Number of bins:", 
                  min = 1, 
                  max = 50, 
                  value = 30)
    ),
    
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

This UI creates a page with a title, a sidebar with a slider input, and a main panel where a plot will be displayed.

The Server Function

The server function is where the magic happens. It’s where you read inputs, perform calculations, and define outputs:

server <- function(input, output, session) {
  
  output$distPlot <- renderPlot({
    
    # Generate bins based on input$bins from ui
    x    <- faithful[, 2]
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    # Draw the histogram
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
    
  })
  
}

The server function receives three arguments:

  • input: A list of all input values from the UI
  • output: A list of objects that will be sent back to the browser
  • session: A session object for advanced control

You define outputs using render*() functions, where * is the type of output (plot, text, table, etc.). Each output in the UI must have a corresponding output$<name> defined in the server.

Running Your App

There are three ways to run a Shiny app:

Method 1: Run from an R Script

Save your app code in an file called app.R and use:

shiny::runApp("app.R")

Method 2: Run from the Console

If you’ve defined ui and server in your R console, simply call:

shinyApp(ui = ui, server = server)

Method 3: Use RStudio

In RStudio, simply press the “Run App” button in the toolbar when you have an app.R file open.

When you run a Shiny app, Shiny starts a local web server and automatically opens your default browser pointing to http://127.0.0.1:xxxxx. The app is fully functional and interactive.

A Complete Example: Interactive Histogram

Let’s put everything together with a complete example that creates an interactive histogram of the Old Faithful geyser data:

library(shiny)

# Define UI
ui <- fluidPage(
  titlePanel("Old Faithful Geyser Data"),
  
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 5,
                  max = 50,
                  value = 30)
    ),
    
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

# Define server
server <- function(input, output, session) {
  
  output$distPlot <- renderPlot({
    x    <- faithful$waiting
    bins <- seq(min(x), max(x), length.out = input$bins + 1)
    
    hist(x, 
         breaks = bins, 
         col = "steelblue", 
         border = "white",
         xlab = "Waiting time (minutes)",
         main = "Old Faithful Geyser Eruptions")
  })
  
}

# Run app
shinyApp(ui, server)

This example demonstrates several key concepts:

  • Using titlePanel() to add a title
  • Using sidebarLayout() for a standard dashboard layout
  • Using sliderInput() to create an interactive control
  • Using plotOutput() to display a plot
  • Using renderPlot() to generate the plot server-side
  • Reactivity: the plot automatically updates when you move the slider

Reactivity: How Shiny Knows When to Update

One of the most important concepts in Shiny is reactivity. When a user changes an input, Shiny automatically re-executes any code that depends on that input.

In our histogram example, the code inside renderPlot() depends on input$bins. When the user moves the slider, Shiny detects this dependency and re-runs the plot automatically. You don’t need to write any explicit update code—this is handled by Shiny’s reactive system.

Next Steps

Now that you’ve built your first Shiny app, here’s what to explore next:

  • More input controls: Shiny provides many input types including textInput(), selectInput(), checkboxInput(), dateInput(), and fileUpload()
  • Reactive expressions: Use reactive() to cache intermediate calculations and improve performance
  • Customizing the UI: Explore navbarPage() for multi-page apps and moduleServer() for reusable components
  • Shiny extensions: Check out shinythemes for styling, shinyWidgets for enhanced inputs, and htmlwidgets for integrating JavaScript libraries
  • Deployment: Share your apps using Shiny Server, Posit Connect, or shinapps.io

Shiny opens up a world of possibilities for creating interactive data applications. The skills you’ve learned here—understanding UI and server, using inputs and outputs, and leveraging reactivity—form the foundation for building more complex applications.