diff --git a/howTo/shiny/App/app.R b/howTo/shiny/App/app.R
new file mode 100644
index 0000000000000000000000000000000000000000..1261959a2a317a1c4f150740d98a00d29b16c3a4
--- /dev/null
+++ b/howTo/shiny/App/app.R
@@ -0,0 +1,129 @@
+# Working through shiny tutorial, lesson 1
+# https://shiny.rstudio.com/tutorial/written-tutorial/lesson1/
+# https://shiny.rstudio.com/tutorial/
+
+# Uses code from woRflow/howTo/apiTutorial.md
+
+library(shiny)
+library(httr)
+library(jsonlite)
+library(lubridate)
+library(ggplot2)
+library(tidyr)
+
+# Define  functions ----
+
+getIntensity<- function(dateGet = input$dateToGet, longDF = TRUE) {
+  
+  response <-  httr::GET(paste0("https://api.carbonintensity.org.uk/intensity/",dateGet,"T00:00Z","/fw24h"))
+  
+  intensityPeriod <-  jsonlite::fromJSON(rawToChar(response$content))
+  
+  periodStart <- lubridate::ymd_hm(intensityPeriod$data$from)
+  periodEnd <- lubridate::ymd_hm(intensityPeriod$data$to)
+  
+  periodData<- intensityPeriod$data$intensity
+  
+  intensityDF <- cbind(periodStart,periodEnd,periodData)
+  # create time midpoint for plotting
+  intensityDF$periodMid <- intensityDF$periodStart + lubridate::minutes(15)
+  
+  intensityDF <- intensityDF[-1,] # remove 1st row
+  
+  if(longDF){
+  # prepare data - tidyr
+  intensityDF <- tidyr::gather(intensityDF, key = "measure", value = "value", c(forecast,actual))
+  } # end if(longDF)
+  
+  return(intensityDF)
+}
+
+# Define UI for app that draws a histogram ----
+ui <- fluidPage(
+  
+  # App title ----
+  titlePanel("GB Grid Electricity Carbon Intensity Forecast"),
+  tags$p("This app was created by ", tags$a(href = "https://energy.soton.ac.uk/rushby/","Tom Rushby "), 
+         tags$a(href = "https://twitter.com/tom_rushby","(@tom_rushby)"),
+         "for the ",tags$a(href = "https://energy.soton.ac.uk/","Energy and Climate Change Division"), 
+         tags$a(href = "https://twitter.com/EnergySoton","(@EnergySoton)"),"at the University of Southampton."),
+  
+  # Sidebar layout with input and output definitions ----
+  sidebarLayout(
+    
+    # Sidebar panel for inputs ----
+    sidebarPanel(
+      fluidRow(
+        tags$p("Select the date to view by clicking in the box below (defaults to today's date)."),
+        tags$p("Data for forecast carbon intensity is available up to four days ahead."),
+        tags$hr()
+      ),
+      
+      # Input: Slider for the number of bins ----
+      dateInput(inputId = "dateToGet",
+                label = "Select date for forecast:",
+                value = NULL,
+                min = lubridate::ymd(2020-01-01),
+                max = lubridate::today() + lubridate::days(3),
+                format = "yyyy-mm-dd",
+                startview = "month",
+                weekstart = 1,
+                language = "en")
+      
+    ),
+    
+    # Main panel for displaying outputs ----
+    mainPanel(
+      fluidRow(
+        tags$br(),
+        tags$p("The chart below shows the forecast and actual carbon intensity of electricity supplied by National Grid over the 24 hours selected.",
+               "The data illustrated by this app is retrieved from ", tags$a(href = "https://carbonintensity.org.uk/","National Grid ESO's Carbon Intensity API"),"."),
+        tags$p("Predicted carbon intensity of electricity is shown in blue (forecast).",
+               "The carbon intensity of electricity supplied is shown in red (actual)."),
+        tags$hr(),
+        
+        # Output: Text ----
+        #textOutput(outputId = "dateText"),
+        
+        # Output: Histogram ----
+        plotOutput(outputId = "intensityPlot")
+        
+      ) # row
+    ) # panel
+  ) # layout
+) # page
+
+# Define server logic required to draw a histogram ----
+server <- function(input, output) {
+  
+  # Display date selected ----
+  output$dateText <- renderText({
+    paste0("Date selected: ",input$dateToGet)
+    })
+  
+  # Get data and create data.frame
+  #DF <- reactive({getIntensity(dateGet = dateToGet)})
+  
+  # Create plot
+  output$intensityPlot <- renderPlot({
+    
+    plotCaption = paste0("Data from: https://api.carbonintensity.org.uk",
+                           "\nVisualisation: rushby.shinyapps.io/gridforecast")
+    
+    plotTitle = paste0("24-hour GB grid carbon intensity forecast for ",input$dateToGet)
+    
+    ggplot(getIntensity(dateGet = input$dateToGet, longDF = TRUE), aes(periodMid,value, fill = measure)) +
+      geom_col(position = "identity", alpha = 0.6) +
+      expand_limits(y = c(0,350)) +
+      labs(x = "Date and time",
+           y = expression("Intensity gCO"[2]/kWh),
+           fill = "Intensity",
+           title = plotTitle,
+           caption = plotCaption) +
+      theme(legend.position = "bottom")
+    
+  })
+  
+}
+
+shinyApp(ui = ui, server = server)
diff --git a/howTo/shiny/App/rsconnect/shinyapps.io/rushby/gridforecast.dcf b/howTo/shiny/App/rsconnect/shinyapps.io/rushby/gridforecast.dcf
new file mode 100644
index 0000000000000000000000000000000000000000..0a6af79e30b894025150f95ccf28505599cc9ba5
--- /dev/null
+++ b/howTo/shiny/App/rsconnect/shinyapps.io/rushby/gridforecast.dcf
@@ -0,0 +1,10 @@
+name: gridforecast
+title: GB Grid Electricity Carbon Intensity Forecast Visualisation
+username:
+account: rushby
+server: shinyapps.io
+hostUrl: https://api.shinyapps.io/v1
+appId: 2811298
+bundleId: 3630929
+url: https://rushby.shinyapps.io/gridforecast/
+when: 1600167776.24198