Skip to contents

Getting Started

Installation

install.packages("muiMaterial")

Or install the development version:

remotes::install_github("lgnbhl/muiMaterial")

Your first Material UI app

library(shiny)
library(muiMaterial)

ui <- muiMaterialPage(
  CssBaseline(
    Box(
      sx = list(p = 2),
      Typography("Hello Material UI!", variant = "h4")
    )
  )
)

server <- function(input, output, session) {}

shinyApp(ui, server)

Important: Use muiMaterialPage() instead of fluidPage() and wrap your UI in CssBaseline() to ensure proper styling. Material UI uses its own design system and can conflict with Bootstrap (see [Bootstrap conflict] below).

Shiny input wrappers

Material UI components become Shiny inputs with *.shinyInput() wrappers. For example, use Button.shinyInput() instead of Button() to capture user interactions in Shiny.

Explore available Shiny inputs with the showcase app (live here):

muiMaterial::muiMaterialExample("showcase")

Server-side rendering

When rendering components from the server, use shiny::renderUI() or shiny.react::renderReact() in your server function, and shiny::uiOutput() or shiny.react::reactOutput() in your UI.

Creating tabs

Use TabContext.shinyInput(), TabList.shinyInput(), and TabPanel.shinyInput() to create tabs with server-side reactivity, or TabContext.static(), TabList.static(), and TabPanel() for purely client-side tab switching. Read the vignette or see a minimal code example.

For more advanced navigation, use client-side routing with reactRouter.

Styling with sx

Customize any component using the sx argument for inline CSS-in-JS styling:

Box(
  sx = list(
    bgcolor = "primary.main",
    color = "white",
    p = 3,
    borderRadius = 2
  ),
  Typography("Styled with sx", variant = "h5")
)

It is more powerful and maintainable than traditional CSS. See the MUI sx documentation for all available properties.

Naming conventions

Function names in muiMaterial mirror the original MUI component names as closely as possible (e.g. Button(), Typography(), Drawer()). Suffixes are used to distinguish variants that add R/Shiny-specific behavior:

  • .shinyInput — Wraps a component as a Shiny input, so its value is available server-side via input$inputId. Use these when you need to read or react to user interactions in R. This convention is borrowed from the shiny.fluent package. Examples: Button.shinyInput(), Slider.shinyInput(), Autocomplete.shinyInput().

  • .triggerId — Wraps a component that binds to an external DOM element by its HTML id. The referenced element acts as a trigger (e.g. a button click opens a drawer or menu), with open/close state managed entirely on the client side. Examples: Drawer.triggerId(), Menu.triggerId().

  • .static — Wraps a component whose state is managed entirely on the client side (in React), with no round-trip to the Shiny server. Useful when server-side reactivity is not needed, for example tab switching that only shows/hides content. Examples: TabContext.static() and TabList.static().

Both .triggerId and .static variants keep state in the browser and never communicate with the Shiny server. The difference is that .triggerId components require a reference to an external trigger element, while .static components are self-contained.

CSS conflicts with Bootstrap

muiMaterialPage() suppresses Bootstrap by default, giving MUI components a clean CSS environment. If you need to mix MUI with Bootstrap-dependent packages (e.g. shiny, bslib, DT, plotly), see the CSS conflicts with Bootstrap vignette for details and workarounds.