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:  83.9 °F
##  💧 Humidity:     72 %
##  🌧️  Rain/Precip:  0 in
##  💨 Wind Speed:   4.9 mph
##  Wind Direction: 227
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) {"☀️"}
  else if (prob < 50) {"⛅ "}
  else {"🌧"}}

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 ☀️ 93.8°F 75.6°F 1% 0in. 209
2026-07-01 ☀️ 97.4°F 76.3°F 1% 0in. 234
2026-07-02 ☀️ 93.9°F 77.9°F 7% 0.016in. 242
2026-07-03 91°F 73°F 38% 0.031in. 237
2026-07-04 84.3°F 72.8°F 48% 0.283in. 251
2026-07-05 85.9°F 67.2°F 47% 0.024in. 45
2026-07-06 88.3°F 65.8°F 24% 0in. 98

Hope this helps!