All notable changes to evjs are documented here. Releases follow Semantic Versioning.
- Reorganized plugin architecture — Split the monolithic
bundler-webpack/src/index.ts(381 lines) into focused modules underplugin/:plugin/index.ts—EvWebpackPluginorchestratorplugin/server-compiler.ts— "use server" module scanning and child compiler
- Moved
ManifestCollectorto@evjs/manifest— Manifest building logic (ManifestCollector,resolveRoutes,ExtractedRoute) now lives in the zero-dependency manifest package alongside the types it produces - Moved
buildHtml()to@evjs/ev— Framework-level HTML transforms (assetPrefix injection, plugintransformHtmlhooks) extracted to the core package; accepts a pre-parsed doc to avoid heavy build-tool dependencies @evjs/evstays lightweight — Removed@evjs/build-toolsdependency;@evjs/evnow only depends on@evjs/manifestand@evjs/shared
- Runtime
publicPathviawindow.assetPrefix— Webpack's chunk loader now readswindow.assetPrefixat runtime, so dynamically loaded chunks resolve against the deploy-time CDN URL without requiring a rebuild. The prefix can be injected intoindex.htmlat deploy time by rewriting the<script>window.assetPrefix="..."</script>tag.
- Updated
assetPrefixdocs indeploy.md(EN + zh-Hans) to reflect runtime publicPath behavior - Updated
config.tsdocstring to mention runtime chunk loading and deploy-time rewriting
assetPrefixconfig option — New top-level config field for deploying static assets to a CDN. SetassetPrefix: "https://cdn.example.com/"inev.config.tsto prefix all JS/CSS asset URLs in the production build output- Runtime
window.assetPrefix— The configured prefix is injected as a<script>window.assetPrefix="..."</script>tag in the<head>ofindex.html, enabling deployment-time rewriting and dynamic asset URL construction in React components assetPrefixignored in dev — Duringev dev, the prefix is always forced to"/"to preserve local HMR and dev server stability
- Added CDN deployment section to
deploy.md(EN + zh-Hans) - Added
assetPrefixreference toconfig.md(EN + zh-Hans) with defaults table, client options description, and full reference example - Updated
evjs-devAI skill with CDN deployment gotcha
- Renamed internal
publicPathtoassetPrefixacross@evjs/build-tools,@evjs/bundler-webpack,@evjs/manifest, and@evjs/evfor naming consistency with Next.js conventions - Added
Window.assetPrefixglobal type augmentation in@evjs/clientfor type-safe access
- Resolved manifest route paths — Route extraction now parses
getParentRoutehierarchy and produces fully resolved URL paths (e.g./posts/$postIdinstead of bare$postId), eliminating duplicate"/"entries inmanifest.json - Removed duplicate index routes — Index routes under non-root parents are excluded from the manifest since they resolve to the same URL as their parent
- Fixed ANSI escape codes in build output — Webpack stats no longer emit raw
\x1B[...sequences in the logger
extractRoutes()/resolveRoutes()— New build-tools APIs for extracting route metadata fromcreateRoute()calls and resolving full URL paths from the parent-child hierarchy
- Upgraded
domparser-rsfrom^0.0.7to^0.1.0— migrated fromNodeReprto standard DOM type hierarchy (Document,Element,Node)
- Added 21 unit tests for route extraction and resolution in
@evjs/build-tools - Updated
ManifestCollectortests for resolved route output
transformHtmlplugin hook — New lifecycle hook receives a parsed DOM document (EvDocument) instead of a raw HTML string, enabling robust, structured HTML manipulation via standard DOM methodsEvDocumentinterface — Bundler-agnostic DOM subset in@evjs/evcovering querying, attributes, tree mutation, content insertion, traversal, and document-level accessors- Custom HTML generation — New
generateHtml()utility in@evjs/build-toolsusingdomparser-rsfor template parsing and asset injection (replacesHtmlWebpackPluginfor asset injection) basic-pluginsexample — New example demonstrating all four plugin hooks (buildStart,bundler,transformHtml,buildEnd)
- Added Playwright e2e tests for
basic-plugins(4 browser tests) - Added
transformHtmlDOM manipulation e2e scenarios toplugin-hooks.test.ts(3 tests: meta injection, comment injection, multi-plugin composition) - Added 13 unit tests for
generateHtmlin@evjs/build-tools
- New dedicated Plugins guide (
docs/docs/plugins.md) with lifecycle diagram,EvDocumentAPI reference, type-safe bundler helpers, and practical recipes (CSP nonce, analytics, deploy manifest) - Chinese (zh-Hans) translation of the Plugins guide
- Added Plugins page to sidebar under Core Concepts
- Updated architecture diagrams and roadmap to include
transformHtmlin the hook lifecycle
- Plugin lifecycle API — Refactored
EvPluginfrom top-level config/bundler hooks to aname+setup(ctx)pattern returning lifecycle hooks (buildStart,bundler,buildEnd) - New
EvPluginContext,EvPluginHooks, andEvBuildResulttypes for full type-safe plugin authoring - Added typed
webpack()helper in@evjs/bundler-webpackfor type-safe bundler config manipulation inside plugins - Removed legacy
EvConfigCtxandbundler.configescape hatch - CLI now orchestrates full
setup → buildStart → bundler → buildEndlifecycle
- Production HTTPS enforcement — TLS cert failures now throw instead of silently falling back to unencrypted HTTP
- Server function input validation —
Array.isArray(args)guard indispatch()prevents malformed payloads from spreading incorrectly - Request body validation — Early
fnIdtype check returns a structured 400 error for malformed RPC requests - Structured error propagation — Client transport now parses JSON error bodies on non-2xx responses, preserving
ServerError.dataend-to-end
- Added missing
@evjs/manifestdependency to@evjs/shared - Removed unused
globandpicocolorsfrom@evjs/cli - Removed dead
import "node:module"side-effect import in webpack adapter - Removed redundant
HotModuleReplacementPlugin(already provided by webpack-dev-server) - Added
toHttpMethod()normalizer for safe, case-insensitive HTTP method handling - Resolved all Biome lint warnings across the monorepo
- Fixed 6 phantom API references documenting non-existent functions (
handleServerFunctions,setContext/getContext,createNodeServer,WebSocketTransport,resolveProjectRoot/loadManifest) - Corrected API names:
createNodeServer→serve,createServer→createFetchHandler - Fixed
ServerErrorconstructor signature in docs (2 args, not 3) - Fixed stale package paths (
packages/webpack-plugin→packages/bundler-webpack) - Fixed stale dependency graph (
@evjs/sharednow depends on@evjs/manifest) - Fixed wrong config path (
server.functions.endpoint→server.endpoint) - Synced all fixes to Chinese (zh-Hans) documentation
- CSR-only mode —
server: falseinev.config.tsproduces a flatdist/output with no server bundle;"use server"modules cause a build error
- Codebase review fixes across 15 files (19 issues)
- Fixed outdated
createHandler()references →createFetchHandler()
- Improved E2E test isolation with dynamic ports and unique temp dirs
- Fixed E2E tests to use correct manifest path
dist/client/manifest.json
- Split build manifest into separate
dist/client/manifest.jsonanddist/server/manifest.jsonfor improved build modularity - Updated
@evjs/manifesttypes:ServerManifest+ClientManifestreplace the unifiedManifest - Fixed project structure docs to use code-based routing and
global.ts
server.backendrenamed toserver.runtime— The config field that specifies the JS runtime command (node,bun,deno) has been renamed for clarity. Update yourev.config.tsif you were using this field.
- CSR-only dev server fix —
ManifestCollector.entrydefaulted to"main.js", causing CSR-only apps to crash onev dev. The entry is nowundefinedwhen no server bundle is produced.
- Fixed
create-appscaffolding: restoredbasic-server-routessymlink after npm pack - Fixed
bundler-webpack: removeddevServerOverridesspread leakinghttpsinto devServer config - Removed fallback RSA certificate generation for HTTPS (explicit key/cert now required)
- Fixed E2E
ENOTEMPTYrace condition by spawning node directly
- Reverted scaffolding package name from
create-ev-appback to@evjs/create-app - Reverted registry publishing to use token-based auth for stability
- Updated docs landing page terminal preview
- Removed npm caching from CI workflows to resolve
huskypermission errors - Fixed stale
create-evjs-appreferences in lockfile
- Renamed scaffolding package
@evjs/create-app→create-evjs-app(later reverted in v0.0.11)
- String literal route paths — Enforced compile-time string literal types for
pathincreateRoute()androute(), ensuring routes are statically analyzable
- Added comprehensive READMEs for all published packages
- Standardized scaffolding command to
npx create-evjs-app
- Bundler adapter architecture — Decoupled bundler logic with a new adapter layer, enabling future bundler backends (Rspack, Vite)
- Renamed
@evjs/webpack-plugin→@evjs/bundler-webpackwith relocated adapter logic - Docusaurus site — Redesigned landing page, added config/dev/build/deploy guides, Mermaid diagrams, and Chinese (zh-Hans) i18n
- Fixed
ERR_REQUIRE_CYCLE_MODULEin Node 22 CI - Fixed mobile navbar sidebar z-index stacking
- Cleaned up technical debt and lint warnings
getFnQueryOptions()— New extractor replacing deprecatedserverFn()wrapper for TanStack Query integration- Project structure guide — Documented recommended FSD (Feature-Sliced Design) conventions
- Server function metadata —
.queryKey(),.fnId,.fnNameproperties on server function stubs for cache invalidation and introspection - Docusaurus documentation site — Full docs with config, dev, build, deploy pages; Mermaid diagram support; GitHub Pages deployment
- Chinese (zh-Hans) i18n — Complete translated documentation
- Renamed
EvPluginloaders tomodule.rulesfor webpack alignment
- Added
declaration: truetopackages/cli/tsconfig.jsonto emit type declarations during build
- Programmatic CLI API — Extracted
dev(config?, options?)andbuild(config?, options?)for programmatic usage alongside the CLI - HTTPS support — Added self-signed HTTPS generation for the local dev server (
server.dev.https) - Config cleanup — Restructured
ServerConfigwith nested endpoints, removed stale dev options
The first stable release of evjs — a React fullstack framework with server functions and programmatic route handlers.
- Server Functions —
"use server"RPC with type-safeuseQuery/useSuspenseQuery - Route Handlers —
route(path, { GET, POST, ... })REST API with middleware, auto-OPTIONS, auto-HEAD, 405 fallback - Zero-Config CLI —
ev dev,ev buildwith Webpack, SWC, and HMR - Plugin System —
EvPluginwith module rules for custom loaders (Tailwind, SVG, etc.) - Multi-Runtime — Hono-based server with Node.js and ECMA (Deno/Bun) adapters
- TypeScript 6 — Full TypeScript 6.0 support across all packages