Overview

Palantir Blueprint is a React component library aimed at data-dense desktop interfaces: analyst tools, dashboards, admin consoles, internal apps. It is not a marketing-site toolkit and not a mobile-first kit. This page covers when to reach for it, the core components worth knowing, and the caveats that catch new teams.

Reach for Blueprint for data-dense internal tools

Pick Blueprint when the app fits the brief it was designed for.

  • Internal analyst tools, ops dashboards, admin consoles.
  • Read-heavy tables with sorting, filtering, and inline editing.
  • Multi-pane workspaces with menus, popovers, and dialogs.
  • Desktop-first usage with keyboard shortcuts and dense layouts.

Avoid Blueprint for customer-facing marketing sites, mobile-first apps, or designs that need bespoke styling on every component. For those, see shadcn and tailwind.

Use the right packages

Blueprint is split into focused packages. Install only what each app uses.

  • @blueprintjs/core: buttons, dialogs, menus, toasters, form controls.
  • @blueprintjs/table: the virtualized table.
  • @blueprintjs/select: combobox, multi-select, suggest.
  • @blueprintjs/datetime2: date and time pickers.
  • @blueprintjs/icons: the icon set; import individual icons to keep bundles small.

Each package ships its own CSS file that must be imported once at the app entry:

import "normalize.css";
import "@blueprintjs/core/lib/css/blueprint.css";
import "@blueprintjs/icons/lib/css/blueprint-icons.css";
import "@blueprintjs/table/lib/css/table.css";

Know the core components

These cover most of a Blueprint app:

  • Table2: virtualized, column-resizable, supports cell renderers and editable cells. Use it for any list over a few hundred rows.
  • Dialog and OverlayToaster: portal-rendered modals and toasts. OverlayToaster.create() returns a toaster instance; share one per app.
  • Menu, MenuItem, Popover, ContextMenu: keyboard-navigable menus and right-click menus. Compose Menu inside Popover for dropdowns.
  • FormGroup, InputGroup, NumericInput, TextArea: form controls with consistent labels and helper text.
  • Tabs, Tree, Tag, Callout: layout and informational primitives.

Read the docs for a component before reaching for a third-party alternative; Blueprint usually has it.

Theme with Sass variables or CSS custom properties

Blueprint ships a Sass-based theme. Override variables before importing the CSS to retheme.

@use "@blueprintjs/core/lib/scss/variables" with (
  $pt-intent-primary: #2965cc,
  $pt-grid-size: 10px
);
@import "@blueprintjs/core/lib/css/blueprint.css";

For runtime theming, Blueprint also exposes a set of CSS custom properties. Toggle the .bp5-dark class on a wrapping element to flip dark mode. Avoid editing component CSS in place; you will pay for it on the next package upgrade.

Overlays render to a portal; mount the portal target deliberately

Dialogs, popovers, tooltips, and toasters render through a React portal. By default, they mount onto document.body. That is fine for most apps. When a parent applies CSS containment, a transform, or a stacking context that the overlay needs to escape, mount it explicitly:

<OverlaysProvider>
  <App />
</OverlaysProvider>

When mixing Blueprint dialogs with a Radix-based component (a shadcn Dialog), pick one overlay system per surface. Stacking two portal systems on top of each other produces focus-trap and z-index bugs.

Run Blueprint 5 with React 19

Blueprint 5 supports React 18 and React 19. Pin to the latest @blueprintjs/* 5.x release. Older Blueprint 4 packages use legacy React APIs that will not work on React 19; upgrade before adopting.

For Next.js 15 App Router (see nextjs), Blueprint components use browser APIs and must run inside a "use client" boundary. Mark the component file or its nearest parent as client and let the server render the shell around it.

Mind the bundle: import icons individually

Blueprint’s icon set is large. Importing the barrel pulls in every icon.

// Bad: pulls all icons into the bundle.
import { Icon } from "@blueprintjs/core";
<Icon icon="folder-open" />;
 
// Better: import the icon component directly.
import { FolderOpen } from "@blueprintjs/icons";
<FolderOpen />;

Configure the bundler to tree-shake @blueprintjs/icons (modern Vite and Next.js do this automatically). Audit the bundle after the first build; a 1 MB icon payload usually means the import path is wrong.