.ai/STACK.md
Primary:
handsontable/src/), all source codehandsontable/src/**/*.scss, handsontable/styles/)Secondary:
wrappers/react-wrapper/src/, wrappers/angular-wrapper/, wrappers/vue3/src/) and hand-authored type definitions (handsontable/types/)handsontable/test/E2ERunner.html, handsontable/src/3rdparty/walkontable/test/SpecRunner.html)Important: The core package (handsontable/) is JavaScript only. Do not create .ts files in handsontable/src/. TypeScript definitions live in handsontable/types/ as .d.ts files.
Environment:
.nvmrc)Package Manager:
package.json packageManager field)corepack enable && corepack prepare [email protected] --activatepnpm-lock.yaml presentpnpm-workspace.yamlCore:
handsontable/src/3rdparty/walkontable/src/)Framework Wrappers:
wrappers/react-wrapper/ (@handsontable/react-wrapper)wrappers/angular-wrapper/ (@handsontable/angular-wrapper)wrappers/vue3/ (@handsontable/vue3)Testing:
handsontable/jest.config.js, *.unit.js files, jsdom environment, jest-jasmine2 runner)*.spec.js files, run via Puppeteer)visual-tests/)@testing-library/react 14 - React wrapper tests@vue/test-utils 2.0.0-rc.16 - Vue 3 wrapper testsjest-preset-angular 14 - Angular wrapper tests (requires NODE_OPTIONS=--openssl-legacy-provider)Build/Dev:
@rspack/core, @rspack/cli) - Core library bundling (handsontable/rspack.config.js + handsontable/.config/). Migrated from Webpack 5; the .config/ folder name is kept for historical reasons.@swc/core, @swc/helpers) - JavaScript transpilation for all builds: Rspack uses builtin:swc-loader, and file-per-file transpilation runs through handsontable/scripts/swc-transpile.mjs (used by build:commonjs, build:es, build:languages.es)babel-jest (see handsontable/babel.config.js); no longer used for production or test bundlesCritical (runtime):
dompurify ^3.1.7 - XSS prevention, HTML sanitization for cell contentnumbro 2.5.0 - Number formatting in cellsmoment 2.30.1 - Date formatting and manipulation@handsontable/pikaday ^1.0.0 - Date picker editor (forked Pikaday)Optional (runtime):
hyperformula ^3.0.0 - Spreadsheet formula engine (optional dependency, integrated via handsontable/src/plugins/formulas/)Angular wrapper runtime:
rxjs ^7.8.1 - Reactive extensions for Angulartslib ^2.3.0 - TypeScript runtime helperszone.js ~0.13.0 - Angular change detectionBuild tooling (key devDependencies):
eslint 7 (core) / 8 (wrappers) - Linting with Airbnb base configeslint-plugin-handsontable - Custom ESLint rules (handsontable/.config/plugin/eslint/)eslint-plugin-compat - Browser API compatibility enforcementstylelint 16 - CSS/SCSS lintingenv-cmd 9 - Injects environment variables from hot.config.js during buildcross-env 7 - Cross-platform environment variable settingrspack.CssExtractRspackPlugin - CSS extraction from Rspack bundles (drop-in replacement for the former mini-css-extract-plugin)rspack.LightningCssMinimizerRspackPlugin - CSS minification via Lightning CSS (replaces the former css-minimizer-webpack-plugin)Environment:
hot.config.js (root): HOT_FILENAME, HOT_VERSION, HOT_PACKAGE_NAME, HOT_BUILD_DATE, HOT_RELEASE_DATEenv-cmd -f ../hot.config.js in all build/test scripts.env files in the repository (air-gapped environment support)Rspack configs (handsontable/.config/): (folder name predates the Webpack→Rspack migration)
base.js - Base configuration (UMD output, library name Handsontable, builtin:swc-loader for JS, empty-loader for numbro/moment locales)development.js / production.js - Dev and production UMD build configswatch.js - Dev watcher config (used by npm run watch)styles-development.js / styles-production.js - CSS build configsthemes-css-development.js / themes-css-production.js - Theme CSS buildsthemes-umd-development.js / themes-umd-production.js - Theme UMD buildslanguages-development.js / languages-production.js - i18n language pack buildswalkontable.js - Walkontable standalone buildtest-e2e.js / test-e2e-esm-cjs.js / test-mobile.js / test-production.js / test-walkontable.js - Test bundle configs (consumed by test:*.dump scripts)loader/forbidden-imports-loader.js - Custom Rspack loader that replaces the former babel-plugin-forbidden-imports (enforces the E2E allow-list in test-e2e.js)plugin/eslint/ - In-repo ESLint plugin (eslint-plugin-handsontable), linked via file:.config/plugin/eslintBabel environments (handsontable/babel.config.js):
commonjs - used by Jest unit tests via babel-jest (@babel/plugin-transform-runtime + @babel/plugin-transform-modules-commonjs). Every other former env (commonjs_dist, es, es_languages, commonjs_e2e) was removed when Babel was swapped out for SWC; the babel.config.js header comment states this explicitly.BABEL_ENV=commonjs / BABEL_ENV=commonjs_e2e still appear in several package.json scripts that invoke rspack. Those assignments are effectively dead — Rspack uses builtin:swc-loader and ignores BABEL_ENV. They are kept to avoid churn in scripts but do not select a Babel environment.SWC pipeline (replaces Babel for everything except Jest):
rspack.config.js + .config/*) - JS transpiled by builtin:swc-loader using targets from browser-targets.jshandsontable/scripts/swc-transpile.mjs - File-per-file transpiler driven by @swc/core; produces the tmp/ output consumed by wrappers. Handles CJS (build:commonjs), ESM (build:es, .mjs output), and i18n language packs with auto-registration (build:languages.es --lang-registration)handsontable/scripts/parallel-build.mjs - Build orchestrator invoked by npm run build; runs the Rspack and SWC tasks above concurrently where the dependency graph allowsLinting:
.eslintrc.js (root) - Monorepo-level ESLint confighandsontable/.eslintrc.js - Core-specific ESLint with custom ruleshandsontable/.config/plugin/eslint/ with rules:
no-native-error-throw - Must use throwWithCause() from src/helpers/errors.jsrestricted-module-imports - No imports from barrel index filesrequire-async-in-it - it() callbacks in spec files must be asyncrequire-await - Specific HOT API calls must be await-edTesting:
handsontable/jest.config.js - Jest config (jsdom environment, jest-jasmine2 runner, *.unit.js pattern)handsontable -> src/, walkontable -> src/3rdparty/walkontable/src/handsontable/test/__mocks__/styleMock.js| Output | Path | Format |
|---|---|---|
| UMD bundles | handsontable/dist/handsontable.js, handsontable/dist/handsontable.full.js | UMD |
| Minified bundles | handsontable/dist/handsontable.min.js, handsontable/dist/handsontable.full.min.js | UMD (minified) |
| CommonJS modules | handsontable/tmp/*.js | CJS |
| ES modules | handsontable/tmp/*.mjs | ESM |
| Compiled CSS | handsontable/styles/ | CSS |
| Language packs | handsontable/dist/languages/, handsontable/languages/ | UMD + ESM |
| Theme bundles | handsontable/dist/themes/ | UMD + CSS |
Two build variants:
handsontable.js - Base build, external dependencies not bundledhandsontable.full.js - Includes HyperFormula bundled inWrappers consume tmp/ output via pnpm workspace linking ("handsontable": "workspace:^" override in root package.json).
ht-theme-main - Default modern themeht-theme-classic - Legacy Handsontable themeht-theme-horizon - Alternative design theme-no-icons variantDevelopment:
.nvmrc)Production (browser targets):
eslint-plugin-compatCDN distribution:
dist/handsontable.full.min.jsdist/handsontable.full.min.jsPlatform: GitHub Actions (.github/workflows/)
Key workflows:
test.yml - Main test pipeline (unit, E2E, Walkontable, wrapper tests)build-all.yml - Full build verificationcode-quality.yml - Linting and code quality checkslinter.yml - ESLint checkspublish.yml - Package publishing pipeline to npmdocs-staging.yml / docs-production.yml - Documentation deployment (Netlify)docs-visual-tests.yml - Visual regression testing for docschangelog.yml - Changelog verificationaudit.yml - Security auditpkg-pr-new.yml - PR package preview