hexojs/hexo
57.4
Adequate · 28 September 2026
8.8k
lines of production code
TypeScript
primary language
4
measurements over time
What this system is
This system is Hexo, a static site generator that processes content files into rendered web pages. It manages the full lifecycle of site generation, including parsing Markdown, handling assets, and applying filters for formatting and localization. The core functionality relies on a plugin architecture that supports custom commands, helpers, and renderers to extend its capabilities.
How it got here
2012–2023 — TypeScript migration and Hexo 8 upgrade
23 changes.
The project underwent a comprehensive migration of its core libraries, plugins, and models from JavaScript to TypeScript, introducing strict type definitions and improved code safety. This effort coincided with the Hexo 8.1.2 release, which mandated Node.js 20 and modernized the build system, while also incorporating performance optimizations and new configuration options for rendering and data handling.
2024 — comprehensive test coverage expansion
10 changes.
This period focused on significantly expanding the test suite by adding comprehensive TypeScript and unit tests across Hexo's core components, including models, processors, renderers, and console commands. The work aimed to verify the behavior of key functionalities such as file handling, theme management, and template rendering to ensure system stability and correctness.
Features
Introduction of custom Moment.js schema type for date handling
A new \SchemaTypeMoment\ class has been added to \lib/models/types/moment.ts\, defining how Moment.js date objects are cast, validated, and serialized within the data layer. This type ensures that date values are correctly converted to Moment instances, validates their integrity, and handles storage by converting them to ISO strings via the \\_d\ property, while also supporting specific query operators for day, month, and year comparisons.
lib/models/types · high confidence
Introduction of the hexo CLI entry point
A new executable script at bin/hexo has been added to serve as the command-line interface entry point. This script initializes the Node.js environment and delegates execution to the hexo-cli module, enabling users to run Hexo commands directly from the terminal.
bin · high confidence
Project initialization and configuration scaffolding
The repository is initialized with essential configuration files to support development and community standards. This includes an .editorconfig for consistent code formatting, TypeScript configuration (tsconfig.json) and ESLint setup (eslint.config.js) for code quality, and a .mocharc.yml for test execution. A CODE\_OF\_CONDUCT.md is added to define community guidelines, and the README.md is updated with installation instructions and badges. Additionally, build artifacts and temporary files are managed via an updated .gitignore, while legacy files like Makefile and .npmignore are removed.
(repo-wide) · high confidence
Architecture
Migrate before\_post\_render filters to TypeScript
The \before\_post\_render\ filter logic, which processes code blocks and title casing before post rendering, has been rewritten from JavaScript to TypeScript. This migration includes the \backtick\_code\_block\ filter, which handles syntax highlighting and supports additional options like line numbers and wrapping, and the \titlecase\ filter, which applies title casing to post titles. The change improves type safety and maintainability for these core rendering steps without altering their external behavior.
_lib/plugins/filter/before\_post\render · high confidence
Behavioural changes
Adopts npx lint-staged for pre-commit hooks
The pre-commit hook in the .husky directory has been updated to execute lint-staged via npx. This change replaces the previous hook implementation, ensuring that staged files are linted before each commit using the project's locally installed version of lint-staged.
.husky · high confidence
Console commands migrated to TypeScript
The console plugin commands (clean, config, deploy, generate, list, migrate, new, publish, render) have been rewritten in TypeScript. This migration introduces static typing for command arguments and return values, improving code reliability and maintainability without changing the user-facing CLI behavior.
lib/plugins/console · high confidence
Console list command rewritten in TypeScript with improved table rendering
The \hexo list\ command and its subcommands (posts, pages, tags, categories, routes) have been rewritten in TypeScript, introducing stricter type safety via \CategorySchema\, \PageSchema\, \PostSchema\, and \TagSchema\. The output formatting has been enhanced: posts now display both categories and tags in separate columns, tags show their path, and routes are displayed in a hierarchical tree structure using \fast-archy\. Table rendering now uses \fast-text-table\ with a custom \stringLength\ helper to correctly handle double-byte characters and ANSI color codes, ensuring aligned columns. The command entry point (\index.ts\) now uses \abbrev\ for argument shortening and delegates to specific handlers for each list type.
lib/plugins/console/list · high confidence
Extend subsystem migrated to TypeScript
The core extension subsystem (lib/extend) has been rewritten in TypeScript, introducing strict type definitions for all plugin interfaces including Console, Deployer, Filter, Generator, Helper, Injector, Migrator, Processor, Renderer, SyntaxHighlight, and Tag. This migration provides better type safety and IDE support for plugin developers while maintaining the existing public API for registering and executing Hexo plugins.
lib/extend · high confidence
Hexo core migrated to TypeScript
The Hexo core library has been rewritten in TypeScript, introducing strict type definitions for the Hexo context, configuration, and internal modules. This migration brings a new \default\_config.ts\ that explicitly defines the structure of the configuration object, a \validate\_config.ts\ module that enforces stricter validation for settings like \url\ and \root\, and a \types.ts\ file that standardizes interfaces for posts, categories, and helpers. For users, this ensures more robust configuration handling and better tooling support, while maintaining backward compatibility with existing JavaScript-based plugins and themes.
lib/hexo · high confidence
Highlight plugin supports language exclusion and stripIndent configuration
The highlight plugin now respects the new \exclude\_languages\ configuration option for both highlight.js and prismjs; when a language is listed in this array, the plugin skips syntax highlighting and returns a plain code block without line numbers or auto-detection. Additionally, the \stripIndent\ option (mapped from \strip\_indent\ in the config) is now passed through to the underlying highlighting engines, allowing users to control whether leading whitespace is removed from code blocks.
lib/plugins/highlight · high confidence
Migrate after-render filters to TypeScript
The external link and meta generator after-render filters have been rewritten in TypeScript. This migration preserves the existing behavior: the external link filter continues to add \target="\_blank"\ and \rel="noopener"\ to external links when site-wide external linking is enabled, and the meta generator filter continues to inject the Hexo version meta tag into the document head if not already present.
_lib/plugins/filter/after\render · high confidence
Migrate filter plugins to TypeScript and add timestamp permalink variable
The filter plugins in lib/plugins/filter have been rewritten in TypeScript, including the before\_exit, new\_post\_path, and post\_permalink filters. This migration introduces a new \timestamp\ variable for permalink generation, allowing users to include the post's Unix timestamp in their URL structure. Additionally, the post\_permalink filter now ensures that permalinks end with a trailing slash when the \post\_asset\_folder\ configuration is enabled and the permalink does not already end with a slash or \.html\ extension.
lib/plugins/filter · high confidence
Migrate i18n template locals filter to TypeScript
The i18n template locals filter in lib/plugins/filter/template\locals has been rewritten in TypeScript. This change updates the internal implementation of how language detection and localization helpers (locals.\\_ and locals.\_p) are applied to page locals, ensuring type safety while preserving the existing behavior of resolving page language from configuration, theme, or URL patterns.
_lib/plugins/filter/template\locals · high confidence
Migrate tag plugins to TypeScript
The tag plugins in lib/plugins/tag (including asset\_img, asset\_link, blockquote, code, full\_url\_for, iframe, img, include\_code, link, post\_link, post\_path, pullquote, and url\_for) have been rewritten in TypeScript. This migration updates the internal implementation to use TypeScript types and modern module patterns while preserving the existing user-facing syntax and behavior for all registered tags.
_lib/plugins/filter/before\generate, lib/plugins/tag · high confidence
Migrated lib/box to TypeScript
The core file-boxing logic in lib/box has been rewritten from JavaScript to TypeScript. This introduces strict type definitions for the File class (including source, path, params, and type properties) and the Box class (including options, context, base, and processors). The migration ensures that file paths are handled correctly on Windows by preserving backslashes for filesystem operations while escaping them for URL paths, and it leverages TypeScript's type system for better code safety and maintainability.
lib/box, lib/theme/processors · high confidence
Migration to TypeScript and performance enhancements in helpers and generators
The core helper and generator plugins have been rewritten in TypeScript, introducing strict typing for data schemas and configuration options. This migration includes several behavioral improvements: the \css\ and \js\ helpers now correctly respect the \relative\_link\ configuration for URL generation, the \list\_archives\ helper caches post queries to reduce overhead, and the \toc\ helper now supports limiting the number of output items via a \max\_items\ option. Additionally, the \open\_graph\ helper has been extended to support Fediverse creator metadata, and the \list\_categories\ helper now allows locale-aware sorting of category names.
lib/plugins/helper · high confidence
Models migrated to TypeScript with binary relation indexes for tags and categories
The data models in lib/models have been rewritten in TypeScript, introducing a new BinaryRelationIndex system to manage Post-Tag and Post-Category relationships. This change replaces direct database queries with in-memory indexes, significantly improving the performance of retrieving tags and categories for posts. The migration also includes a new caching mechanism for the tags getter to further optimize repeated lookups during site generation.
lib/models · high confidence
Post-render filters migrated to TypeScript
The \after\_post\_render\ plugin logic, specifically the excerpt generation and external link handling, has been rewritten in TypeScript. This migration preserves the existing behavior: posts are split into excerpts and full content based on the \\<!-- more --\>\ marker, and external links are automatically updated with \target="\_blank"\ and \rel="noopener"\ attributes when the external link feature is enabled for posts.
_lib/plugins/filter/after\_post\render · high confidence
Processor module rewritten in TypeScript with new post title and asset handling
The post and asset processors have been rewritten in TypeScript, introducing a new configuration option \use\_slug\_as\_post\_title\ that automatically uses the post's slug as its title when no title is explicitly defined in the front-matter. The processor now correctly handles post assets within \post\_asset\_folder\ by restricting renderable file checks to the configured new post file extension, ensuring non-matching assets are processed as static files rather than pages. Additionally, a new \SourceIdIndex\ class optimizes post lookups by caching source-to-ID mappings, and common utilities for date/timezone adjustment and file exclusion have been consolidated into a shared module.
lib/plugins/processor · high confidence
Renderer plugin files migrated to TypeScript
The renderer plugin implementation files (index, json, nunjucks, plain, and yaml) have been converted from JavaScript to TypeScript. This migration introduces explicit type definitions for function data and environment interfaces, ensuring stricter type safety in the rendering logic for formats like HTML, CSS, JS, JSON, YAML, and Nunjucks templates without changing the external API or user-facing behavior.
lib/plugins/renderer · high confidence
Test coverage
Added TypeScript test coverage for core Hexo modules; Added TypeScript test suites for Box, File, Theme, and View components; Added TypeScript tests for the extend API; Added benchmark and profiling test script; Added test coverage for post and asset tags; Added test coverage for post-rendering and site-generation filters; Added test fixtures and utilities for post-rendering scenarios; Added unit tests for Hexo data models; Added unit tests for Hexo processors and theme processors; Added unit tests for JSON, Nunjucks, plain text, and YAML renderers; Added unit tests for console commands; Added unit tests for template helper functions.
Dependencies
Hexo 8.1.2 release with Node.js 20 requirement and TypeScript build
Hexo has been updated to version 8.1.2, introducing a mandatory Node.js runtime requirement of version 20.19.0 or higher. The project has migrated to a TypeScript-based build system, compiling source code to a \dist/\ directory and utilizing \tsc\ for builds. This release also refreshes the dependency ecosystem, upgrading core libraries such as \hexo-util\ to 4.0.0, \hexo-fs\ to 5.0.0, \warehouse\ to 6.0.0, and \js-yaml\ to 4.1.0, while updating development tools like \eslint\ to 9.17.0, \mocha\ to 10.0.0, and \sinon\ to 17.0.1.
(dependencies) · high confidence
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 44 → 57 (+13.0)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.16) — scores are not directly comparable.
Lenses
- Code Health 79 → 85 (+5.9)
- Architecture 67 (new)
- Maturity 59 → 53 (-5.5)
- Readiness 40 → 60 (+19.8)
- Security 37 → 53 (+15.9)
- Performance 100 (new)
Resolved (65)
- Critical CVE: [GHSA redacted] (package-lock.json)
- Dimension evaluation failed
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- …and 45 more
New (214)
- Change coupling: css.ts ↔ js.ts (lib/plugins/helper/css.ts)
- Concentrated knowledge decay
- Console.register (cognitive 20) (lib/extend/console.ts)
- Critical CVE: [GHSA redacted] (package-lock.json)
- FixmeComment (lib/models/types/moment.ts)
- FixmeComment (lib/models/types/moment.ts)
- FixmeComment (lib/plugins/renderer/yaml.ts)
- Further sole-owners (lower concentration)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High CVE: [GHSA redacted] (package-lock.json)
- High vulnerability: [GHSA redacted] (package-lock.json)
- High vulnerability: [GHSA redacted] (package-lock.json)
- High vulnerability: [GHSA redacted] (package-lock.json)
- …and 194 more
Changes since last survey
- 5 commits — 5 feature/other, 0 fixes
By area
- lib/plugins — 5 commits
Notable commits
- change: feat(helper): support locale-aware category sorting (#5819)
- change: feat(open_graph): support fediverse creator metadata (#5816)
- change: perf(nunjucks): reuse compiled view templates (#5810)
- change: perf: avoid copying partial locals on cache hits (#5811)
- change: perf: speed up hot processing (#5803)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
hexojs/hexo 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 28 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 751e856691bfe24182cf8763feb29db0422dcfee — the exact code this score is about.
- Scored under rubric-2026.09.16 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-eb9197011364.