name: markstream-install
description: Install and wire markstream-vue, markstream-react, markstream-vue2, markstream-angular, or markstream-svelte into an existing repository. Use when Codex needs to choose the right package, install the smallest peer-dependency set, fix CSS/reset order, choose Vue 3 renderer mode, decide between content, nodes, and Vue 3 virtual-scroll coordination, or add a minimal working renderer example.
Markstream Install
Use this skill when the task is "add markstream to an app" or "fix a broken markstream install".
Read references/scenarios.md before making dependency choices.
Workflow
- Detect the target framework and CSS stack.
- Check
package.json, app entry files, Tailwind or UnoCSS config, and whether the repo is SSR or streaming-focused. - Choose the package that matches the host app:
markstream-vue,markstream-vue2,markstream-react,markstream-angular, ormarkstream-svelte. - Use
markstream-svelteonly for Svelte 5 apps.
- Check
- Install the smallest peer set that matches the requested features.
- Add peers only for features the user actually needs: Monaco, Mermaid, D2, KaTeX, or lightweight highlighting via
stream-markdown. - Do not install every optional peer by default.
- For Vue 3 Monaco preloading, use
preloadCodeBlockRuntimefrommarkstream-vueso the renderer runtime knows Monaco is warm. ExistinggetUseMonaco()calls are still compatible.
- Add peers only for features the user actually needs: Monaco, Mermaid, D2, KaTeX, or lightweight highlighting via
- Fix CSS order.
- Put reset styles before Markstream styles.
- In Tailwind or UnoCSS projects, use
@import 'markstream-*/index.css' layer(components);. - Do not rely on renderer imports to inject CSS; import the package CSS subpath explicitly.
- Import
katex/dist/katex.min.csswhen math is enabled.
- Add the smallest working render example.
- Use
contentfor static or low-frequency rendering. - In Vue 3 apps with long AI conversations, thread restore, or an existing message virtualizer such as
vue-virtual-scroller, do not stop at a trivial renderer. UseMarkstreamVirtualTimelineoruseMarkstreamVirtualAdapter()and followdocs/guide/performance.md. - For Vue 3, choose renderer
modeby surface before tuning lower-level props.mode="chat": AI chat or SSE output; lightweight batches,<pre>code rendering by default,fade=false,max-live-nodes=0, andsmooth-streaming="auto".mode="docs": rich document surfaces; default mode, larger batches, tooltips, fade, and Monaco-backed code blocks when the peer is installed.mode="minimal": lightweight non-chat surfaces.- If a docs page does not need Monaco-backed code blocks, set
:render-code-blocks-as-pre="true".
- For streaming AI chat in other Markstream packages, start with
contentand built-in smooth streaming.- Auto mode is the default:
smoothStreaming="auto"/smooth-streaming="auto". - Auto pacing activates when
typewriter=trueormaxLiveNodes <= 0/max-live-nodes <= 0. typewriteronly controls the blinking cursor and defaults tofalse.fadecontrols node enter and streamed-text fade animations and defaults totrue.- For high-frequency smooth streams, consider
fade=false/:fade="false"/[fade]="false"to avoid fade stacking.
- Auto mode is the default:
- Streaming vs recovering history: in chat UIs the same renderer starts streaming and later switches to history when
finalbecomestrue.- Vue 3 streaming:
mode="chat",smooth-streaming="auto",:fade="false",typewriter=true. - Vue 3 recovering/completed chat history: keep
mode="chat"on the same chat row; use:smooth-streaming="false",typewriter=false, and only set:fade="true"when the host explicitly wants a history-entry animation. - Use
mode="minimal"for lightweight non-chat recovered content, and usemode="docs"only for rich document surfaces. - Other packages streaming:
smoothStreaming="auto"/smooth-streaming="auto",fade=false,typewriter=true. - Other packages recovering history:
smoothStreaming=false/smooth-streaming=false,fade=true,typewriter=false. - Dynamic switch:
smoothStreaming={isStreaming ? 'auto' : false},fade={!isStreaming}.
- Vue 3 streaming:
- Use
nodes+finalonly for worker preparsing, shared AST stores, or custom AST control. - For manual pacing with
nodes, useuseSmoothMarkdownStream:enqueue()chunks,finish()when done, render fromvisible, wait forcaughtUpbefore final parsing. - Preserve the default hardening: HTML policies now default to
safe, and Mermaid runs in strict mode by default.
- Use
- Keep customization scoped.
- If the task requires overrides, prefer
customId/custom-idplus scopedsetCustomComponents(...).
- If the task requires overrides, prefer
- Validate.
- Run the smallest relevant build, typecheck, test, or docs build command.
- Report which peers were installed, where CSS lives, and whether the repo should later adopt
nodes.
Default Decisions
- Prefer the minimal peer set over "install everything".
- For Vue 3, omit
modeonly when the surface should use rich docs defaults. - Prefer
contentfor most streaming chat now that built-in smooth streaming is available across Vue 3, Vue 2, React, Svelte, and Angular. - Move to
nodesonly when another layer owns parsing or AST transforms. - For Vue 3 apps that already virtualize messages, keep the outer virtualizer responsible for mounted rows; use Markstream virtual-scroll coordination so item height comes from
metrics.totalHeight, not the renderer DOM height. - When using
contentfor streaming, smooth streaming (smooth-streaming="auto") is on by default fortypewriterormax-live-nodes <= 0. Set:smooth-streaming="false"to preserve raw chunk cadence. - Streaming vs recovering history: when a chat message transitions from streaming to history, keep the renderer mode stable and switch props dynamically —
smooth-streaming="auto",fade=falsefor streaming;smooth-streaming=false, optionalfade=truefor history. Seedocs/guide/ai-chat-streaming.mdfor full examples. - Treat CSS order as a first-class part of installation, not a later cleanup.
- When the request includes SSR, explicitly gate browser-only peers behind client-only boundaries.
- Do not widen HTML or Mermaid security defaults unless the user explicitly needs trusted legacy compatibility.
- If compatibility requires it, scope the opt-out to the trusted surface with
htmlPolicy/html-policy="trusted"andmermaidProps.isStrict = falseinstead of changing app-wide defaults blindly.
Useful Doc Targets
docs/guide/installation.mddocs/guide/usage.mddocs/guide/performance.mddocs/guide/troubleshooting.mddocs/guide/component-overrides.md