Vercel wordmark
Tremor is joining Vercel.

Getting Started

Everything you need to set up Tremor Blocks.

Requirements

Tremor is designed for React and requires React v18.2.0+

To use the Blocks, your project must fulfill one of the following setups:

Framework specific installation guideline
Detailed installation instructions can be found in our installation guide here
  1. 1

    Dependencies

    Learn more about Tremor here. To install all dependencies, run:

    npm install @radix-ui/react-accordion @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-hover-card @radix-ui/react-label @radix-ui/react-navigation-menu @radix-ui/react-popover @radix-ui/react-radio-group @radix-ui/react-select @radix-ui/react-slider @radix-ui/react-slot @radix-ui/react-switch @radix-ui/react-tabs @radix-ui/react-toast @radix-ui/react-tooltip @internationalized/date date-fns@3.6.0 react-day-picker@8.10.1 recharts @react-aria/datepicker @react-stately/datepicker
  2. 2

    Tailwind CSSv3.4.0+ and @tailwindcss/formsv0.5.10

    Learn more about Tailwind CSS here. To install, run:

    npm install tailwindcss@3.4.17 -D @tailwindcss/forms

    Add the @tailwind directives for each of Tailwind’s layers to your main CSS file (e.g. global.css).

    Make sure to restart the dev server to activate the tailwind configurations.

    // e.g. global.css  @tailwind base;@tailwind components;@tailwind utilities;
  3. 3

    Remix Iconv4.6.0

    Learn more about Remix Icon here. To install, run:

    npm install @remixicon/react
  4. 4

    Latest version of Tremor's `tailwind.config.js`

    See config examples of some popular frameworks below. Detailed installation instructions can be found in our installation guide here.

    import type { Config } from "tailwindcss"
    const config: Config = {  content: [    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",    "./src/lib/**/*.{js,ts,jsx,tsx,mdx}",  ],  theme: {    extend: {      keyframes: {        hide: {          from: { opacity: "1" },          to: { opacity: "0" },        },        slideDownAndFade: {          from: { opacity: "0", transform: "translateY(-6px)" },          to: { opacity: "1", transform: "translateY(0)" },        },        slideLeftAndFade: {          from: { opacity: "0", transform: "translateX(6px)" },          to: { opacity: "1", transform: "translateX(0)" },        },        slideUpAndFade: {          from: { opacity: "0", transform: "translateY(6px)" },          to: { opacity: "1", transform: "translateY(0)" },        },        slideRightAndFade: {          from: { opacity: "0", transform: "translateX(-6px)" },          to: { opacity: "1", transform: "translateX(0)" },        },        accordionOpen: {          from: { height: "0px" },          to: { height: "var(--radix-accordion-content-height)" },        },        accordionClose: {          from: {            height: "var(--radix-accordion-content-height)",          },          to: { height: "0px" },        },        dialogOverlayShow: {          from: { opacity: "0" },          to: { opacity: "1" },        },        dialogContentShow: {          from: {            opacity: "0",            transform: "translate(-50%, -45%) scale(0.95)",          },          to: { opacity: "1", transform: "translate(-50%, -50%) scale(1)" },        },      },      animation: {        hide: "hide 150ms cubic-bezier(0.16, 1, 0.3, 1)",        slideDownAndFade:          "slideDownAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)",        slideLeftAndFade:          "slideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)",        slideUpAndFade: "slideUpAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)",        slideRightAndFade:          "slideRightAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)",        // Accordion        accordionOpen: "accordionOpen 150ms cubic-bezier(0.87, 0, 0.13, 1)",        accordionClose: "accordionClose 150ms cubic-bezier(0.87, 0, 0.13, 1)",        // Dialog        dialogOverlayShow:          "dialogOverlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1)",        dialogContentShow:          "dialogContentShow 150ms cubic-bezier(0.16, 1, 0.3, 1)",      },    },  },  plugins: [require("@tailwindcss/forms")],}export default config
  5. 5

    Add utilities and helpers

    Our components depend on a few utilities. You can read more about them in the Utilities section.

    Create a new lib folder in /src. Add a new utils.ts file inside. Paste the following utilities into this file.

    // Tremor cx [v0.0.0]
    import clsx, { type ClassValue } from "clsx"import { twMerge } from "tailwind-merge"
    export function cx(...args: ClassValue[]) {  return twMerge(clsx(...args))}
    // Tremor focusInput [v0.0.1]
    export const focusInput = [  // base  "focus:ring-2",  // ring color  "focus:ring-blue-200 focus:dark:ring-blue-700/30",  // border color  "focus:border-blue-500 focus:dark:border-blue-700",]
    // Tremor focusRing [v0.0.1]
    export const focusRing = [  // base  "outline outline-offset-2 outline-0 focus-visible:outline-2",  // outline color  "outline-blue-500 dark:outline-blue-500",]
    // Tremor hasErrorInput [v0.0.1]
    export const hasErrorInput = [  // base  "ring-2",  // border color  "border-red-500 dark:border-red-700",  // ring color  "ring-red-200 dark:ring-red-700/30",]

    Next, we add the chart utilities. Add a new chartUtils.ts file and paste the following code into this file.

    // Tremor chartColors [v0.1.0]
    export type ColorUtility = "bg" | "stroke" | "fill" | "text"
    export const chartColors = {  blue: {    bg: "bg-blue-500",    stroke: "stroke-blue-500",    fill: "fill-blue-500",    text: "text-blue-500",  },  emerald: {    bg: "bg-emerald-500",    stroke: "stroke-emerald-500",    fill: "fill-emerald-500",    text: "text-emerald-500",  },  violet: {    bg: "bg-violet-500",    stroke: "stroke-violet-500",    fill: "fill-violet-500",    text: "text-violet-500",  },  amber: {    bg: "bg-amber-500",    stroke: "stroke-amber-500",    fill: "fill-amber-500",    text: "text-amber-500",  },  gray: {    bg: "bg-gray-500",    stroke: "stroke-gray-500",    fill: "fill-gray-500",    text: "text-gray-500",  },  cyan: {    bg: "bg-cyan-500",    stroke: "stroke-cyan-500",    fill: "fill-cyan-500",    text: "text-cyan-500",  },  pink: {    bg: "bg-pink-500",    stroke: "stroke-pink-500",    fill: "fill-pink-500",    text: "text-pink-500",  },  lime: {    bg: "bg-lime-500",    stroke: "stroke-lime-500",    fill: "fill-lime-500",    text: "text-lime-500",  },  fuchsia: {    bg: "bg-fuchsia-500",    stroke: "stroke-fuchsia-500",    fill: "fill-fuchsia-500",    text: "text-fuchsia-500",  },} as const satisfies {  [color: string]: {    [key in ColorUtility]: string  }}
    export type AvailableChartColorsKeys = keyof typeof chartColors
    export const AvailableChartColors: AvailableChartColorsKeys[] = Object.keys(  chartColors,) as Array<AvailableChartColorsKeys>
    export const constructCategoryColors = (  categories: string[],  colors: AvailableChartColorsKeys[],): Map<string, AvailableChartColorsKeys> => {  const categoryColors = new Map<string, AvailableChartColorsKeys>()  categories.forEach((category, index) => {    categoryColors.set(category, colors[index % colors.length])  })  return categoryColors}
    export const getColorClassName = (  color: AvailableChartColorsKeys,  type: ColorUtility,): string => {  const fallbackColor = {    bg: "bg-gray-500",    stroke: "stroke-gray-500",    fill: "fill-gray-500",    text: "text-gray-500",  }  return chartColors[color]?.[type] ?? fallbackColor[type]}
    // Tremor getYAxisDomain [v0.0.0]
    export const getYAxisDomain = (  autoMinValue: boolean,  minValue: number | undefined,  maxValue: number | undefined,) => {  const minDomain = autoMinValue ? "auto" : minValue ?? 0  const maxDomain = maxValue ?? "auto"  return [minDomain, maxDomain]}
    // Tremor hasOnlyOneValueForKey [v0.1.0]
    export function hasOnlyOneValueForKey(  array: any[],  keyToCheck: string,): boolean {  const val: any[] = []
      for (const obj of array) {    if (Object.prototype.hasOwnProperty.call(obj, keyToCheck)) {      val.push(obj[keyToCheck])      if (val.length > 1) {        return false      }    }  }
      return true}

Dark mode usage:

For all Block examples, we use bg-gray-950 as the overall background color. You can add this to the `<html className="dark:bg-gray-950">` tag.

Font smoothing (antialiasing):

On our website, we apply font smoothing and recommend you do the same. Simply add the antialiased utility to the HTML tag. `<html className="antialiased">`.

Further Reading and Ressources

Tremor

If you would like to learn more about our component library, check out tremor.so.

Figma UI Kit

Here you'll find all components and styles for building Tremor dashboards in Figma. Check out Tremor's Figma UI Kit.

Icons

We love the bold style of Remix Icon. It's a large icon set, licensed under `Apache License 2.0`.