---
title: "Palantir Blueprint Best Practices"
slug: "blueprint"
category: "frontend"
tags: ["frontend", "blueprint", "react"]
status: "stable"
last_updated: 2026-08-14
summary: "When to pick Blueprint 6, core components for data-dense UIs, theming with Sass tokens, portal overlays, React 19 integration, and tree-shaking caveats."
related: ["[[frontend/react]]", "[[frontend/shadcn]]"]
---

## 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 [[frontend/shadcn]] and [[frontend/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:

```ts
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:

- `Table`: virtualized, column-resizable, supports cell renderers and editable cells. Use it for any list over a few hundred rows. (Blueprint 6 renamed the v4/v5 `Table2`/`ColumnHeaderCell2` APIs to the unversioned `Table`/`ColumnHeaderCell`; the "2" names remain as deprecated aliases.)
- `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.

```scss
@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 [[frontend/css-custom-properties|CSS custom properties]]. Toggle the `.bp6-dark` class on a wrapping element to flip dark mode (the namespace changed from `bp5-` to `bp6-` in Blueprint 6). 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:

```tsx
<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 6 with React 19

Blueprint 6 (current since mid-2025; CSS namespace `bp6-`) requires React 18 or 19 and dropped support for React 16/17 as peer dependencies. Pin to the latest `@blueprintjs/*` 6.x release. Blueprint 5 (`bp5-` namespace) still works on React 19 but is the previous major; Blueprint 4 and earlier use legacy React APIs that will not work on React 19.

For Next.js [[frontend/nextjs-app-router|App Router]] (see [[frontend/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.

```ts
// 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 [[glossary/tree-shaking|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.

## Related

- [[frontend/react]]
- [[frontend/shadcn]]
