#4059·marko

Component re-exported from a .ts module breaks hydration in production builds (crash with a sibling event handler, silently dead without)

Author: svalloryCreated Aug 25, 2026Updated Aug 25, 2026

[!NOTE] Issue text and repro written by Claude (AI); every result personally verified by me in a real browser.

Using a component that is re-exported from a TypeScript file breaks client hydration — but only in production builds (marko-run build). The dev server is fine.

Repro repo: https://github.com/svallory/marko-run-dynamic-tag-repro — the whole app is three files:

typescript
// src/manifest.ts
export { default as Demo } from "./demo.marko";
marko
// src/demo.marko
<let/count=0>
<button onClick() { count++ }>Button (clicked ${count} times)</button>
marko
// src/routes/+page.marko
import { Demo } from "../manifest.ts";

<Demo/>
<button onBlur=() => {}>another button</button>

bun run build && bun run start, open /. Two scenarios:

  1. Just <Demo/> (remove the second button): no error — but the Demo button is dead. No client bundle is emitted for the route at all (0.0 kB).
  2. With any other tag carrying an event handler (an inert onBlur=() => {} is enough): the console throws on load and nothing hydrates:
TypeError: effects[(i++)] is not a function
    at runEffects
    at runResumeEffects
    at init
    at initEmbedded

(stack from a minify: false + sourcemaps build — the crash is identical minified)

One-line fix/workaround: import the component directly — import Demo from "../demo.marko"; — identical HTML, everything hydrates.

Scenario 2 reproduces without @marko/run: the repo's plain/ variant (plain @marko/vite, ~25-line build+serve harness) throws the identical error — which is why this is filed here rather than at marko-js/run (originally marko-js/run#266, closed in favor of this issue). Scenario 1 (silently emitting no client bundle) is the @marko/run-specific symptom of the same import shape. Neither reproduces in the dev server or the Marko playground (unoptimized compiles).

Versions (all verified): marko 6.3.35 and 6.3.45 (latest), @marko/run 0.11.9 and 0.11.12 (latest), @marko/vite 6.1.9/6.1.11, vite 8, Node 22/26, macOS.