A tiny CLI weather {Rapp}ort

Author

Matt Dray

Published

March 1, 2026

A screenshot of a terminal that's running the comand 'weva tr197aa -h 24 -e', which returns a one-line weather report with temperature and weather emojis for now and a day later, plus the temperature extreems for today. The temperature values are bold and coloured.

tl;dr

The {weva} R package contains a titchy, opinionated command-line interface (CLI) to present an opinionated micro-weather report.

Building some {Rapp}ort

I’ve been making little Python-CLI concepts recently:

  • jot for recording notes
  • pet for a persistent cyberpet
  • tyle for a roguelike-like

I’ve been using Python mostly because it seems a better tool for the job than R.

So I was pleased to see a recent blog post about a new release of {Rapp}, an R package to help create CLIs.

Given my interests, it seemed fitting to try it out.

CLImate

But a CLI for what?

My colleagues and I have enjoyed twee weather CLIs of late, like weathr and wttr.in.

So, because I have no imagination: introducing the concept {weva} R package (‘wevvah’).

It does way less than those other examples and doesn’t have fun ASCII graphics. It’s just a simple toy project to see how {Rapp} works, with no guarantees. Is that enough disclaimers?

This was made possible by:

R console

From the R console, you could install it like:

pak::pak("matt-dray/weva")

Still in the R console, you can install the CLI:

weva::install_cli()

You’ll get a confirmation of where it’s been installed.

Terminal

From a terminal—not the R console—you can use weva to look up weather for a given UK postcode.

Let’s compare Lands End (‘top’ of mainland Britain) to John o’ Groats (‘bottom’) as I write this.

weva tr197aa
now 10.9°C ☁️ | +1h 11.3°C ☁️ 
weva kw14yr
now 6.1°C ☁️ | +1h 6.3°C 🌧️🪶 

The mini display has segments for the current and future temperature and weather. There are emoji modifiers for heavy, light and freezing versions of some weather types.

Surprise, it’s early March in Britain.

Hopefuly your day will be brightened by the styling with ANSI escape codes, assuming your terminal supports them.

Options

You can add some flags to adjust the settings. Use --hour (or its shortcut -h) to adjust the number of hours for the forward-look. Let’s look one day ahead.

weva tr197aa -h 24
now 10.9°C ☁️ | +24h 7.7°C 🌧️🪶 

So there’s light drizzle this time tomorrow and it will be cooler (did I mention it’s early March in Britain).

Note that you can only look at forecasts up to the end of the day after tomorrow.

Use the --extremes (-e) flag to also print a segment with today’s low and high temperatures. You can compound these options.

weva tr197aa -h 24 -e
now 10.9°C ☁️ | +24h 7.7°C 🌧️🪶 | today 9.3°C to 12°C 

Well, ‘extremes’ is perhaps a bit extreme for this termperature range.

Time is hard

‘Now’ and ‘later’ in this context are actually a bit awkward.

The Open-Meteo API returns the ‘current’ time as a quarter-hour increment, while ‘hourly’ information is the top of the hour.

My low-effort solution was to round ‘now’ to the nearest hour and declare ‘+1 hour’ as the hour after that.

This was made slightly more awkward because the hourly data is returned for the whole of the current day (i.e. some of it is from the past). That means we have to match the rounded ‘now’ time to the list of times for today to get its index, then add the user-supplied --hours to find the details for the correct time in the future.

So you can only ask for a forecast for the rest of today or the following two full days.

That’s a bit confusing, so you can use the --datetime (-d) option to expose the datetimes for the data in each segment of the report.

weva tr197aa -h 24 -e -d
2026-03-01 10:00 10.9°C 🌧️🪶 | 2026-03-02 10:00 7.7°C 🌧️🪶 | 2026-03-01 9.3°C to 12°C 

As I write, it’s 10:06 on 1 March 2026. That’s rounded to 10:00 for the ‘now’ time. And so 24 hours from now is 10:00 tomorrow: 1 March 2026.

Inside the crystal ball

What’s actually happening in the code?

{weva} is just a normal R package, with one difference: a script under exec/ that contains R code that {Rapp} will reinterpret into a CLI.

At time of writing it looks like this:

#!/usr/bin/env Rapp
#| name: weva
#| description: A micro weather report with 'Open-Meteo' and 'postcodes.io' APIs

#| description: A UK postcode
postcode <- NULL

#| description: Hours from now for the 'later' segment (up to three days)
#| short: h
hours <- 1L

#| description: Show API and calculated datetimes in 'now' and 'later' segments?
#| short: d
datetimes <- FALSE

#| description: Show a segment for today's min and max temperatures?
#| short: e
extremes <- FALSE

get_weather(postcode) |>
  prepare_report(hours, datetimes, extremes) |>
  cat()

Note in this file:

  • the shebang (#!), which gives the path to where {Rapp} is installed
  • the hashpipes (#|) for documenting our variables
  • that everything else is normal R code

{Rapp} interprets postcode <- NULL as a required positional argument for weva. You can just type the postcode without a flag.

Conversely, the remaining options must be named, though short names can be used to save typing. --hours (-h) is interpreted as an integer with a default of 1 --datetimes and --extremes (-d, -e) are off (FALSE) by default, but the user can just use the flag without an argument to turn it on.

What’s also nice is that {Rapp} gives us --help (and --help-yaml) for free, based on our variable documentation.

weva --help
Usage: weva [OPTIONS] <POSTCODE>

A micro weather report with 'Open-Meteo' and 'postcodes.io' APIs

Options:
  -h, --hours <HOURS>             Hours from now for the 'later' segment (up to
                                  three days)
                                  [default: 1] [type: integer]
  -d, --datetimes / --no-datetimes  Show API and calculated datetimes in 'now'
                                  and 'later' segments?
                                  [default: false]
                                  Enable with `--datetimes`.
  -e, --extremes / --no-extremes  Show a segment for today's min and max
                                  temperatures?
                                  [default: false]
                                  Enable with `--extremes`.

Arguments:
  <POSTCODE>  A UK postcode

In short, {Rapp} lets you write ‘normal’ looking R code that gets interpreted into a CLI with various types of options.

That’s quite a neat, low-effort way to create a CLI.

The here and now

{weva} is very limited and opinionated with little attention to proper request-handling and testing. Your kilometreage may vary.

It would be easy to get carried away and build something even more complex. I’ve achieved the content and learning I wanted, so I stop here.

In fact, I already used this tool yesterday before a trip. I discovered the day was going to be overcast with some showers. Who could have guessed?

But on more variable days, I’m reminded of Fran’s observation when faced with differing forecasts:

I had better go outside and see who’s right

Very wise.

Environment

Session info
Last rendered: 2026-03-01 12:18:36 GMT
R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Sequoia 15.6.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.4 compiler_4.5.2    fastmap_1.2.0     cli_3.6.5        
 [5] tools_4.5.2       htmltools_0.5.8.1 yaml_2.3.12       rmarkdown_2.29   
 [9] knitr_1.50        jsonlite_2.0.0    xfun_0.52         digest_0.6.37    
[13] rlang_1.1.7       evaluate_1.0.4   

Footnotes

  1. I don’t want to simply run scripts from the command line, which is what Rscript is for.↩︎

  2. With a respectful cockney accent.↩︎

  3. Remember: you shouldn’t trust ‘some dude’ telling you to install random stuff from the internet.↩︎

  4. For my purposes I don’t care about weather anywhere except in the UK. I’m more likely to know the postcode than latitude-longitude, so I’m happy to limit the tool in this way.↩︎

  5. Actually these postcodes are for the First & Last House pub and the John o’ Groats brewery.↩︎

  6. We don’t need to forecast beyond that, because we know the weather’s going to be really dicey and unpredictable.↩︎

  7. Important disambiguation.↩︎

  8. This is becoming a catch-phrase of this blog, along with ‘this does what I need to do’.↩︎

  9. Amusingly, given my time-related pains in {weva}, we went to Greenwich.↩︎

Reuse