Install The Headless Package
The headless package gives you VirtuosoDataTable, Column, ColumnHeader, and Cell without any preset styling. Pick it when you already have a design system, use non-Tailwind styling, or need fully custom markup around the table.
Install the package
Section titled “Install the package”pnpm add @virtuoso.dev/data-tablenpm, yarn, and bun work too.
Import structural styles
Section titled “Import structural styles”The package ships layout defaults (column sizing, box model) in a @layer virtuoso block. Import the stylesheet once in your app’s CSS or entry point:
@import '@virtuoso.dev/data-table/styles.css';import '@virtuoso.dev/data-table/styles.css'The @layer virtuoso wrapping puts these rules at the lowest cascade priority, so any plain CSS or Tailwind utility class overrides them.
Minimal headless example
Section titled “Minimal headless example”import { Cell, Column, ColumnHeader, VirtuosoDataTable, localModel } from '@virtuoso.dev/data-table'
import { rows } from './data'
const currency = new Intl.NumberFormat('en-US', {
currency: 'USD',
style: 'currency',
})
const model = localModel({ data: rows })
export default function App() {
return (
<VirtuosoDataTable
model={model}
style={{
height: 360,
border: '1px solid var(--border)',
borderRadius: 16,
overflow: 'hidden',
}}
>
<Column field="name">
<ColumnHeader>
{() => <div style={{ padding: '0 12px', fontWeight: 600, height: 44, display: 'flex', alignItems: 'center' }}>Product</div>}
</ColumnHeader>
<Cell>
{({ cellValue }) => (
<div style={{ padding: '0 12px', height: 44, display: 'flex', alignItems: 'center' }}>{String(cellValue)}</div>
)}
</Cell>
</Column>
<Column field="category">
<ColumnHeader>
{() => <div style={{ padding: '0 12px', fontWeight: 600, height: 44, display: 'flex', alignItems: 'center' }}>Category</div>}
</ColumnHeader>
<Cell>
{({ cellValue }) => (
<div style={{ padding: '0 12px', height: 44, display: 'flex', alignItems: 'center' }}>{String(cellValue)}</div>
)}
</Cell>
</Column>
<Column field="price">
<ColumnHeader>
{() => (
<div
style={{ padding: '0 12px', fontWeight: 600, height: 44, display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}
>
Price
</div>
)}
</ColumnHeader>
<Cell>
{({ cellValue }) => (
<div
style={{
padding: '0 12px',
height: 44,
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
fontVariantNumeric: 'tabular-nums',
}}
>
{currency.format(Number(cellValue))}
</div>
)}
</Cell>
</Column>
</VirtuosoDataTable>
)
}Next steps
Section titled “Next steps”The headless package exposes the full surface area: local and remote data models, instance control, scroll control, and testing utilities. Continue with data model and columns.