0.18.0
Changelog: v0.18.0
Release date: 2026-05-17
Release type: minor (new capability, backward compatible)
Overview
v0.18.0 implements the Universal WC Engine Admission Layer, enabling LessJS to safely accept third-party Web Component packages through a validated compatibility model. Previously, LessJS could not distinguish between SSR-capable and client-only third-party packages, leading to potential runtime failures.
Complete SOP Steps
Step 1: CEM Parser ✅
Added packages/core/src/cem-parser.ts — parses standard custom-elements.json without executing package code:
- Extracts tag names, module paths, exports, attributes, events, slots, CSS parts, and CSS custom properties
- Preserves unknown CEM fields for future compatibility
- Rejects invalid tag names and unresolved module paths
- Detects duplicate tags before SSR registration
- 19 tests passing
Step 2: Compatibility Classifier ✅
Added packages/core/src/compatibility.ts — 4-tier classification engine:
| Tier | Meaning | Build behavior |
|---|---|---|
ssr-capable |
Explicit Less manifest or adapter says SSR supported | Import/register in SSR bundle |
client-only |
Browser-only package or no SSR declaration | Exclude from SSR bundle |
rejected |
Invalid manifest, duplicate tag, unsafe path | Fail before code generation |
experimental-dom |
Opt-in DOM simulation candidate | Render only when explicit flag enabled |
Conservative defaults: CEM without Less extension → client-only (not SSR). 29 tests passing.
Step 3: SSR/client-only Planner ✅
Updated packages/adapter-vite/src/entry-descriptor.ts:
buildSsrAdmissionPlan()now acceptsCompatibilityClassification[]- CEM classifications take precedence over island metadata
SsrAdmissionPlan.cemClassificationsfield added- 18 tests passing (9 new + 9 existing)
Step 4: Report Schema Extension ✅
packages/core/src/types.ts—CemCompatibilityReportinterface added toDsdBuildReportpackages/adapter-vite/src/cli/ssg-render.ts—buildCemCompatibilityReport()builderpackages/adapter-vite/src/build-context.ts—Phase1Meta.cemClassificationsfield- Report schema version bumped to 1.1.0
cemCompatibilitysection indsd-report.json
Step 5: Fixtures and Tests ✅
- 4 new tests for CEM compatibility in
ssg-report.test.ts - 6 new tests for CEM auto-detection in
route-scanner.test.ts - Total: 630 tests passing
CEM Plugin Integration ✅
Completed the "last mile" integration that was missing from the original SOP:
packages/adapter-vite/src/route-scanner.ts—scanCemManifests()+detectAndClassifyCemPackages()- Scans
node_modulesforcustom-elements.jsonwithout executing package code - Handles scoped packages (
@org/pkg), skips invalid JSON (non-fatal) - Calls
parseCem()+classifyCemManifest()pipeline
- Scans
packages/adapter-vite/src/index.ts—buildStart()now callsdetectAndClassifyCemPackages()- Stores results in
ctx.phase1.cemClassifications - Passes
cemClassificationstobuildEntryDescriptor() - Failure is non-fatal (best-effort, debug log only)
- Stores results in
packages/core/deno.json— added./compatibilitysubpath export
Package Version Update
Updated all 12 packages from 0.17.5 to 0.18.0:
@lessjs/core✅@lessjs/adapter-lit✅@lessjs/adapter-react✅@lessjs/adapter-vanilla✅@lessjs/adapter-vite✅@lessjs/app✅@lessjs/content✅@lessjs/create✅@lessjs/i18n✅@lessjs/rpc✅@lessjs/signals✅@lessjs/ui✅
Note: Inter-package dependencies use ^0.17.0 (caret range), so 0.18.0 is automatically compatible.
Verification
- All 5 SOP items implemented
- CEM plugin integration complete
- 630 tests passing
-
deno task fmt:check && deno task lint && deno task typecheck - Committed and pushed to
origin/dev
Breaking Changes
None. This is a minor release that adds:
- New CEM parsing capability
- New compatibility classification tiers
- New report schema extensions
- No API changes
- No behavior changes (conservative defaults preserve existing behavior)
Migration Guide
For users: No action needed. v0.18.0 is a drop-in replacement for v0.17.5.
For third-party Web Component authors:
- If your package has a
custom-elements.json, it will now be auto-detected - By default, your components are treated as client-only (not SSR)
- To enable SSR: add a LessJS manifest with
ssr: trueor use a supported adapter
For contributors:
- When adding new compatibility tiers, update
packages/core/src/compatibility.ts - When modifying CEM parsing, update
packages/core/src/cem-parser.ts - Run
deno task testto verify compatibility classification
Next Steps
With v0.18.0 complete, the project can now proceed to:
- v0.18.1:
less validate-manifestCLI built on top of the classifier - See
docs/sop/v0.18.1-validate-manifest-cli.md(to be created)
Diff Summary
git diff --stat v0.17.5..v0.18.0
packages/core/src/cem-parser.ts (new)
packages/core/src/compatibility.ts (new)
packages/core/src/types.ts (CEM types added)
packages/adapter-vite/src/entry-descriptor.ts (cemClassifications support)
packages/adapter-vite/src/entry-renderer.ts (cemClassifications support)
packages/adapter-vite/src/route-scanner.ts (CEM auto-detection)
packages/adapter-vite/src/build-context.ts (Phase1Meta.cemClassifications)
packages/adapter-vite/src/cli/ssg-render.ts (cemCompatibility report)
packages/adapter-vite/__tests__/ssr-admission.test.ts (18 tests)
packages/adapter-vite/__tests__/route-scanner.test.ts (CEM tests)
packages/adapter-vite/__tests__/ssg-report.test.ts (CEM report tests)
packages/core/deno.json (version bump + ./compatibility export)
packages/adapter-lit/deno.json (version bump)
packages/adapter-react/deno.json (version bump)
packages/adapter-vanilla/deno.json (version bump)
packages/adapter-vite/deno.json (version bump)
packages/app/deno.json (version bump)
packages/content/deno.json (version bump)
packages/create/deno.json (version bump)
packages/i18n/deno.json (version bump)
packages/rpc/deno.json (version bump)
packages/signals/deno.json (version bump)
packages/ui/deno.json (version bump)Stats:
- 25+ files changed
- 2 new core modules (cem-parser, compatibility)
- 630 tests passing
- 12 version bumps
Consumer-Level Explanation (Simple Analogies)
What was the problem?
Imagine you're building a house, and you can use materials from:
- Local suppliers (your own components) — you know exactly how they work
- Third-party suppliers (npm packages) — you don't know if they work in SSR or only in browser
Previously, LessJS treated all third-party Web Components as potentially SSR-safe, which could cause runtime failures if a component tried to access browser APIs during server-side rendering.
What did we do in v0.18.0?
-
Added a "material inspector" (CEM Parser)
- Reads the "spec sheet" (
custom-elements.json) for each third-party package - Understands what the component is and what it needs
- Reads the "spec sheet" (
-
Added a "classification system" (Compatibility Classifier)
- SSR-capable: safe for server rendering
- Client-only: must run in browser only
- Rejected: broken or unsafe
- Experimental: needs opt-in
-
Added "automatic detection" (CEM Plugin Integration)
- Scans your
node_modulesfor Web Component packages - Classifies them automatically
- No configuration needed
- Scans your
-
Added "reporting" (Report Schema Extension)
- Every decision is logged in
dsd-report.json - You can see exactly why each component was classified
- Every decision is logged in
Why should you care?
-
If you're a user: Your builds are now safer. Third-party components that don't support SSR are automatically excluded from the SSR bundle, preventing runtime failures.
-
If you're a library author: Add a
custom-elements.jsonto your package. By default, it's treated as client-only (safe). Add LessJS metadata to enable SSR if your component supports it.
Analogy Summary
Before v0.18.0: "I hope all these third-party materials work on the server."
After v0.18.0: "Here's exactly which materials are safe for server, which need browser, and why. No more guessing."