Skip to content

Releases: neomjs/neo

v10.3.2 Hotfix Release

03 Aug 00:49

Choose a tag to compare

This hotfix addresses an issue where changing the tabBarPosition config for tab.Container did not correctly update the UI. Additionally, a broader refactoring was applied to improve component lifecycle management.

Fixes

  • tab.Container: Resolved an issue where switching tabBarPosition did not correctly update the UI. The tabBar component's dock config now properly reflects the new position, ensuring correct rendering. This fix involved adding tabBarPosition to the config object, and implementing afterSetTabBarPosition and beforeSetTabBarPosition methods to manage UI updates and component creation.
  • Component Lifecycle: Replaced this.rendered with this.vnodeInitialized across various components (Circle, Gallery, Helix, Dialog, Text field, GridBody, Flexbox, List, TableBody). This change refines the component lifecycle management, ensuring that UI updates and other operations are performed when the virtual DOM node is properly initialized.
  • Font Awesome v7 Adjusted 3 spots inside our theming, where v6 was still in use.
  • Earthquakes Tutorial Fixed a malformed code closing tag, added a warning that the labs are currently not working.

Neo.mjs v10.3.1: Build Process Reliability

02 Aug 16:44

Choose a tag to compare

This is a patch release focused on improving the stability and reliability of the core build process.

Key Fix: Build Process Dependency Order

The Problem

The main buildAll.mjs script could fail on a clean repository checkout. The build steps that process HTML templates (e.g., buildESModules) have a dependency on the dist/parse5.mjs bundle. However, the script did not guarantee that this bundle was created before it was needed, leading to a potential crash.

The Solution

We have updated buildAll.mjs to explicitly run the bundleParse5.mjs script as one of its first actions, immediately after the optional npm install.

The Impact

This change ensures the parse5 dependency is always available for subsequent build tasks. It makes the build process more robust and predictable, particularly for developers setting up the project for the first time.

Neo.mjs v10.3.0: Introducing HTML Templates

02 Aug 14:37

Choose a tag to compare

This release marks a major milestone in the evolution of Neo.mjs, introducing an intuitive, HTML-like syntax for building component VDOMs. This has been a significant undertaking, designed to lower the barrier to entry for new developers while holding true to the framework's core principles of performance and adherence to web standards.

This feature is the culmination of the work tracked in our public epic: #7130.

Key Feature: HTML Templates

You can now define a component's VDOM using familiar HTML-like syntax, powered by standard JavaScript Tagged Template Literals. This provides an alternative to the traditional JSON-based VDOM structure, making UI development more approachable.

import { html } from '../../src/functional/util/html.mjs';
import Button   from '../../src/button/Base.mjs';

// Inside a component's render() method:
return html`
    <div class="my-container">
        <p>${this.myText}</p>
        <${Button} text="Click Me" handler="${this.onButtonClick}" />
    </div>
`;

The Philosophy: Why Not JSX?

This new feature is built on a core Neo.mjs principle: a commitment to a zero-builds development experience.

  • Standard JavaScript: Unlike JSX, which requires a compiler, html templates are a standard JavaScript feature. Your code runs directly in the browser without a mandatory build step, providing an instant feedback loop.
  • No Hidden Magic: Logic is handled with plain JavaScript (if/else, .map()), not special template directives. What you write is what you get.

The Dual-Mode Architecture

To achieve both developer convenience and production performance, the framework uses a sophisticated dual-mode approach:

  1. Development Mode: Templates are parsed live in the browser using parse5. This parser is only loaded if templates are actually used, ensuring zero overhead for applications that stick to the JSON VDOM.
  2. Production Mode: For dist/esm, dist/dev, and dist/prod builds, a powerful build-time AST transformation converts templates directly into optimized VDOM objects. This eliminates the parse5 dependency from production builds entirely, resulting in zero runtime parsing overhead and maximum performance. The enableHtmlTemplates flag is also automatically set to false in production environments, ensuring that the runtime parser is never accidentally used.

As a developer convenience, if you name your template-generating method render(), the build process will automatically rename it to createVdom() for you, aligning with the framework's lifecycle methods while providing a familiar entry point.

Foundational Enhancements

The introduction of HTML templates was made possible by a series of significant enhancements to the framework's core and build scripts:

  • Component Lifecycle Integration (src/functional/component/Base.mjs): The functional component base class was updated to recognize and process the new HtmlTemplate return type from render(), seamlessly integrating the parsing process into the component lifecycle.
  • Runtime Parsing (src/functional/util/HtmlTemplateProcessor.mjs): A new runtime processor that intelligently flattens nested templates, handles dynamic values, and uses parse5 to convert the HTML string into a VDOM structure.
  • Build-Time AST Processing (buildScripts/util/astTemplateProcessor.mjs): A new, robust build-time processor that uses acorn to parse source code into an Abstract Syntax Tree (AST), replaces template literals with their VDOM object counterparts, and generates new, optimized code with astring.
  • Webpack Integration (buildScripts/webpack/loader/template-loader.mjs): A new Webpack loader that hooks the AST processor into the dist/dev and dist/prod build pipelines, applied only to the app worker where components live.

New Documentation

To support this major new feature, we have added two comprehensive guides:

  • Using HTML Templates: A guide focused on the syntax, features, and best practices for using the new template system.
  • Under the Hood: HTML Templates: A deep dive into the philosophy and the dual-mode architecture, explaining how templates work in both development and production environments.

All changes combined into 1 commit: 0841e7e

We are incredibly excited about this release and believe it makes Neo.mjs more powerful and accessible than ever. Please explore the new feature, read the documentation, and share your feedback!

Try it out by yourself:

https://neomjs.com/examples/functional/nestedTemplateComponent/

Screenshot 2025-08-02 at 17 01 25

https://neomjs.com/dist/esm/examples/functional/nestedTemplateComponent/

Screenshot 2025-08-02 at 17 00 12

https://neomjs.com/dist/development/examples/functional/nestedTemplateComponent/

Screenshot 2025-08-02 at 17 06 24

housekeeping

30 Jul 12:51

Choose a tag to compare

Neo.mjs v10.2.1 Release Notes

Introduction

Version 10.2.1 is a patch release that addresses a critical layout regression discovered in lazy-loaded tabs and introduces a significant enhancement to the button.Base component, improving both its flexibility and security.

Key Changes

Enhancements

  • Button Text as VDOM: The text config for Neo.button.Base has been enhanced to accept a VDOM cn (children) array in addition to a string. This allows for rich, complex button content to be defined in a structured, secure, and performant way, avoiding the need for innerHTML and enabling granular delta updates for the button's content. See ticket #7135.

Bug Fixes

  • Lazy-Loaded Tab Layout Regression: Fixed a critical regression where the layout config of a lazy-loaded tab (e.g., a Panel) was being mutated on the class prototype, causing subsequent lazy-loaded tabs to fail with a missing ntype error. The fix, implemented in container.Base, ensures that each container instance gets a unique, deep-cloned copy of its layout config, preventing prototype pollution. See ticket #7134.

  • Covid App Navigation Rendering: Fixed a rendering issue in the GalleryContainer and HelixContainer of the Covid apps where the navigation instructions were not being displayed correctly. The text config was changed to html on the BoxLabel components to ensure the HTML content is rendered as expected. See issue #7133.

Stabilization, DX Improvements & Template PoC

30 Jul 11:27

Choose a tag to compare

Neo.mjs v10.2.0 Release Notes

Introduction

Following the major architectural changes in v10.0.0 with the new core and state provider, v10.2.0 is focused on stabilization, refinement, and developer experience. This release adjusts our demonstration applications to the new architecture, fixes key regressions in the single and multi-window Covid apps, and polishes the Big Data Grid example.

A key highlight is the introduction of an early-stage proof-of-concept for string-based VDOM templates, offering a more intuitive way to build functional components.

Key Changes

New Features & Enhancements

  • PoC: String-Based VDOM Templates: An initial proof-of-concept for using tagged template literals to define VDOM in functional components has been introduced. This feature can be enabled via the enableHtmlTemplates config and provides a more familiar, HTML-like syntax for building component views. See commit a3bbca76653ffc822a102e9bde76dea3d8e7bb8b.

  • Synchronous fireChangeEvent: The fireChangeEvent method in ComboBox and other form fields is now fully synchronous. This resolves critical timing issues in applications like the Covid tracker, where dependent logic needs to execute immediately after a value changes to ensure state consistency. See issue #7129.

  • Optimized ComboBox Selection: The afterSetValue logic for single-select ComboBox fields has been optimized to prevent unnecessary processing when the selection has not changed, improving performance. See issue #7125.

  • Refined StateProvider Logic: The StateProvider change notification logic has been improved to be more precise, preventing unnecessary component updates and ensuring a more efficient data flow. See issue #7124.

Bug Fixes

  • Form Field Value Sequencing: Addressed a bug related to the sequencing of afterSetValue calls in form fields, ensuring that values are processed in the correct order. See issue #7127.

  • Big Data Grid Example: Fixed an issue in the Big Data Grid example where dropdowns in the controls container were not showing their initial values correctly. See issue #7126.

  • Covid App Regression: Fixed a regression bug in the Covid app that caused an infinite selection loop when choosing a country from the header dropdown. See issue #7123.

  • SharedCovid App Regression: Resolved a regression bug in the SharedCovid app where clicking on a table row would throw an error. See issue #7122.

  • State Provider Feedback Loop: Added a new test case to prevent feedback loops within the StateProvider, enhancing its reliability. See issue #7128.

All changes combined into 1 commit: 95f9e75

Grid Column Header Drag&Drop Hotfix

27 Jul 18:02

Choose a tag to compare

Neo.mjs v10.1.1 Release Notes

This is a patch release that addresses a critical regression bug affecting drag-and-drop operations in grids.

Bug Fixes

Grid Column Drag & Drop

  • Fixed a bug in Neo.collection.Base where the move() method would fail to correctly swap adjacent items. This was caused by an unsafe, nested splice() operation that could lead to unpredictable behavior.
  • The direct impact of this bug was the failure of drag-and-drop for grid column reordering, which is a significant regression.
  • The move() method has been refactored to use a safer, two-step approach, ensuring the stability of all collection-based move operations.
  • See: #7118

This fix restores the expected drag-and-drop functionality for grid columns.

housekeeping

27 Jul 11:10

Choose a tag to compare

Neo.mjs v10.1.0 Release Notes

This release includes important fixes and minor improvements, primarily focusing on VDOM optimization, collection performance, and selection model improvements.

Key Updates:

  • VDOM Optimization & neo-ignore Refinement (Addresses #7114):
    The internal handling of the neo-ignore flag has been significantly improved. Previously, neo-ignore could interfere with the VDOM's structural integrity, potentially leading to rendering anomalies, especially in complex layouts like grids, where elements might overlap. Now, a dedicated neoIgnore: true flag is added to VDOM nodes, preserving the original componentId and id. This ensures the VDOM engine can correctly identify and skip sub-trees during diffing, leading to more robust and efficient asymmetric VDOM updates and resolving visual rendering issues such as those observed in grid components.

  • Collection Performance Enhancements (Addresses #7115):
    Several methods within src/collection/Base.mjs (e.g., clear, findBy, pop, remove) have been optimized by replacing this.getCount() method calls with direct access to this.count. This change streamlines collection operations, leading to improved performance.

  • Enhanced Selection Model (Addresses #7116):
    The src/selection/Model.mjs has been updated to provide more comprehensive data during selection changes. A new getController() method has been added, and the selectionChange event now includes the records array, offering richer context for selection handling and better integration with view controllers.

  • Minor Fixes & Improvements (Addresses #7117):
    This release also includes minor cleanups and documentation improvements, such as an updated JSDoc comment in src/grid/Body.mjs and the removal of a debug console.log statement in src/main/DeltaUpdates.mjs.

v10 polishing

26 Jul 20:02

Choose a tag to compare

Neo.mjs v10.0.2 Release Notes

This release includes several enhancements and fixes since v10.0.1.

Key Updates:

  • README.md & Comparison Enhancements: Significant updates to the README.md, including a new section "🚀 Inside v10: A New Era of Frontend Architecture" with links to a five-part blog series. The architectural comparison table "🔍 Architectural Deep Dive: Neo.mjs vs. Main-Thread Frameworks" has been expanded, and detailed comparison documents (NeoVsAngular.md, NeoVsReact.md, NeoVsVue.md) have been updated to provide enhanced insights.
  • Data Model Enhancements: Default values for records now optionally support functions, enabled by changes in data.RecordFactory.
  • DOM Rendering: DomApiRenderer has been improved for creating void attributes, enhancing rendering accuracy.
  • Core Component Fix: Re-added the lost parentId default value to component.Abstract, which resolves an issue with the tooltip singleton.
  • Dark Theme: Improved the styling for ghost buttons
  • Tree List Polished drag&drop support for the edge case where stores are not using id as the keyProperty.

Added 2 new v10 series blog posts to the neo website app

24 Jul 08:23

Choose a tag to compare

Neo.mjs v10: The Reactive Revolution

24 Jul 06:03

Choose a tag to compare

This release brings significant enhancements and refactorings, improving performance, reactivity, and the overall developer experience.

Core Framework Improvements

  • Reactive Core Refactoring (core.Observable):
    • Architectural refactoring of core.Observable to a fully reactive mixin (#7090).
    • Modernized core.Observable: Refactored core.Observable to align with the reactive config system. This involved converting the listeners property to a reactive listeners_ config, eliminating manual initialization, and establishing true encapsulation using a module-scoped Symbol (eventMapSymbol) for internal event registry management. A bug in removeListener related to incorrect state access was also fixed. (#7090)
    • Listeners are now managed as a reactive config within core.Observable (#7089).
  • Effect Management System:
    • Foundational Refactoring of Effect Management: The core reactivity system has been refactored and unified under a single Neo.core.EffectManager (#7085). This introduces a clear distinction between:
      • Execution Batching (pause() / resume()): Replaced the old isPaused flag with a numeric pauseCounter for robust, nested batching of UI updates. Effects are queued and executed only when the counter is zero.
      • Dependency Tracking Suppression (pauseTracking() / resumeTracking()): A new mechanism (isTrackingPaused flag) to temporarily stop active effects from collecting new dependencies, solving self-dependency issues.
    • The EffectBatchManager singleton has been completely removed, and its functionality absorbed by the enhanced EffectManager. This results in a more predictable, robust, and resilient reactive system.
  • State Management:
    • State Provider Refactoring & Deep Merging:
      • Refactored state.Provider's internalSetData() method to support intuitive deep-merging of nested objects, allowing dynamic creation of new, fully reactive data structures at runtime. This resolves inconsistent behavior and aligns with expected merge operations. (#7099)
      • Enhanced Reactivity & Atomic Updates: state.Provider now features "Reactivity Bubbling," where changes to leaf properties recursively update parent objects, correctly triggering effects on intermediate data objects. Public setData() and setDataAtSameLevel() methods are now wrapped with Neo.batch() (leveraging the new EffectManager's batching capabilities) to ensure all reactive updates are collected, de-duplicated, and executed atomically, preventing race conditions and improving performance. A new test suite (ProviderNestedDataConfigs.mjs) validates this functionality.
      • Moved all state provider related logic (configs like bind, modelData, stateProvider_, data_, parentComponent_, and methods like getStateProvider(), getState(), setState(), beforeGetData(), getConfigInstanceByNtype(), along with lifecycle logic and two-way binding logic) from src/component/Base.mjs to src/component/Abstract.mjs. This makes state providers available to both classic class-based components and modern functional components. (#7100)
  • Component Base Classes:
    • Common Abstract Base Class: Introduced Neo.component.Abstract as a new common base class for both Neo.component.Base (classic) and Neo.functional.component.Base (functional) components. This refactoring centralizes shared logic (e.g., set(), destroy(), mountedPromise, core configs, DomEvents, Observable, VdomLifecycle mixins), improving code reusability, enhancing consistency, and simplifying maintenance by removing duplicated code. (#7089)
    • Removed redundant createBindings() calls from onConstructed (#7101).

Functional Components

  • VDOM Reconciliation: Enhanced Functional Component VDOM Reconciliation (#7086).
  • Lifecycle Hook: Introduced a new beforeUpdate() lifecycle method to Neo.functional.component.Base (#7084). This hook executes after all state changes from a reactive Effect have been processed and just before updateVdom(). It provides a predictable entry point for pre-render logic and allows conditionally canceling a VDOM update by returning false.
  • Functional Button Component: Introduced a new Neo.functional.button.Base component (#7087). This component serves as a key UI element built using the functional component paradigm, demonstrating integration with the reactive VDOM system and leveraging automatic VDOM node ID generation for efficient diffing. A dedicated test suite and demo application were created.
  • functional.button.Base: beforeSetBadgePosition(), beforeSetIconPosition() now use constructor access for future class extensions.

VDOM & Rendering

  • util.vdom.TreeBuilder: Improvements to buildTree(): Refactored getVdomTree and getVnodeTree into a single, DRY method (#7098).
  • util.VDom: syncVdomIds() enhanced for future-proofing and improved filtering.
  • manager.VDomUpdate: Significantly enhanced JSDoc comments and method order/cleanup.

Other Enhancements & Fixes

  • Dependencies: Updated FontAwesome to v7.
  • Examples Website: Fixed flakiness on Safari (#7102).
  • Tests: All 770 unit tests now pass successfully, including a significant number of new tests added since beta.6.
  • form.field.Text: onInputValueChange() intent made clearer.
  • Portal.view.ViewportController: Cube-layout timing adjustments.
  • core.EffectManager: Optimized Neo.batch usage.
  • Removed obsolete onNeoConfigChange() calls from tests.
  • Updated test/siesta/tests/vdom/layout/Cube.mjs to match current VdomHelper.create() signature.

Documentation Updates

  • The learn/guides/datahandling/StateProviders.md guide has been updated to accurately describe the new deep-merge behavior of state providers.
  • Code examples in the learn/blog/v10-deep-dive-state-provider.md blog post have been updated to demonstrate the intuitive API usage.

All changes combined into 1 commit: c84a2cd