Changelog
All notable changes to this project are documented here. The format follows Keep a Changelog and versions follow Semantic Versioning.
2.0.0 - 2026-10-19
Server-composed micro-frontends for Node.js: render faces on any server, compose them into pages, hydrate them as islands.
Added
- A documentation site with a live demo, built by
npm run sitefor ayers.repair/opensource/minimesh. - TypeScript 7 in strict mode, ESM only, Node.js 22.18 or later. Built with tsdown, linted and
formatted with Biome, tested with
node:test. - Fastify 5.
createMeshServerreturns the instance before it listens. - Faces and views are named with
name. Meshes are views withmesh: true. - Preprocessors are plain functions that fill
context.data, run shared, then face, then view.context.templatesets the template. - Child faces are
{ name, url, timeout, headers }, rendered in parallel. A failing child face renders as an HTML comment, andmaxNestLevelstops nesting with a 508 response. View.assets: scripts and styles loaded beside a face’s markup, outside its hydration root.routeOptionspasses Fastify route options to the content and data routes.classNameandattributesset the face container’s class and attributes.plugins,staticDirsanddevWrapperadd plugins, static directories and a development wrapper.- The browser runtime is
minimesh/client:defineView, andtoAll,toFaces,toMeshandonMessagefor messages between faces. Preact helpers areminimesh/preact. - Device detection uses the
Sec-CH-UA-Mobileclient hint and bowser (MIT).devicereaches preprocessors and the browser. - One
minimeshcommand:build(esbuild and Sass, with@usesupport);dev(rebuild,node --watch, live reload, face previews);generate; andinsights, which links to the full report on pagespeed.web.dev and saves the JSON for Lighthouse Viewer with--out. - Markdown code highlighting with highlight.js.
Security
- The browser receives route parameters and the query, never request headers or bodies.
- Remote faces receive only
user-agent,accept-languageand the headers you configure. - Asset URLs never come from the
Hostheader; setpublicUrlfor absolute URLs. - No built-in authentication and no default Helmet policy: use
routeOptions.preHandleror a plugin, and register Helmet yourself with a policy that fits.