This guide briefly explains the steps I took to build a weather app for
the Debian(Trixie) operating system command line using only R.

R Packages

suppressPackageStartupMessages({
  library(crayon)
  library(cli)
  library(httr2)
  library(knitr)
})

Fetch Data

I used the API from https://open-meteo.com/en/docs as the data source.
The site provides many options and data parameters than can be returned when
making an API call. I specified the GFS model and parameters included temperature,
relative humidity, precipitation probability, wind speed, and wind direction.

I created a request object using httr2::request() and then performed the
request with httr2::req_perform(). The data is returned in JSON format so
httr2::resp_body_json is used to parse the data.

url <- "https://api.open-meteo.com/v1/forecast?latitude=42.7325&longitude=-84.5555&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,precipitation_probability_max,wind_direction_10m_dominant&models=gfs_seamless&current=temperature_2m,relative_humidity_2m,precipitation,wind_direction_10m,wind_speed_10m&timezone=America%2FNew_York&wind_speed_unit=mph&precipitation_unit=inch&temperature_unit=fahrenheit"
response <- request(url) %>% req_perform()
data <- resp_body_json(resp = response)

Using print(data) I can now see what was returned by the API call.

Current Conditions Panel

This panel is pretty straightforward. I’m using cli::cli_h1 to make a header
and crayon::bold() and crayon::green(), crayon::blue(), etc. to add text
effects.

cli_h1(bold("Currently in Lansing, MI"))
## 
## ── Currently in Lansing, MI ────────────────────────────────────────────────────
cat("\n")
cat(bold("🌡️  Temperature: "), green(data$current$temperature_2m, "°F\n"),
    bold("💧 Humidity:    "), cyan(data$current$relative_humidity_2m, "%\n"),
    bold("🌧️  Rain/Precip: "), blue(data$current$precipitation, "in\n"),
    bold("💨 Wind Speed:  "), yellow(data$current$wind_speed_10m, "mph\n"),
    bold("Wind Direction:"), black(data$current$wind_direction_10m))
## 🌡️  Temperature:  94.1 °F
##  💧 Humidity:     49 %
##  🌧️  Rain/Precip:  0 in
##  💨 Wind Speed:   13.8 mph
##  Wind Direction: 228
cat("\n")

Note: To add emojis I had to search for the ASCII unicode characters. Press
ctrl+shift+u and then type in the 4 digit code and press enter.

7 Day Forecast Panel

This panel is a bit more involved as it requires a function. The first
function is assigning an icon for the day based on the probability of
precipitation.

get_precip_emoji <- function(prob){
  if (prob < 20) return("☀️")
  if (prob < 50) return("⛅ ")
  return("🌧")}

I could then build my 7 day data frame using data.frame():

forecast_df <- data.frame(Day = as.Date.character(data$daily$time),
  Icon =  sapply(data$daily$precipitation_probability_max, get_precip_emoji),
  High = paste0(data$daily$temperature_2m_max, "°F"),
  Low = paste0(data$daily$temperature_2m_min, "°F"),
  Precip_Prob = paste0(data$daily$precipitation_probability_max, "%"),
  Precip_Total = paste0(data$daily$precipitation_sum, "in."),
  Wind_Direction = paste0(data$daily$wind_direction_10m_dominant))

Finally, using knitr::kable() I could produce the table with absolutely zero
formatting required.

kable(forecast_df)
Day Icon High Low Precip_Prob Precip_Total Wind_Direction
2026-06-30 ☀️ 94.3°F 75.6°F 2% 0in. 215
2026-07-01 ☀️ 97.4°F 75.8°F 6% 0in. 231
2026-07-02 ☀️ 94.3°F 78.4°F 7% 0in. 242
2026-07-03 92.1°F 74.6°F 47% 0.012in. 237
2026-07-04 87.9°F 70.7°F 47% 0.528in. 249
2026-07-05 80.9°F 62.9°F 45% 0.004in. 54
2026-07-06 84.1°F 62.4°F 20% 0in. 80

Hope this helps!