
Security News
RubyGems Adds Cooldown Feature to Bundler for Newly Published Gems
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.
Documentation: gigatable.aiken.si
Gigatable is supported by Preskok ThinkTank.
Excel-like datatable for React with cell selection, range selection, inline editing, copy/paste, fill handle, column resizing, and undo/redo — powered by TanStack Table and TanStack Virtual.
Install:
npx gigatable initcopies the source files directly into your project. You own the code.
npx gigatable init
This will:
src/gigatable)@tanstack/react-table, @tanstack/react-virtual, clsx// app.tsx
import { Gigatable, useGigatable } from "./gigatable";
import { columns } from "./columns";
import { myData } from "./data";
export function App() {
const { table, paste, applyFill, undo, redo } = useGigatable({
columns,
data: myData,
enableColumnResizing: true,
columnResizeMode: "onChange",
history: true,
});
return (
<Gigatable
table={table}
allowCellSelection
allowRangeSelection
allowHistory
allowPaste
allowFillHandle
allowColumnResizing
paste={paste}
applyFill={applyFill}
undo={undo}
redo={redo}
/>
);
}
Use TanStack Table's ColumnDef format. Mark editable columns with meta: { editable: true } and wrap the cell with <EditableCell>.
// columns.tsx
import { ColumnDef } from "@tanstack/react-table";
import { EditableCell, EditableCellInputProps } from "./gigatable";
const TextInput = ({
value,
onChange,
onKeyDown,
onBlur,
}: EditableCellInputProps<string>) => (
<input
autoFocus
value={value as string}
onChange={onChange}
onKeyDown={onKeyDown}
onBlur={onBlur}
/>
);
const NumberInput =
(step = 1) =>
({ value, onChange, onKeyDown, onBlur }: EditableCellInputProps<number>) =>
(
<input
autoFocus
type="number"
step={step}
value={value as number}
onChange={onChange}
onKeyDown={onKeyDown}
onBlur={onBlur}
/>
);
export const columns: ColumnDef<MyRow, unknown>[] = [
{
accessorKey: "id",
header: "ID",
size: 80,
// no meta.editable — read-only
},
{
accessorKey: "name",
header: "Name",
size: 200,
cell: (cell) => <EditableCell {...cell} renderInput={TextInput} />,
meta: { editable: true },
},
{
accessorKey: "score",
header: "Score",
size: 100,
cell: (cell) => <EditableCell {...cell} renderInput={NumberInput(0.1)} />,
meta: { editable: true },
},
];
Add the type augmentation file to your tsconfig.json:
{
"include": ["src", "src/gigatable/types/react-table.ts"]
}
This enables the meta: { editable: true } property on column definitions without type errors.
useGigatable(options)Wraps TanStack Table's useReactTable. Accepts all standard TableOptions<TData> except getCoreRowModel (added automatically).
| Option | Type | Default | Description |
|---|---|---|---|
columns | ColumnDef<TData, TValue>[] | required | TanStack column definitions |
data | TData[] | required | Row data. Synced to internal state when the array reference changes. |
history | boolean | false | Enable undo/redo tracking |
maxHistorySize | number | 20 | Max undo steps retained |
enableColumnResizing | boolean | TanStack default | Enable TanStack column resizing state and handlers |
columnResizeMode | "onChange" or "onEnd" | TanStack default | Use "onChange" for live width updates while dragging |
Returns: { table, paste, applyFill, undo, redo, clear, canUndo, canRedo }
<Gigatable>| Prop | Type | Default | Description |
|---|---|---|---|
table | Table<TData> | required | Instance from useGigatable |
allowCellSelection | boolean | false | Click selection + arrow key navigation |
allowRangeSelection | boolean | false | Drag + Shift+Arrow range. Requires allowCellSelection. |
singleColumnCellSelection | boolean | false | Drag + Shift+Arrow range down one column. Requires allowCellSelection; works when allowRangeSelection is false. |
allowHistory | boolean | false | Ctrl/Cmd+Z / Ctrl/Cmd+Shift+Z. Requires undo + redo. |
allowPaste | boolean | false | Ctrl/Cmd+V paste (TSV). Requires paste. |
allowFillHandle | boolean | false | Drag-fill down. Requires applyFill + meta: { editable: true } columns. |
allowColumnResizing | boolean | false | Header-border drag resizing. Requires enableColumnResizing in useGigatable. |
paste | Function | — | From useGigatable. Required when allowPaste. |
applyFill | Function | — | From useGigatable. Required when allowFillHandle. |
undo | () => void | — | From useGigatable. Required when allowHistory. |
redo | () => void | — | From useGigatable. Required when allowHistory. |
allColumnsEditable | boolean | false | Make every column editable with a default text input. Columns with meta: { editable: true } keep their own renderInput. |
onPasteComplete | (result: PasteResult) => void | — | Called after each paste with change details. |
theme | GigatableTheme | themes.light | Customise visual appearance. |
<EditableCell>Renders a cell in either view mode (double-click/Enter to edit) or edit mode. Accepts all TanStack CellContext<TData, TValue> props plus:
| Prop | Type | Description |
|---|---|---|
renderInput | FC<EditableCellInputProps<TValue>> | Your custom input component |
EditableCellInputProps<TValue>Props passed to your renderInput component:
| Prop | Description |
|---|---|
value | Current cell value |
onChange | Standard input change handler |
onBlur | Commits value and exits edit mode |
onValueChange | Commit a value string directly (for custom/select inputs) |
onKeyDown | Forward to handle Tab (save + move), Enter (save), Escape (cancel) |
cancelEditing | Discard changes and return to view mode |
className | Optional className for the input element |
PasteResultReturned by paste() and passed to onPasteComplete:
interface PasteResult {
changes: CellChange[];
totalChanges: number;
}
interface CellChange {
rowIndex: number;
rowId: string;
columnId: string;
columnHeader: string;
oldValue: unknown;
newValue: unknown;
}
| Shortcut | Action |
|---|---|
| Click | Select cell |
| Shift+Click / Drag | Extend range selection |
| Arrow keys | Move selection |
| Shift+Arrow | Extend range |
| Ctrl/Cmd+Home/End | Jump to first/last row |
| Enter | Enter edit mode |
| Double-click | Enter edit mode |
| Tab | Save + move to next cell |
| Escape | Cancel edit |
| Ctrl/Cmd+C | Copy selection to clipboard (TSV) |
| Ctrl/Cmd+V | Paste from clipboard |
| Ctrl/Cmd+Z | Undo |
| Ctrl/Cmd+Shift+Z | Redo |
| Drag header border | Resize column |
| Double-click header border | Reset column width |
Column resizing is opt-in at both the TanStack state layer and the Gigatable render layer:
const { table } = useGigatable({
columns,
data,
enableColumnResizing: true,
columnResizeMode: "onChange",
});
<Gigatable table={table} allowColumnResizing />;
Persist widths by controlling TanStack sizing state:
const [columnSizing, setColumnSizing] = useState({});
const { table } = useGigatable({
columns,
data,
enableColumnResizing: true,
columnResizeMode: "onChange",
state: { columnSizing },
onColumnSizingChange: setColumnSizing,
});
Three built-in presets are available. Pass one as the theme prop, or spread and override individual fields.
import { themes, Gigatable } from "./gigatable";
// Use a preset
<Gigatable theme={themes.dark} ... />
// Customize on top of a preset
<Gigatable theme={{ ...themes.dark, header: { background: "var(--brand)" } }} ... />
// Partial custom theme — unset fields fall back to themes.light
<Gigatable theme={{ row: { height: 36 }, selection: { outline: "orange" } }} ... />
The GigatableTheme interface groups fields by visual area:
import type { GigatableTheme } from "./gigatable";
const myTheme: GigatableTheme = {
header: { background: "#1e293b", textColor: "#f8fafc", height: 40 },
row: { height: 32, background: "#ffffff", hoverBackground: "#f1f5f9" },
cell: { borderColor: "#e2e8f0", fontSize: 13, paddingX: 12, paddingY: 6 },
selection: { outline: "var(--primary)", rangeBackground: "rgba(59,130,246,0.1)" },
paste: { highlightBackground: "rgba(134,239,172,0.25)" },
fill: { previewBackground: "#eff4ff", previewTextColor: "#6b8ccd" },
};
All values accept strings (including CSS variable references like "var(--primary)") or numbers (treated as px).
FAQs
Excel-like datatable for React — add it to your codebase with npx gigatable init
We found that gigatable demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.