From 58c1584f34989dd05c6b42ca4e55b0233e22804a Mon Sep 17 00:00:00 2001 From: Isaac Hunja Date: Wed, 4 Mar 2026 06:54:14 +0300 Subject: [PATCH 1/2] fix(table-core): guard process.env checks for non-bundled environments Replaces direct `process.env.NODE_ENV` references with a safe `isDev()` utility that checks for the existence of `process` before accessing it. This prevents `ReferenceError: process is not defined` when using @tanstack/table-core in vanilla JS environments loaded via importmaps (e.g. Rails) without a bundler. The built ESM output preserved raw `process.env.NODE_ENV` references which would throw in environments where `process` is not globally defined. Closes #6078 --- packages/table-core/src/core/column.ts | 6 +++--- packages/table-core/src/core/table.ts | 8 ++++---- packages/table-core/src/utils.ts | 14 +++++++++++++- .../table-core/src/utils/getFilteredRowModel.ts | 4 ++-- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/table-core/src/core/column.ts b/packages/table-core/src/core/column.ts index cbc220b724..5fdbaf8b62 100644 --- a/packages/table-core/src/core/column.ts +++ b/packages/table-core/src/core/column.ts @@ -6,7 +6,7 @@ import { RowData, ColumnDefResolved, } from '../types' -import { getMemoOptions, memo } from '../utils' +import { getMemoOptions, isDev, memo } from '../utils' export interface CoreColumn { /** @@ -100,7 +100,7 @@ export function createColumn( for (const key of accessorKey.split('.')) { result = result?.[key] - if (process.env.NODE_ENV !== 'production' && result === undefined) { + if (isDev() && result === undefined) { console.warn( `"${key}" in deeply nested key "${accessorKey}" returned undefined.`, ) @@ -116,7 +116,7 @@ export function createColumn( } if (!id) { - if (process.env.NODE_ENV !== 'production') { + if (isDev()) { throw new Error( resolvedColumnDef.accessorFn ? `Columns require an id when using an accessorFn` diff --git a/packages/table-core/src/core/table.ts b/packages/table-core/src/core/table.ts index 75702bda53..1548277024 100644 --- a/packages/table-core/src/core/table.ts +++ b/packages/table-core/src/core/table.ts @@ -1,4 +1,4 @@ -import { functionalUpdate, getMemoOptions, memo, RequiredKeys } from '../utils' +import { functionalUpdate, getMemoOptions, isDev, memo, RequiredKeys } from '../utils' import { Updater, @@ -284,7 +284,7 @@ export function createTable( options: TableOptionsResolved, ): Table { if ( - process.env.NODE_ENV !== 'production' && + isDev() && (options.debugAll || options.debugTable) ) { console.info('Creating Table Instance...') @@ -399,7 +399,7 @@ export function createTable( if (!row) { row = table.getCoreRowModel().rowsById[id] if (!row) { - if (process.env.NODE_ENV !== 'production') { + if (isDev()) { throw new Error(`getRow could not find row with ID: ${id}`) } throw new Error() @@ -510,7 +510,7 @@ export function createTable( getColumn: (columnId) => { const column = table._getAllFlatColumnsById()[columnId] - if (process.env.NODE_ENV !== 'production' && !column) { + if (isDev() && !column) { console.error(`[Table] Column with id '${columnId}' does not exist.`) } diff --git a/packages/table-core/src/utils.ts b/packages/table-core/src/utils.ts index c1f02a7c61..4d0ac82379 100755 --- a/packages/table-core/src/utils.ts +++ b/packages/table-core/src/utils.ts @@ -1,5 +1,17 @@ import { TableOptionsResolved, TableState, Updater } from './types' +/** + * Safely checks if we are in a non-production (development) environment. + * Guards against `process` not being defined in environments like + * vanilla JS loaded via importmaps without a bundler (e.g. Rails, browser ESM). + */ +export function isDev(): boolean { + return ( + typeof process !== 'undefined' && + process.env?.NODE_ENV !== 'production' + ) +} + export type PartialKeys = Omit & Partial> export type RequiredKeys = Omit & Required> @@ -213,7 +225,7 @@ export function getMemoOptions( ) { return { debug: () => tableOptions?.debugAll ?? tableOptions[debugLevel], - key: process.env.NODE_ENV === 'development' && key, + key: isDev() && key, onChange, } } diff --git a/packages/table-core/src/utils/getFilteredRowModel.ts b/packages/table-core/src/utils/getFilteredRowModel.ts index 3d09f0af2e..4dc346bc92 100644 --- a/packages/table-core/src/utils/getFilteredRowModel.ts +++ b/packages/table-core/src/utils/getFilteredRowModel.ts @@ -1,6 +1,6 @@ import { ResolvedColumnFilter } from '../features/ColumnFiltering' import { Table, RowModel, Row, RowData } from '../types' -import { getMemoOptions, memo } from '../utils' +import { getMemoOptions, isDev, memo } from '../utils' import { filterRows } from './filterRowsUtils' export function getFilteredRowModel(): ( @@ -38,7 +38,7 @@ export function getFilteredRowModel(): ( const filterFn = column.getFilterFn() if (!filterFn) { - if (process.env.NODE_ENV !== 'production') { + if (isDev()) { console.warn( `Could not find a valid 'column.filterFn' for column with the ID: ${column.id}.`, ) From b170475cdef8189cb52ac741d9de9a5b72c327c5 Mon Sep 17 00:00:00 2001 From: Isaac Hunja Date: Wed, 4 Mar 2026 07:10:32 +0300 Subject: [PATCH 2/2] chore: add changeset --- .changeset/fix-process-not-defined.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-process-not-defined.md diff --git a/.changeset/fix-process-not-defined.md b/.changeset/fix-process-not-defined.md new file mode 100644 index 0000000000..b8b4f35fc4 --- /dev/null +++ b/.changeset/fix-process-not-defined.md @@ -0,0 +1,5 @@ +--- +'@tanstack/table-core': patch +--- + +Guard process.env.NODE_ENV checks with typeof to prevent ReferenceError in non-bundled environments