Installation

Prerequisites

Before installing TableCraft, ensure your environment meets the following requirements:

  • Node.js 18 or later
  • React 19 or later
  • Next.js 15 or later (App Router)
  • TypeScript 5.0 or later

Package Manager

Install the TableCraft package using your preferred package manager:

npm
npm install react-table-craft
yarn
yarn add react-table-craft
pnpm
pnpm add react-table-craft

Peer Dependencies

TableCraft relies on several peer dependencies that must be installed in your project. These are kept as peers to avoid version conflicts and to let you control upgrades independently.

Core peer dependencies
npm install @tanstack/react-table next-intl date-fns lucide-react export-to-csv clsx tailwind-merge class-variance-authority cmdk vaul

TableCraft also uses a set of Radix UI primitives for accessible UI components such as dropdowns, dialogs, popovers, and tooltips. Install them as follows:

Radix UI peer dependencies
npm install @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-label @radix-ui/react-popover @radix-ui/react-select @radix-ui/react-separator @radix-ui/react-slot @radix-ui/react-tooltip

Tailwind CSS Integration

TableCraft components are styled with Tailwind CSS. Add the library's source to your PostCSS content paths so Tailwind scans and includes all required utility classes.

postcss.config.mjs
/** @type {import('postcss-load-config').Config} */
const config = {
  plugins: {
    tailwindcss: {
      content: [
        "./src/**/*.{ts,tsx}",
        "./node_modules/react-table-craft/dist/**/*.{js,mjs}",
      ],
    },
  },
};

export default config;

TableCraft uses CSS custom properties for theming. Add the following variables to your global stylesheet (typically src/app/globals.css):

globals.css — CSS custom properties
:root {
  --tc-background: 0 0% 100%;
  --tc-foreground: 222.2 84% 4.9%;
  --tc-card: 0 0% 100%;
  --tc-card-foreground: 222.2 84% 4.9%;
  --tc-popover: 0 0% 100%;
  --tc-popover-foreground: 222.2 84% 4.9%;
  --tc-primary: 221.2 83.2% 53.3%;
  --tc-primary-foreground: 210 40% 98%;
  --tc-secondary: 210 40% 96.1%;
  --tc-secondary-foreground: 222.2 47.4% 11.2%;
  --tc-muted: 210 40% 96.1%;
  --tc-muted-foreground: 215.4 16.3% 46.9%;
  --tc-accent: 210 40% 96.1%;
  --tc-accent-foreground: 222.2 47.4% 11.2%;
  --tc-destructive: 0 84.2% 60.2%;
  --tc-destructive-foreground: 210 40% 98%;
  --tc-border: 214.3 31.8% 91.4%;
  --tc-input: 214.3 31.8% 91.4%;
  --tc-ring: 221.2 83.2% 53.3%;
  --tc-radius: 0.5rem;
}

.dark {
  --tc-background: 222.2 84% 4.9%;
  --tc-foreground: 210 40% 98%;
  --tc-card: 222.2 84% 4.9%;
  --tc-card-foreground: 210 40% 98%;
  --tc-popover: 222.2 84% 4.9%;
  --tc-popover-foreground: 210 40% 98%;
  --tc-primary: 217.2 91.2% 59.8%;
  --tc-primary-foreground: 222.2 47.4% 11.2%;
  --tc-secondary: 217.2 32.6% 17.5%;
  --tc-secondary-foreground: 210 40% 98%;
  --tc-muted: 217.2 32.6% 17.5%;
  --tc-muted-foreground: 215 20.2% 65.1%;
  --tc-accent: 217.2 32.6% 17.5%;
  --tc-accent-foreground: 210 40% 98%;
  --tc-destructive: 0 62.8% 30.6%;
  --tc-destructive-foreground: 210 40% 98%;
  --tc-border: 217.2 32.6% 17.5%;
  --tc-input: 217.2 32.6% 17.5%;
  --tc-ring: 224.3 76.3% 48%;
}

Next.js Integration

TableCraft uses next-intl for internationalization. Configure your Next.js project to use the next-intl plugin and set up the i18n request handler.

App Router required
TableCraft's i18n integration targets the Next.js App Router. Pages Router projects are not supported.
next.config.ts
import type { NextConfig } from "next";
import createNextIntlPlugin from "next-intl/plugin";

const withNextIntl = createNextIntlPlugin("./src/i18n/request.ts");

const nextConfig: NextConfig = {
  // your existing Next.js config
};

export default withNextIntl(nextConfig);

Create the next-intl request handler. This file is responsible for resolving the active locale and loading the corresponding message bundle on every server request.

src/i18n/request.ts
import { getRequestConfig } from "next-intl/server";
import { routing } from "./routing";

export default getRequestConfig(async ({ requestLocale }) => {
  let locale = await requestLocale;

  // Validate that the incoming locale is supported; fall back to the default.
  if (!locale || !routing.locales.includes(locale as never)) {
    locale = routing.defaultLocale;
  }

  return {
    locale,
    messages: (await import(`../../messages/${locale}.json`)).default,
  };
});