Skip to content

Repository files navigation

AI-DECLARATION: copilot

Plumber + React Cookbook

An R analysis script turned into an authenticated Plumber API, an LLM-powered summary API built on top of it, and two React front ends (web + mobile) that consume both.

From Plumbing Your Way to React: Using Plumber APIs to Evolve Shiny Systems, useR!2026.

Slides

Prerequisites

  • Docker + Docker Compose: for the one-step setup
  • R (tested on 4.5.0) and Node.js (tested on 22.x): only needed for the local, per-project setup
  • An OpenRouter API key: only needed to get real text out of summary-api; everything else works without one

Run everything with Docker

cp .env.example .env

Open .env and set OPENROUTER_API_KEY. Then:

docker compose up --build

The first build restores each R project's renv.lock and compiles any packages without a prebuilt binary, so it takes a while the first time. Later builds reuse Docker's layer cache and are fast unless a lockfile changes.

To stop everything:

docker compose down

Run a project locally, without Docker

Rscript analysis-script/analysis.R
cd flights-api
Rscript -e "renv::restore()"
PORT=8001 FLIGHTS_API_KEY=changeme-demo-key Rscript plumber.R
cd summary-api
Rscript -e "renv::restore()"
PORT=8002 FLIGHTS_API_URL=http://localhost:8001 FLIGHTS_API_KEY=changeme-demo-key \
  OPENROUTER_API_KEY=sk-or-... Rscript plumber.R
cd web-app
FLIGHTS_API_KEY=changeme-demo-key npm install && npm run dev
cd mobile-app
FLIGHTS_API_KEY=changeme-demo-key npm install && npm run dev -- --port 5174

FLIGHTS_API_KEY is deliberately not called API_KEY; R's .Renviron loading takes precedence over inline/shell-exported environment variables, so a generic name can silently collide with something unrelated already set on your machine.

The projects

analysis-script: A plain R script using dplyr, tidyr, stringr, purrr, lubridate, and ggplot2 over the nycflights13 dataset. Defines the functions everything else in this repo is built on: carrier delays, top routes, monthly trends, and airport traffic.

flights-api: The real backend: Plumber, renv, and Docker, with a static API key checked on every request. Structured with routers, middleware, hooks, and an OpenAPI spec patch. Every other service in this repo talks to this one.

summary-api: A second Plumber API that calls flights-api over HTTP and hands the JSON to an LLM through ellmer and OpenRouter to generate a plain-English summary.

web-app: A React (Vite) app: animated stat cards, an interactive route map plotted from real airport coordinates, a carrier delay chart, and AI-generated summaries pulled from summary-api.

mobile-app: A React (Vite) app styled for mobile: the same data as a set of swipeable, single-stat screens.

Architecture

Architecture diagram

Resources

flights-api's router/middleware/hooks structure and OpenAPI patch are adapted from Gotfrid/plumber-cookbook.

About

An example of using plumber along with React

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages