MyNixOS website logo
Description

Build Modern Web Applications with 'htmx' and 'plumber2'.

A lightweight framework for building server-driven web applications in 'R'. 'htmxr' combines the simplicity of 'htmx' for partial page updates with the power of 'plumber2' for non-blocking HTTP endpoints. Build interactive dashboards and data applications without writing 'JavaScript', using familiar 'R' patterns inspired by 'Shiny'. For more information on 'htmx', see <https://htmx.org>.

htmxr htmxr website

hyperverse Lifecycle:experimental R-CMD-CHECK Codecov testcoverage CRANstatus downloadsmonthly downloadstotal

Build modern web applications in R — without writing JavaScript.

htmx handles client-side interactions via HTML attributes. plumber2 handles R endpoints server-side. {htmxr} bridges the two with R helpers that generate the right HTML and wire everything together.

Installation

install.packages("htmxr")

# or install the development version from GitHub:
pak::pak("hyperverse-r/htmxr")

How it works

htmxr architecture diagram

On first load, the server returns a complete HTML page. When the user interacts with an element (e.g. a slider), htmx sends a request to the R endpoint and swaps the response into the DOM — no JavaScript needed, no full page reload.

Example — Old Faithful

The hello example ships with {htmxr}. It reproduces the classic Old Faithful histogram with a slider to control the number of bins.

The page

The GET / endpoint returns a full HTML page built with hx_page() and hx_head(). The slider is created with hx_slider_input(), which generates a <input type="range"> wired to htmx attributes.

#* @get /
#* @parser none
#* @serializer html
function() {
  hx_page(
    hx_head(title = "Old Faithful Geyser Data", bootstrap_css),
    tags$div(
      class = "container py-5",
      # ...
      hx_slider_input(
        id = "bins",
        label = "Number of bins:",
        value = 30,
        min = 1,
        max = 50,
        get = "/plot",
        trigger = "input changed delay:300ms",
        target = "#plot"
      )
      # ...
    )
  )
}

The endpoint

The GET /plot endpoint is a standard plumber2 handler. It receives the bins query parameter, generates an SVG histogram, and returns it as an HTML fragment.

generate_plot <- function(bins = 30) {
  svg_string <- svglite::xmlSVG({
    x <- faithful[, 2]
    bins_seq <- seq(min(x), max(x), length.out = as.numeric(bins) + 1)
    hist(x, breaks = bins_seq, col = "darkgray", border = "white")
  })
  svg_string
}

#* @get /plot
#* @query bins:integer(30)
#* @parser none
#* @serializer none
function(query) {
  generate_plot(query$bins)
}

htmxr hello example screenshot

Run it

hx_run_example("hello")

Design philosophy

{htmxr} is built around a few explicit constraints:

  • Primitives, not a framework{htmxr} provides low-level building blocks. It doesn’t impose a page structure, a routing convention, or an application model. You compose your own app from small, predictable pieces.

  • HTML over abstraction — Every hx_* function produces standard HTML elements with hx-* attributes. There is no hidden layer, no reactivity graph, no virtual DOM. What you write in R is what lands in the browser.

  • CSS-agnostic{htmxr} doesn’t depend on any CSS framework. Use Bootstrap, Tailwind, plain CSS, or nothing at all.

  • R-centric — All logic lives in R. htmx handles client-side interactions via HTML attributes — no JavaScript required in your application code.

  • htmltools re-exportedtags, div, p, etc. are available directly from {htmxr}, so you don’t need to load {htmltools} separately.

Code of Conduct

Please note that the htmxr project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.

Metadata

Version

0.2.0

License

Unknown

Platforms (78)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows