---
package: "@webjsdev/server"
version: 0.8.0
date: 2026-05-29T09:22:01.876Z
commit_count: 11
---
## Breaking

- **jspm.io direct vendor (Rails-style no-build)** ([#89](https://github.com/webjsdev/webjs/pull/89)) [`988b37b`](https://github.com/webjsdev/webjs/commit/988b37b)
  * feat(server): tighten bare-import scanner to exclude server-only files and false positives
  
  The vendor scanner picked up server-only imports from contexts that
  never reach the browser, generating spurious vendor pipeline work

## Features

- **multi-CDN pin (--from), audit/outdated/update, data-webjs-track reload** ([#105](https://github.com/webjsdev/webjs/pull/105)) [`4db2360`](https://github.com/webjsdev/webjs/commit/4db2360)
  * feat(vendor): Rails-importmap-rails CLI parity (--from, audit, outdated, update)
  
  Closes the four real-Rails gaps the parity review surfaced:
- **auto-load <appDir>/.env at server boot** ([#107](https://github.com/webjsdev/webjs/pull/107)) [`a9a97a4`](https://github.com/webjsdev/webjs/commit/a9a97a4)
  Tracker #37. Scaffolded apps ship a .env.example that users copy to
  .env, but `webjs dev` / `webjs start` never read the file. Booting
  the SaaS scaffold failed with `createAuth() requires a 'secret'`
  because lib/auth.server.ts calls `createAuth({ secret:
- **publish-time esbuild bundles in dist/ alongside src/** ([#117](https://github.com/webjsdev/webjs/pull/117)) [`6dd0360`](https://github.com/webjsdev/webjs/commit/6dd0360)
  * feat(core): publish-time esbuild bundles in dist/ alongside src/
  
  Acceptance criterion 1 + 2 of #113.
- **split browser-only entry from index, drop server modules** ([#128](https://github.com/webjsdev/webjs/pull/128)) [`0c8cb31`](https://github.com/webjsdev/webjs/commit/0c8cb31)
  * feat(core): split browser-only entry from index, drop server modules
  
  @webjsdev/core's index.js re-exported renderToString,
  renderToStream, expose, getExposed, and setCspNonceProvider
- **add display-only component elision analyser** [`0eb958c`](https://github.com/webjsdev/webjs/commit/0eb958c)
  The analyser decides whether a component module can be elided from the
  browser (SSR'd HTML is the complete output, no client work). It is a
  conservative denylist of interactivity signals: anything unrecognised
  ships. The signal lists are the single source of truth, enforced by a
- **elide display-only component imports from served modules** [`14e0bd1`](https://github.com/webjsdev/webjs/commit/14e0bd1)
  Compute the elidable-component set at boot and on rebuild, then strip
  side-effect imports of those components from served browser modules so
  the browser never downloads their JS. The modulepreload hint was only a
  waterfall optimisation; the static import in page/component source is
- **drop elided components from preloads and importmap** [`8817223`](https://github.com/webjsdev/webjs/commit/8817223)
  Filter display-only components out of modulepreload hints (and the
  subtree reachable only through them, via a skip set on transitiveDeps),
  and exclude vendor specifiers imported only by elided components from
  the importmap by scanning bare imports after the elision set is known.
- **add `webjs.elide: false` opt-out switch**
  Project-level escape hatch. Setting `{ "webjs": { "elide": false } }` in
  package.json skips the elision analysis entirely (everything ships, like
  before the feature). Pure opt-out, re-read on every rebuild, default on.

## Fixes

- **detect module-scope client work by an allowlist of safe top-level forms**
  Elision's "does this module do client work at load" check is an allowlist
  (top level may only declare and register; any other top-level call, `new`,
  dynamic `import()`, or `await` ships) instead of a denylist of browser
  global names. This closes false-elision holes (a module-scope `fetch`,
  `new WebSocket`, or dynamic `import()` was wrongly elided) and does not rot
  as browsers add APIs.
- **hand-rolled lexer tracks regex literals and nested template interpolation**
  `redactStringsAndTemplates` is now a proper lexer. Regex literals are
  delimited by the standard regex-versus-division rule and their bodies
  blanked, and template literals are tracked with full `${...}` nesting, so a
  quote or brace inside a regex, or a nested `` html`...${html`...`}` ``, can
  no longer desync the scanner and cause a false elision verdict.
- **template-literal-aware scanner eliminates 9 false positives** ([#109](https://github.com/webjsdev/webjs/pull/109)) [`f411477`](https://github.com/webjsdev/webjs/commit/f411477)
  * fix(check): redact template literals before scanning to remove 9 false positives
  
  The check rules scan source via regex. Docs pages render code examples
  inside html`...` template literals, and test files write fixture
- **scope source serving to the browser-bound module graph** ([#111](https://github.com/webjsdev/webjs/pull/111)) [`07271fb`](https://github.com/webjsdev/webjs/commit/07271fb)
  * fix(server): scope source serving to the browser-bound module graph
  
  Webjs's dev server previously served any file under appDir whose path
  ended in a known extension (.js, .ts, .json, .svg, …) with only
- **add trustProxy option; default to socket-stamped IP** ([#116](https://github.com/webjsdev/webjs/pull/116)) [`3ddb5ad`](https://github.com/webjsdev/webjs/commit/3ddb5ad)
  * fix(rate-limit): add trustProxy option; default to socket-stamped IP
  
  Closes #114.
