Skip to content
CAI
Software that uses CAICheck a score

marko-js/marko

50.0

Adequate · 1 October 2026

56.4k

lines of production code

TypeScript

with JavaScript

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the Marko templating framework, providing a compiler and runtime for rendering UI components on both the server and client. It supports two distinct component APIs—a legacy Class-based model and a modern Tags-based model—along with a unified interop layer to facilitate migration between them. The architecture includes a Babel-based compiler for transforming templates and separate runtime packages for handling virtual DOM diffing, server-side HTML serialization, and client-side event delegation.

How it got here

2014–2024 — Marko 6 runtime and compiler rewrite

63 changes.

This period focused on the comprehensive rewrite of the Marko templating engine, introducing a new Tags API alongside the legacy Class API. The work involved rebuilding the compiler with an internal Babel copy, modularizing the runtime into distinct DOM and HTML packages, and establishing a robust interoperability layer between the two systems. Extensive test coverage and tooling overhauls supported this major architectural shift.

2025–2026 — Runtime tags type safety and build optimization

10 changes.

This period focused on enhancing the runtime-tags package by adding comprehensive TypeScript type stubs and optimizing the build pipeline with rolldown for better tree-shaking. The work also included improving the compiler's interop translator, preserving source fidelity in generated output, and expanding test coverage for both the compiler and server components.

Features

Add TypeScript type stubs for runtime tags

Added \.d.marko\ type definition files for core runtime tags including \await\, \const\, \debug\, \define\, \effect\, \html-comment\, \html-script\, \html-style\, \id\, \let\, \lifecycle\, \log\, \script\, \show\, and \try\. These stubs provide explicit TypeScript interfaces for tag inputs and return types, enabling better type checking and autocomplete for users of these tags in Marko templates.

packages/runtime-tags/tags · high confidence

Compiler error reporting and agent integration utilities

This change introduces a suite of utility modules in the compiler to enhance error diagnostics and coding agent support. It adds a custom CompileError class that generates structured code frames with windowing for long lines, ensuring readable output in both Node.js and browser environments. It also implements an agent-fix-guide mechanism that automatically appends a link to a translator's cheat sheet to compile errors when detected coding agents (like Cursor or Claude Code) are present, helping them resolve issues more effectively. Additionally, it provides utilities for merging multiple compilation errors into a single aggregate error, hashing source content, stripping ANSI codes from output, and safely loading external translators with caching.

packages/compiler/src/util · high confidence

Compiler now includes built-in HTML, SVG, and MathML taglib definitions

The compiler source now ships with native taglib definitions for standard HTML, SVG, and MathML elements (marko-html, marko-svg, marko-math). This means these tags are recognized and compiled by default without requiring external configuration or separate packages, providing immediate support for these web standards out of the box.

packages/compiler/src/taglib · high confidence

Compiler package structure and API documentation

The \@marko/compiler\ package now includes a comprehensive README and an AGENTS.md guide that document the public API, configuration options, and translator contract. The package exports type definitions for compile results, taglib definitions, and babel-utils, ensuring that tooling and bundler integrations have accurate TypeScript support for the compiler's interface.

packages/compiler · high confidence

Introduce Class API translator for Marko templates

The \packages/runtime-class/src/translator\ directory now contains the complete implementation of the Class API translator, which compiles Marko templates into JavaScript using the Class API. This includes dedicated translators for HTML and VDOM output modes, handling of native and custom tags, dynamic tags, attribute directives (such as \class\, \style\, and \no-update\), and interop logic for the Tags API. Users benefit from a new compilation path that supports class-based component definitions and improved handling of template features like conditional comments, CDATA, and scriptlets.

packages/runtime-class/src/translator · high confidence

Introduce debug and production accessor constant modules

The runtime-tags package now exposes dedicated constant modules for accessor prefixes, property names, and resume symbols, each provided in both debug (human-readable strings) and production (shortened single-character or compact codes) variants. This change introduces new files such as \accessor-prefix.debug.ts\, \accessor-prop.debug.ts\, \resume-symbol.ts\, and \walk-code.ts\ alongside their production counterparts, enabling the runtime to use readable identifiers during development while minimizing bundle size and overhead in production builds.

packages/runtime-tags/src/common/constants · high confidence

Introduce new runtime-class vdom implementation

The runtime-class package now includes a new virtual DOM (vdom) implementation located in src/runtime/vdom. This adds core virtual node types (VElement, VText, VComment, VComponent, VFragment, VDocumentFragment), an AsyncVDOMBuilder for rendering, and a morphdom-based diffing engine to update the DOM. It also provides DOM insertion helpers (appendTo, replace, etc.) and a hot-reload mechanism for class components that detects lifecycle changes and triggers re-renders.

packages/runtime-class/src/runtime/vdom · high confidence

Introduces new HTML runtime implementation for Marko templates

The HTML rendering engine in the runtime-class package has been replaced with a new implementation. This update introduces dedicated modules for managing output streams, including AsyncStream for handling asynchronous rendering, BufferedWriter to optimize write operations by batching chunks, and StringWriter for managing string-based content and script injection. The change also adds support for hot-reloading templates and establishes a global Marko namespace, fundamentally altering how template output is generated and streamed to the client.

packages/runtime-class/src/runtime/html · high confidence

Introduction of new runtime class-based component architecture

The runtime component system has been refactored to support a new class-based component model alongside the existing legacy widget system. This change introduces new core runtime modules including \Component.js\ and \ComponentDef.js\ for managing component instances and metadata, \ServerComponent.js\ for server-side rendering lifecycles, and \State.js\ for tracking state changes. It also adds \ComponentsContext.js\ and \GlobalComponentsContext.js\ to manage rendering contexts and component lookups, while \defineComponent.js\ provides the factory for creating new class-based components. The legacy widget definitions (\defineWidget-legacy.js\, \defineRenderer-legacy.js\) and their associated dependency patching logic remain in place to ensure backward compatibility.

packages/runtime-class/src/runtime/components · high confidence

Marko 6 core tag translators moved to runtime-tags

The core tag translators (including \<const\>, \<let\>, \<for\>, \<if\>, \<await\>, \<define\>, \<id\>, \<script\>, and others) have been relocated from the compiler into the new \packages/runtime-tags\ package. This change introduces a dedicated runtime tag library for Marko 6, providing the implementation for core language features such as control flow, state management, and async handling. The diff also includes the new \\<attrs\>\ tag, which is deprecated in favor of destructuring \input\ via the \\<const\>\ tag, and the \\<class\>\ tag, which now throws a compile-time error to guide users toward \\<let\>\ and \\<const\>\ for state.

packages/runtime-tags/src/translator/core · high confidence

New DOM runtime implementation for Marko Tags API

The \packages/runtime-tags/src/dom\ directory has been replaced with a new, standalone DOM runtime implementation for the Marko Tags API. This change introduces a complete rewrite of the client-side rendering engine, including new modules for handling abort signals (\abort-signal.ts\), event delegation (\event.ts\), and a priority-queue-based render scheduler (\queue.ts\). It adds support for controllable native form elements (\controllable.feat.ts\), dynamic tag variables (\dynamic-tag-var.feat.ts\), and lazy-loaded templates (\load.ts\). The new runtime also implements a compatibility layer (\compat.ts\) to bridge the Tags API with the legacy Class runtime, ensuring smooth interoperability during migration.

packages/runtime-tags/src/dom · high confidence

New HTML runtime implementation for the Tags API

The HTML compilation path for the Tags API has been replaced with a new runtime implementation located in \packages/runtime-tags/src/html\. This new runtime introduces dedicated modules for handling assets (including lazy loading with visible, idle, media, and event triggers), attribute processing (such as controlled \\<select\>\ and \\<textarea\>\ values), and template rendering. It also includes a compatibility layer to bridge the Tags API with the existing Class API, ensuring that server-side rendering and client-side hydration work correctly across both systems.

packages/runtime-tags/src/html · high confidence

New core tags and runtime support for async rendering and component initialization

This change introduces the core implementation files for several new runtime tags in the \core-tags\ package. It adds the \\<await\>\ tag logic (including \AsyncValue\, client-side reordering via \client-reorder\, and timeout handling), the \\<init-components\>\ tag for managing UI component initialization in both sync and async contexts, the \\<preferred-script-location\>\ tag for controlling script placement, and the \\_\_flush\_here\_and\after\\_\ tag for controlling render flushing. It also includes type definitions for the \\<script\>\ tag and a new ESLint configuration for the package.

packages/runtime-class/src/core-tags · high confidence

New program-level translator visitors for DOM and HTML output

The translator now uses dedicated \dom.ts\ and \html.ts\ visitors within the program scope to handle template compilation. For DOM output, the new logic manages content registration, closure handling, and setup function generation, while also optimizing text-only conditionals and hoisting static placeholder text. For HTML output, it handles element resolution, hoisting, and global state management. These changes replace the previous program-level handling, improving how the compiler processes template structure and runtime registrations.

packages/runtime-tags/src/translator/visitors/program · high confidence

New runtime-tags common module with validation and iteration helpers

The \packages/runtime-tags/src/common\ directory now contains a new set of shared runtime utilities. This includes strict validation logic in \errors.ts\ that throws descriptive errors for invalid attribute values (such as functions or unrenderable objects), invalid \\<for\>\ tag keys, and incorrect attribute names, along with debug warnings for silently dropped values like \NaN\. The module also introduces iteration helpers (\for.ts\) supporting \forIn\, \forOf\, \forTo\, and a new \forUntil\ range loop, as well as attribute handling utilities (\attr-tag.ts\) and type definitions for scopes and renderers.

packages/runtime-tags/src/common · high confidence

New taglib lookup implementation in compiler source

The compiler now includes a new \TaglibLookup\ class within \packages/compiler/src/taglib/lookup/index.js\ that handles the merging and fast lookup of custom tags and attributes. This implementation consolidates taglib data into a single merged structure, supporting nested tag registration, attribute group resolution, and pattern attribute handling, effectively moving the taglib API logic into the compiler source code.

packages/compiler/src/taglib/lookup · high confidence

New tags API translator entry point in runtime-tags

The \packages/runtime-tags/src/translator/index.ts\ file now serves as the primary entry point for the Marko compiler's translator, establishing the 'tags' API as the preferred interface (\preferAPI = 'tags'\). This module configures the core tag library, defines the directory for tag discovery (\tags\), and exposes the translation, analysis, and transformation logic via extracted visitors. It also provides runtime entry file paths for HTML and DOM outputs, exposes a cheat sheet for coding agents, and extends the \@marko/compiler\ type definitions to include extra metadata for AST nodes like \MarkoTag\ and \MarkoAttribute\.

packages/runtime-tags/src/translator · high confidence

New translator utility modules for analysis, binding, and serialization

The translator's utility layer has been expanded with a suite of new modules that handle core compilation tasks. \analyze-errors.ts\ introduces a diagnostic-based error reporting system to collect all analysis mistakes in a single pass rather than throwing immediately. \binding-prop-tree.ts\ and \binding-has-prop.ts\ provide new data structures and logic for analyzing binding property paths and pruning unused content. \serialize-reasons.ts\ and \serialize-guard.ts\ (referenced in \branch-tag.ts\) manage the logic for determining which template sections need to be serialized for client-side updates. Additionally, \evaluate.ts\ adds expression evaluation capabilities to determine if values are constant or nullable, and \for-selector.ts\ implements logic to detect and optimize \for\ loop key selectors.

packages/runtime-tags/src/translator/util · high confidence

Removals

Removal of legacy RaptorJS core, async, and caching tag libraries

The \lib/taglibs\ directory has been cleared of the legacy RaptorJS templating implementation. This change removes the core tag handlers (including \c:if\, \c:forEach\, \c:choose\, \c:include\, \c:define\, and \c:write\), the async fragment tag (\async:fragment\), and the caching fragment tag (\caching:cached-fragment\), along with their associated compiler nodes, transformers, and taglib definitions. Templates relying on these specific RaptorJS tags will no longer be processed by this library.

lib/taglibs · high confidence

Removal of legacy templating runtime entry points and configuration

The library has removed several core files that previously provided the main templating runtime and its environment-specific extensions. Specifically, \lib/index.js\ (the main entry point), \lib/index\_async.js\ (async rendering support), \lib/index\_rhino.js\ (Java/Rhino bridge), and \lib/index\_server.js\ (server-side template loading and file rendering) have been deleted. Additionally, the configuration files \lib/async-optimizer.json\ and \lib/optimizer.json\ that defined dependencies for these modules have been removed. This change eliminates the legacy runtime interfaces and associated optimizer configurations from the library.

lib · high confidence

Architecture

Compiler refactored to use internal Babel copy and new plugin architecture

The Marko compiler now uses an internal copy of Babel rather than the host's Babel installation, ensuring consistent behavior and avoiding conflicts with the project's own dependencies. The core plugin logic has been restructured into a new \MarkoFile\ class and dedicated \migrate\ and \transform\ plugin modules, which handle tag-level hooks and transformations more cleanly. This change also introduces a new parser integration via \htmljs-parser\ and improves how the compiler manages file metadata, caching, and error reporting during the transformation phase.

packages/compiler/src/babel-plugin · high confidence

Internal Babel bundling and type declarations added

The compiler's internal module now includes a dedicated Babel wrapper (\packages/compiler/internal/babel/index.ts\) that re-exports core Babel functionality (such as \transformAsync\, \parse\, and \traverse\) along with specific plugins for TypeScript and CommonJS modules. This change introduces a static entry point designed to bundle Babel into \dist/babel.js\, ensuring that runtime-patched Marko AST additions are preserved by using static default imports rather than namespace imports. Additionally, a \modules.d.ts\ file has been added to provide TypeScript declarations for the various Babel packages used in this internal layer.

packages/compiler/internal · high confidence

New modular runtime entry points for DOM and HTML serialization

The runtime-tags package now exposes dedicated entry points for client-side DOM operations (dom.ts) and server-side HTML serialization (html.ts), replacing or supplementing previous monolithic exports. These modules provide specific APIs for control flow (if, for, show, try, await), attribute handling, event binding, and state management, allowing consumers to import only the functionality they need. The dom.ts entry point focuses on client-side runtime concerns like signal management, dynamic tag handling, and resume logic, while html.ts handles server-side rendering tasks such as escaping, asset loading, and HTML writing. This structural change supports better tree-shaking and clearer separation between client and server runtime concerns.

packages/runtime-tags/src · high confidence

New modular translator visitor structure in runtime-tags

The translator logic in \packages/runtime-tags/src/translator/visitors\ has been reorganized into a set of dedicated, modular files (e.g., \cdata.ts\, \comment.ts\, \placeholder.ts\, \function.ts\, \import-declaration.ts\). This change introduces specific handling for previously unsupported or generic elements—such as throwing errors for CDATA and XML declarations, and properly removing comments—while refining the analysis and translation of placeholders, static text, and function registrations. It also adds stricter validation for \load\ imports (enforcing default specifiers and resolving tag imports) and improves how the compiler tracks global references and abort signals for reactive state.

packages/runtime-tags/src/translator/visitors · high confidence

Refactor compiler internals to use an internal Babel copy and new utility modules

The compiler's \babel-utils\ directory has been restructured to rely on an internal copy of Babel (\@marko/compiler/internal/babel\) rather than the external \babel\ package, and now exports a comprehensive set of utility modules including \assert\, \compute\, \decode-html\, \diagnostics\, \get-file\, \imports\, \loc\, \parse\, \taglib\, \tags\, and \template-string\. This change introduces new capabilities for constant folding via \computeNode\ (supporting binary, unary, logical, conditional, template literal, and object expressions), improved error handling with non-throwing diagnostic channels (\diagnosticWarn\, \diagnosticDeprecate\, \diagnosticSuggest\), and refined parsing logic that better handles source locations, tag variables, and custom tag argument/attribute constraints. It also adds utilities for resolving relative imports, normalizing template strings, and tracking seen tags for watch file management.

packages/compiler/src/babel-utils · high confidence

Refactor tag translation into modular, tree-shakable visitor files

The tag translation logic in the runtime-tags package has been reorganized from a monolithic structure into distinct, modular visitor files (attribute-tag, custom-tag, dynamic-tag, native-tag, and index). This change introduces a new visitor pattern where each tag type is handled by its own dedicated module, improving code maintainability and enabling better tree-shaking of unused tag-handling code. The index file now acts as a central dispatcher that routes tag analysis and translation to the appropriate specialized visitor based on the tag type.

packages/runtime-tags/src/translator/visitors/tag · high confidence

Refactor taglib loader into modular source files

The taglib loading logic in the compiler has been reorganized from a single monolithic file into a set of distinct, modular components (Attribute, Tag, Taglib, DependencyChain, Transformer, Property, cache, loaders, and property handlers). This structural change improves maintainability and clarity of the taglib loading process without altering the external behavior for users.

packages/compiler/src/taglib/loader · high confidence

Behavioural changes

Build tooling overhaul: pnpm migration, parallel test runner, and native TypeScript support

The build system has been converted from npm to pnpm, introducing a new parallel test runner that distributes test suites across CPU cores to significantly reduce execution time. TypeScript source files are now executed directly via native Node.js type stripping, removing the previous dependency on @babel/register. Additionally, a new Babel plugin handles MARKO\_DEBUG expressions, and the package publishing workflow now supports aliasing packages to the main 'marko' scope.

scripts · high confidence

Compiler build system switches to rolldown bundling with optimized output

The compiler's build process has been refactored to use rolldown instead of per-file Babel processing, resulting in a single bundled output that improves performance and reduces bundle size. This change includes specific optimizations such as pruning unused Babel parser plugins and runtime helpers, stubbing optional dependencies to prevent hard errors, and resolving module references to avoid deadlocks. Additionally, the build scripts now handle type definitions by copying necessary Babel type declarations during the install phase, ensuring the published package remains functional and efficient for users.

packages/compiler/scripts · high confidence

Compiler configuration and entry points restructured

The compiler's configuration logic has been centralized into a new \config.js\ module, introducing explicit options for \linkAssets\ (enabling browser asset resolution and lazy loading), \hydrateInit\ (controlling automatic hydration initialization), and \stripTypes\ (managing TypeScript type removal). The main entry point (\index.js\) now exposes a \configure()\ function for setting global compiler defaults and implements error recovery diagnostics that include a coding agent fix guide. Additionally, the CommonJS register hook (\register.cjs\) has been updated to automatically install source-map-support when source maps are generated in development mode, ensuring accurate stack traces for compiled templates.

packages/compiler/src · high confidence

Improved HTML escaping and attribute handling in runtime helpers

The runtime HTML helpers now include robust escaping for script, style, and comment placeholders to prevent premature tag closure and potential injection issues, while also ensuring the ampersand character is correctly escaped in server-side rendered attributes. New helper modules for dynamic, merged, and specific (class/style) attributes standardize how HTML attributes are generated and validated, improving security and consistency in rendered output.

packages/runtime-class/src/runtime/html/helpers · high confidence

Improved interop translator feature detection and error reporting

The interop translator now more accurately distinguishes between Tags API and Class API templates by detecting specific features such as bound attributes, the \<show\> core tag, and templates located in 'tags' directories, while correctly ignoring raw open tags for attribute checks. Additionally, a new aggregate error builder provides users with detailed, syntax-highlighted code frames and precise file locations when compilation errors occur, improving the debugging experience for mixed API usage.

packages/runtime-tags/src/translator/interop · high confidence

Internal Babel traverse types adapted for Marko compiler

The compiler's type-generation scripts now include a custom \babel-traverse.js\ module that adapts the standard \@types/babel\_\_traverse\ definitions. This script injects Marko-specific metadata (such as \MarkoMeta\ and compiler \Config\) into the Babel file interface and generates type-checking methods for Marko AST node types, ensuring that internal type stripping and analysis correctly recognize Marko-specific structures.

packages/compiler/scripts/types · high confidence

Introduce new runtime-tags implementation with optimized rendering and event delegation

The runtime has been replaced with a new 'runtime-tags' implementation that significantly alters how components are rendered and events are handled. For users, this means the underlying rendering engine now uses a compact, encoded walk-code system for DOM traversal and delegates all event listeners to the document root, which can improve performance and reduce bundle size. The new runtime also introduces changes to how reactive signals and scopes are managed, potentially affecting how state updates are queued and processed, although the public API surface remains largely consistent for standard component usage.

.sizes/counter.csr · medium confidence

Introduces sibling-text constant definitions for placeholder positioning

A new \sibling-text.ts\ module has been added to the constants visitor, defining \None\, \Before\, and \After\ constants (values 0, 1, and 2) along with a corresponding \Value\ type. This provides a structured way to represent placeholder positioning relative to siblings within the runtime tags translator.

packages/runtime-tags/src/translator/visitors/constants · medium confidence

Marko 5 runtime-class package initialization and type alignment

The \packages/runtime-class\ package is now initialized with its core structure, including the runtime, compiler, and translator layers, along with debug/dist entry-point shims that conditionally load source or distribution files based on the \MARKO\_DEBUG\ environment. TypeScript definitions have been added to align Marko 5 Class API types with the Marko 6 Tags API, specifically ensuring that \renderBody\ is correctly typed on SVG tags and that HTML attributes inherit from the unified tag definitions.

packages/runtime-class · high confidence

Marko runtime class files moved into the runtime package

The Marko runtime implementation files—including the CLI entry point, compiler configuration, Node.js require hooks, and runtime utilities—have been relocated into the \packages/runtime-class\ directory. This restructuring consolidates the runtime-specific code, making the package structure more explicit for users managing dependencies or customizing the build environment.

(repo-wide) · high confidence

Pre-commit hook now runs linting, build, and size snapshot generation

The pre-commit hook has been updated to execute lint-staged, build the project, and generate build size snapshots using pnpm. This ensures that code is linted, compiled, and size metrics are tracked and committed before every commit.

.husky · high confidence

Removal of legacy RaptorJS compiler modules

The templating compiler in lib/compiler has been refactored by removing several core modules that were part of the previous RaptorJS implementation, including AttributeSplitter, ElementNode, EscapeXmlContext, Expression, ExpressionParser, Node, ParseTreeBuilder, Taglib, TaglibCollection, and TaglibXmlLoader. This change eliminates the old module structure and prepares the compiler for the new module.exports CommonJS pattern.

lib/compiler · high confidence

Repository tooling and configuration overhaul

The repository has been restructured with a new set of configuration files to support a modern development workflow. Linting and formatting are now handled by oxlint and oxfmt, replacing the previous jshint setup. The test runner (mocha) is configured for parallel execution across CPU cores with specific memory limits and VM module support. TypeScript compilation is standardized via tsconfig.json, and bundle size tracking is managed through .sizes.json. Additionally, the monorepo is configured using pnpm workspaces, and a security policy has been added to guide vulnerability reporting.

(repo-wide) · high confidence

Runtime class package exposes tags API interop and debug build config

The runtime-class package now includes a new build configuration file (build.json) that enables debug mode by default, allowing for easier debugging of runtime behavior. Additionally, the package introduces a new translator module (translator.js) that creates an interoperability layer between the internal class-based API and the Marko tags API, exposing standard translator methods like transform, analyze, and translate through this interop wrapper. The main entry point (index.js) has been updated to export the createOut function from the runtime module and the load function from the internal loader, establishing the core runtime interface.

packages/runtime-class/src · high confidence

Taglib finder now caches results per translator and uses provided filesystem

The taglib discovery logic in the compiler now keys its internal cache by the translator instance rather than just the directory path, ensuring that mixed Marko 5/6 processes do not share taglib entries across different translators. Additionally, the finder now accepts and uses a provided filesystem interface for file existence checks, improving compatibility with environments that lack the standard Node.js \process\ API.

packages/compiler/src/taglib/finder · high confidence

Taglib lookup now requires an explicit translator argument

The \buildLookup\ function in the taglib module now requires a translator instance to be passed as the second argument. Previously, the module would automatically fall back to requiring the default translator if none was provided; this implicit behavior has been removed. Users must now explicitly pass the translator (e.g., \require('marko/translator')\) when calling \buildLookup\ to ensure correct tag resolution, with a debug warning issued if the argument is missing.

packages/runtime-class/src/taglib · high confidence

Fixes

Compiler preserves comments, whitespace, and async shorthand in generated output

The compiler now generates output that more faithfully reflects the source code by preserving JavaScript comments, type annotations, and escape sequences that were previously stripped. It also retains whitespace in elements like \<pre\> and \<script\>, keeps open-tag comments, and correctly formats async shorthand methods. Additionally, the compiler now properly handles tag variables ending in line comments and preserves whitespace in empty body tags, ensuring the generated code is easier to read and debug.

patches · high confidence

New build pipeline with rolldown and tree-shaking support

The build system for the runtime-tags package has been updated to use rolldown instead of esbuild, introducing custom plugins to support tree-shakable feature modules and fix declaration hoisting issues in production builds. This change enables more efficient bundling by allowing debug-only modules to be stripped in production and ensures correct variable declaration handling in the output.

packages/runtime-tags/scripts · high confidence

Runtime helpers for class/tags interop, lazy loading, and serialization

This change introduces a suite of runtime helper modules in \packages/runtime-class/src/runtime/helpers\ to support the Marko runtime-class architecture. It adds \dynamic-tag.js\ and \render-tag.js\ to handle dynamic component rendering and event binding interoperability between Class and Tags APIs (converting camelCase props to dash-case and bridging \on-x\ events). It includes \load-tag.js\ and specific trigger helpers (\load-tag-visible-trigger.js\, \load-tag-idle-trigger.js\, etc.) to implement native asset management and lazy loading capabilities. Additionally, it provides \serialize-noop.js\ and \skip-serialize.js\ to fix serialization issues for implicit split components and hydration state, while \class-value.js\ and \style-value.js\ offer utility functions for rendering class and style attributes.

packages/runtime-class/src/runtime/helpers · high confidence

Stabilize Class API and Tags API interop runtime

The runtime compatibility layer in \packages/runtime-class/src/runtime/helpers/tags-compat\ has been significantly hardened to ensure reliable mixing of Marko 5 (Class API) and Marko 6 (Tags API) components. This update introduces dedicated entry points for DOM and HTML rendering (supporting both CommonJS and ESM, with debug variants) that bridge the two systems. Key improvements include robust serialization of Class API state into Tags chunks, correct handling of inert Class children within Tags parents, and fixes for event handler bridging and scope resumption. These changes prevent crashes during re-renders and ensure that inline scripts and component definitions are flushed correctly across the interop boundary.

packages/runtime-class/src/runtime/helpers/tags-compat · high confidence

Test coverage

Added API test suite for Marko runtime class; Added browser fixture tests for class component lifecycle and DOM interactions; Added browser-side test infrastructure for Marko components; Added component-page fixtures for runtime-class tests; Added comprehensive test coverage for AsyncStream; Added comprehensive test coverage for the Marko compiler; Added render fixture tests for attribute handling and async client-reordering; Added server-side rendering tests for class components and runtime utilities; Added test fixtures for async callback await behavior; Added test utility helpers for browser-based Marko component testing; Added tests for AsyncVDOMBuilder and RenderResult; Added tests for ServerComponent lifecycle and state management; Added tests for compiler babel-utils helpers; Added tests for taglib finder edge cases; Added tests for taglib loader configuration and discovery; Added tests for taglib lookup functionality; Added tests for the API compiler; Added translator tests for complex at-tag scenarios; Expanded test coverage for the Tags API runtime; Removed obsolete test infrastructure files.

Dependencies

Marko runtime-class package.json and internal module manifests added

The \packages/runtime-class\ directory now includes a \package.json\ defining the main \marko\ package (version 5.39.44) with dependencies on \@marko/compiler\ ^5.42.8 and \@marko/runtime-tags\ ^6.3.55, alongside a suite of internal \@internal/\*\ module manifests under \src/node\_modules\ that define browser/worker exports for component and loader logic. Additionally, \packages/runtime-tags\ (version 6.4.0) is present with its own dependency on \@marko/compiler\ ^5.42.10, and various test fixture \package.json\ files have been added to support taglib and config resolution tests.

(dependencies) · high confidence

Housekeeping

Initial DOM runtime size snapshot; Initial size snapshot for comments.csr component; New developer documentation for runtime-tags architecture and workflows; New size snapshot for SSR counter component; New size snapshot for comments SSR entry.

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 56 → 50 (-5.6)
  • Rubric changed (rubric-2026.09.12 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 55 → 57 (+2.7)
  • Architecture 62 → 63 (+0.2)
  • Maturity 57 → 57 (-0.0)
  • Readiness 54 → 41 (-13.5)
  • Security 61 → 61 (-0.7)
  • Performance 60 (new)

Resolved (104)

  • (anonymous) (cognitive 55) (.sizes/comments.csr/runtime.js)
  • (anonymous) (cognitive 55) (.sizes/dom.js)
  • (anonymous) (cognitive 59) (.sizes/dom.js)
  • (anonymous) (cyclomatic 28) (.sizes/dom.js)
  • (anonymous) (cyclomatic 44) (.sizes/comments.csr/runtime.js)
  • (anonymous) (cyclomatic 44) (.sizes/dom.js)
  • * (cognitive 54) (packages/compiler/src/taglib/loader/loadTagFromProps.js)
  • Change coupling: html-comment.ts ↔ html-script.ts (packages/runtime-tags/src/translator/core/html-comment.ts)
  • Change coupling: html-comment.ts ↔ html-style.ts (packages/runtime-tags/src/translator/core/html-comment.ts)
  • Change-coupling hub: dom.js → entry.js, entry.js, entry.js (.sizes/dom.js)
  • Documentation: no architecture or design documentation (packages/runtime-class/docs/installing.md)
  • FunctionTooLong: references.finalizeReferences (packages/runtime-tags/src/translator/util/references.ts)
  • FunctionTooLong: references.getReadReplacement (packages/runtime-tags/src/translator/util/references.ts)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • Hotspot: .sizes/counter.csr/runtime.js (.sizes/counter.csr/runtime.js)
  • Hotspot: packages/compiler/src/taglib/lookup/index.js (packages/compiler/src/taglib/lookup/index.js)
  • Hotspot: packages/runtime-class/src/translator/util/add-dependencies.js (packages/runtime-class/src/translator/util/add-dependencies.js)
  • Hotspot: packages/runtime-class/src/translator/util/load-import.js (packages/runtime-class/src/translator/util/load-import.js)
  • …and 84 more

New (320)

  • (anonymous) (cognitive 16) (.sizes/dom.js)
  • (anonymous) (cognitive 33) (.sizes/comments.csr/runtime.js)
  • (anonymous) (cognitive 33) (.sizes/dom.js)
  • (anonymous) (cognitive 50) (.sizes/dom.js)
  • (anonymous) (cyclomatic 27) (.sizes/dom.js)
  • (anonymous) (cyclomatic 29) (.sizes/comments.csr/runtime.js)
  • (anonymous) (cyclomatic 29) (.sizes/dom.js)
  • * (cognitive 53) (packages/compiler/src/taglib/loader/loadTagFromProps.js)
  • Change coupling: entry.js ↔ dom.js (.sizes/comments.ssr/entry.js)
  • Chunk.flushPlaceholder (cognitive 18) (packages/runtime-tags/src/html/writer.ts)
  • Chunk.flushReadyScripts (cognitive 16) (packages/runtime-tags/src/html/writer.ts)
  • ComponentDef.ComponentDef.___deserialize (cyclomatic 24) (packages/runtime-class/src/runtime/components/ComponentDef.js)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no project overview (README.md)
  • FileTooLong: tag/dynamic-tag.ts (packages/runtime-tags/src/translator/visitors/tag/dynamic-tag.ts)
  • FileTooLong: util/finalize-references.ts (packages/runtime-tags/src/translator/util/finalize-references.ts)
  • FunctionTooLong: read-replacement.getReadReplacement (packages/runtime-tags/src/translator/util/read-replacement.ts)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • High CVE: [GHSA redacted] (pnpm-lock.yaml)
  • …and 300 more

Changes since last survey

  • 186 commits — 97 feature/other, 89 fixes

By area

  • packages/runtime-tags — 120 commits
  • agent-feedback/items — 27 commits
  • packages/compiler — 18 commits
  • packages/runtime-class — 8 commits
  • (root) — 4 commits
  • .changeset/cheatsheet-raw-output.md — 1 commit
  • .changeset/compile-missing-dir.md — 1 commit
  • .changeset/drop-marko-wildcard-types.md — 1 commit
  • .changeset/keep-cjs-strict-mode.md — 1 commit
  • .changeset/reject-string-content-type.md — 1 commit
  • .changeset/svg-render-body-types.md — 1 commit
  • .github/CONTRIBUTING.md — 1 commit
  • .github/workflows — 1 commit
  • agent-feedback/README.md — 1 commit

Notable commits

  • fix: agent-feedback: three tags-API bugs found downstream (#4224)
  • fix: fix(compiler): accept a tag var that ends in a line comment
  • fix: fix(compiler): collapse only ASCII whitespace in template text
  • fix: fix(compiler): end source map sourceRoot with a separator
  • fix: fix(compiler): keep JavaScript comments in source output
  • fix: fix(compiler): keep marko@5's translator when @marko/runtime-tags is also a dependency
  • fix: fix(compiler): keep open tag comments in source output
  • fix: fix(compiler): keep the agent fix guide on the label bundler plugins print
  • fix: fix(compiler): keep types and escapes in source output
  • fix: fix(compiler): print async shorthand methods as shorthand
  • fix: fix(compiler): report an invalid attribute method parameter as a compile error
  • fix: fix(compiler): stop naming Babel's parseExpression() in expression errors
  • fix: fix(compiler): strip a tag's type arguments and parameters with stripTypes
  • fix: fix(compiler): type compile results and taglib definitions as they come back
  • fix: fix(compiler): window a long line in the error code frame
  • fix: fix(runtime-class): settle an errored render once, as an error
  • fix: fix(runtime-class): type renderBody on SVG tags
  • fix: fix(runtime-tags): a lazy template reading no input renders in a dynamic tag
  • fix: fix(runtime-tags): analyze dynamic tags that choose between templates
  • fix: fix(runtime-tags): apply a top level tag param default
  • …and 166 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

marko-js/marko was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 70a0594fe2b79d9179fa38edfada524a32f8f7c3 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.