Introduction & Setup
Relevant source files
The following files were used as context for generating this wiki page:
Better Tables is a type-safe, database-agnostic table library for React designed to eliminate the boilerplate associated with building complex data grids. It provides a unified API for defining columns, managing relationships, and handling features like advanced filtering, sorting, and virtualization with end-to-end type safety. The system is architected around a core logic layer, ORM-specific adapters, and a UI layer distributed via a CLI to allow for full customization.
Sources: README.md:1-15, CLAUDE.md:8-15
Core Architecture & Package Map
The project is structured as a monorepo containing specialized packages that separate concerns between core logic, database integration, and user interface.
| Package | Path | Responsibility |
|---|---|---|
@better-tables/core | packages/core | Logic for column builders, filter/sort managers, and adapter contracts. |
@better-tables/ui | packages/ui | React components (shadcn-style) and hooks. Distributed via CLI. |
@better-tables/cli | packages/cli | CLI tool for initializing the UI components in consumer projects. |
@better-tables/adapters-drizzle | packages/adapters/drizzle | Drizzle ORM adapter for SQL query generation across relationships. |
@better-tables/adapters-toolkit | packages/adapters/toolkit | Primitives for building custom ORM-agnostic adapters. |
The following diagram illustrates the flow of data from column definitions through the adapter to the rendered UI:
This data flow ensures that type safety is maintained from the database schema to the rendered React components.
Sources: CLAUDE.md:8-23, README.md:214-230
Project Setup
Requirements
- Bun: The primary package manager and runtime used for the workspace.
- Node.js: Version 18+ is required.
- React: The library target is React 19+.
Sources: CONTRIBUTING.md:7-10, README.md:6
Installation Steps
To begin contributing to the project, clone the repository and install dependencies using Bun.
git clone https://github.com/Better-Tables/better-tables.git
cd better-tables
bun install
bun run build # Compiles all packages
bun run typecheck # Verifies type safety across the monorepo
Sources: CONTRIBUTING.md:12-18
Development Workflow
The repository utilizes a workspace catalog to pin shared versions of React, Tailwind, and TypeScript. Standard commands include:
- Testing:
bun run test(root) runs tests for every package. Specific packages can be tested by navigating to their directory. - Linting: Per-package linting is done via
biome check .. The rootbun run lintcommand is mutative and auto-fixes issues across the whole repo. - Changesets: Required for any user-facing change to a published package (
core,cli,adapters-drizzle).
Sources: CLAUDE.md:25-45, CONTRIBUTING.md:43-50
Flagship API Initialization
The 0.6+ flagship API centers on the betterTables() instance and defineTable() factory, which provide a "Better-Auth-style" configuration experience.
Step 1: Define the Instance
Applications typically create a single instance in a central configuration file, selecting the appropriate database adapter.
import { betterTables } from '@better-tables/core';
import { drizzleAdapter } from '@better-tables/adapters-drizzle';
import { db } from './db';
// Create a single instance for the app
export const tables = betterTables({
database: drizzleAdapter(db),
});
Sources: plans/011-table-definition-dx-design.md:54-62, plans/039-documentation-truth.md:124-135
Step 2: Define Tables and Columns
Tables are defined using the instance, which allows for autocompletion based on the database schema. The t.* path builders allow for dot-notation paths to traverse relationships.
import { defineTable } from '@better-tables/core';
import type { tables } from './tables';
export const usersTable = defineTable<typeof tables>()('users', (t) => ({
columns: [
t.text('name').displayName('Name').filterable(),
t.text('profile.location').displayName('Location'), // Auto-traverses joins
t.count('posts').label('Total Posts'), // Aggregate support
],
}));
Sources: plans/011-table-definition-dx-design.md:64-77, README.md:41-55
UI Integration via CLI
Unlike traditional libraries, @better-tables/ui is not installed via npm. Instead, it is distributed as a set of shadcn-style components that are copied into the consumer project using the CLI.
CLI Initialization
The init command detects the project environment (e.g., Next.js), verifies a shadcn/ui setup, and copies components to a local directory (default: components/better-tables-ui/).
bunx @better-tables/cli init
The following sequence diagram shows the initialization process:
Summary & Significance
The Better Tables architecture ensures that complex table requirements—such as automatic relationship JOINs and synchronized URL states—are handled with minimal developer overhead. By utilizing a core logic package and CLI-distributed UI, the project provides a balance between an "out-of-the-box" experience and the flexibility required for production-grade applications. The flagship API introduced in version 0.6 further streamlines this by providing a unified, schema-aware configuration point that drives type safety across the entire stack.
Sources: README.md:17-38, plans/039-documentation-truth.md:37-45