.ai/ARCHITECTURE.md
Overall: Microkernel with plugin system and layered rendering engine
Key Characteristics:
Core) that exposes the entire public API as instance methodsBasePlugin and hook into the core via an event/hook busTableViewIndexMapperbase.js (tree-shakeable, minimal) and index.js (full, registers everything)Public API (Core):
handsontable/src/core.js (~5656 lines)Core constructor function with all public API methods defined on thisView Layer (TableView + Walkontable):
handsontable/src/tableView.js (TableView), handsontable/src/3rdparty/walkontable/src/ (Walkontable)this.view)Walkontable Rendering Engine:
handsontable/src/3rdparty/walkontable/src/renderer/), overlay managers (overlay/), viewport calculators (calculator/), cell/range coordinate primitives (cell/), scroll logic (scroll.js), selection rendering (selection/)facade/core.js)core/_base.js, core/core.js, core/clone.js - Walkontable core and clone instancestable/master.js - Master table, table/top.js, table/bottom.js, etc. - Overlay tablesoverlay/ - 6 overlay types (top, bottom, inlineStart, topInlineStartCorner, bottomInlineStartCorner, plus base)calculator/ - Viewport row/column calculatorsrenderer/ - Low-level cell/row/colgroup/header renderersscroll.js - Scroll position managementviewport.js - Viewport stateData Layer (DataMap + DataSource):
handsontable/src/dataMap/DataMap (row/column data access), DataSource (raw data wrapper), replaceData (data replacement logic), sourceDataValidator (validation)datamap and dataSource internal variables)Metadata Layer (MetaManager):
handsontable/src/dataMap/metaManager/metaLayers/globalMeta.js, tableMeta.js, columnMeta.js, cellMeta.js), meta schema (metaSchema.js), modifier mods (mods/)hot.getCellMeta(), hot.getSettings())Index Translation Layer:
handsontable/src/translations/IndexMapper (main class), maps/ (HidingMap, TrimmingMap, IndexesSequence, PhysicalIndexToValueMap, LinkedPhysicalIndexToValueMap), mapCollections/ (AggregatedCollection, MapCollection), changesObservable/hot.rowIndexMapper, hot.columnIndexMapper), plugins that modify row/column visibilitySelection Layer:
handsontable/src/selection/Selection class (selection.js), SelectionRange (range.js), Highlight system (highlight/), transformation modules (transformation/), mouse event handler (mouseEventHandler.js), utilities (utils.js)selection internal variable), EditorManager, pluginsPlugin System:
BasePluginhandsontable/src/plugins/index.js barrel exportthis.hot), Hooks system, IndexMapperautoColumnSize, autoRowSize, columnSorting, dataProvider, filters, formulas, hiddenColumns, hiddenRows, mergeCells, nestedHeaders, nestedRows, notification, undoRedo, contextMenu, copyPaste, comments, stretchColumnsdataProvider configuration, failed fetchRows or onRowsCreate / onRowsUpdate / onRowsRemove (including refetch after a mutation) can show a built-in error toast when the Notification plugin is enabled (notification: true or a config object). Fetch failures add a Refetch action that calls fetchData() again (toast uses duration: 0 until dismissed or Refetch). The Dialog plugin is not used for those errors; Dialog remains for blocking overlays (for example Loading plugin, ExportFile binary export progress, and custom modal content).Hooks System:
handsontable/src/core/hooks/Hooks class (singleton), HooksBucket, hook constants (constants.js with REGISTERED_HOOKS, REMOVED_HOOKS, DEPRECATED_HOOKS)this.addHook() (auto-cleaned on disable) vs this.hot.addHook() (manual cleanup).Editor System:
handsontable/src/editors/, handsontable/src/editorManager.jsEditorManager (orchestrates editor lifecycle), BaseEditor (abstract base), 15+ editor typesRenderer System:
handsontable/src/renderers/baseRenderer, textRenderer, numericRenderer, checkboxRenderer, htmlRenderer, etc.Validator System:
handsontable/src/validators/autocompleteValidator, dateValidator, numericValidator, timeValidator, etc.Cell Type System:
handsontable/src/cellTypes/textType, numericType, checkboxType, dateType, dropdownType, etc.Shortcut System:
handsontable/src/shortcuts/ (manager, recorder, context), handsontable/src/shortcutContexts/ (predefined contexts)Focus Management:
handsontable/src/focusManager/FocusGridManager, scope manager, predefined scopesTheme System:
handsontable/src/themes/ (engine, registry, static themes), handsontable/src/styles/ (SCSS sources)engine/), theme registry (registry.js), static theme definitions (static/), theme class (theme/)stylesHandler and themeManager)Initialization Flow:
new Handsontable(element, settings) which calls base.js -> Core(element, settings, rootInstanceSymbol)MetaManager, IndexMapper (row + column), DataSource, Selection, EditorManager, ShortcutManager, FocusGridManager, StylesHandler, ThemeManagerTableView which creates Walkontable instanceconstructor(hotInstance))afterPluginsInitialized hook fires, each plugin's isEnabled() is checked, and enablePlugin() called if trueinit() triggers initial data load and renderRender Flow:
this.view.render() (or plugin triggers render via hooks)TableView delegates to Walkontable's draw() methodViewportRowsCalculator and ViewportColumnsCalculatorSelection rendering systemData Change Flow:
setDataAtCell(row, col, value)beforeChange hook (plugins can modify/cancel)DataMap.set() updates the source dataafterChange hookvalidateCells() runs validatorsrender() is called to update the DOMSettings Update Flow:
updateSettings(newSettings)beforeUpdateSettings hookMetaManager updates cascading meta layersonUpdateSettings() is called; if the changed key is in SETTING_KEYS, updatePlugin() runsafterUpdateSettings hookCoordinate Translation Flow:
selectCell(2, 3))rowIndexMapper.getRenderableFromVisualIndex() to get renderable index for DOM operationsrowIndexMapper.getPhysicalFromVisualIndex() to get physical index for data operationshiddenRows/hiddenColumns register HidingMap instances that affect visual-to-renderable translationtrimRows register TrimmingMap instances that affect physical-to-visual translationState Management:
DataSource (reference to user's array/object)MetaManagerIndexMapper with registered HidingMap/TrimmingMap instances per pluginSelection class with SelectionRange tracking visual coordinatesCellCoords / CellRange:
handsontable/src/3rdparty/walkontable/src/cell/coords.js, handsontable/src/3rdparty/walkontable/src/cell/range.jsisEqual(), includes(), getTopStartCorner(), etc.IndexMapper:
handsontable/src/translations/indexMapper.jsBasePlugin:
handsontable/src/plugins/base/base.jsisEnabled() -> enablePlugin() -> updatePlugin() -> disablePlugin() -> destroy()Hooks (Event Bus):
handsontable/src/core/hooks/index.jsorderIndex.MetaManager (Cascading Config):
handsontable/src/dataMap/metaManager/index.jsRegistry Pattern:
handsontable/src/plugins/registry.js, handsontable/src/editors/registry.js, handsontable/src/renderers/registry.js, handsontable/src/validators/registry.js, handsontable/src/cellTypes/registry.js, handsontable/src/themes/registry.jsregister() / get() / getNames() methods. The registry.js module in src/ aggregates all registerAll*() calls.Full Entry (index.js):
handsontable/src/index.jsregisterAllModules() which registers all editors, renderers, validators, cell types, and pluginsBase Entry (base.js):
handsontable/src/base.jsTextCellType and baseRenderer (minimal defaults)Core Constructor:
handsontable/src/core.js (exported as Core)Handsontable() wrapper in base.jsStrategy: Custom error helper with cause tracking
Patterns:
throwWithCause(message, cause) from handsontable/src/helpers/errors.js instead of throw new Error(). Enforced by ESLint rule handsontable/no-native-error-throw.before* hooks can return false to cancel operationsvalidator(value, callback) where callback(true/false) signals validityhandsontable/src/helpers/console.js (never raw console)Logging: Via handsontable/src/helpers/console.js helpers (warn, log, error). Raw console is banned by ESLint.
Validation: Cell validators in handsontable/src/validators/. Source data validators in handsontable/src/dataMap/sourceDataValidator.js. Triggered on data changes and via validateCells() API.
Authentication: Not applicable (frontend-only library, no auth).
Internationalization: handsontable/src/i18n/ with language dictionaries and a registry. RTL layout support via layoutDirection setting and isRtl()/isLtr() Core methods.
Accessibility: ARIA attributes applied via helpers in handsontable/src/helpers/a11y.js. Announcer utility in handsontable/src/utils/a11yAnnouncer.js. Focus management in handsontable/src/focusManager/. Two navigation modes: spreadsheet mode and data grid mode.
DOM Abstraction: All DOM access goes through handsontable/src/helpers/dom/element.js and handsontable/src/helpers/dom/event.js. Global window/document are banned; use this.hot.rootWindow/this.hot.rootDocument.
Event Management: handsontable/src/eventManager.js provides centralized DOM event listener management with automatic cleanup.