
Research
Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.
semantic-renderer
Advanced tools
Intelligent LLM response renderer that detects semantic intent (comparisons, steps, pros/cons, code explanations, tables, emails, verdicts) and renders with purpose-built visual components instead of generic markdown.
Intelligent LLM response renderer that detects the semantic intent of markdown responses and renders them with purpose-built visual components — not just "better markdown", but context-aware layouts.
A comparison response renders as side-by-side cards. A step-by-step guide renders as an interactive stepper. Pros and cons render as a green/red two-column layout. All automatically detected — zero prompt engineering required.
| Type | Trigger | Visual |
|---|---|---|
| Pros & Cons | Headings/bold with "pros/advantages" + "cons/disadvantages" | Two-column green/red layout with check/X icons |
| Comparison | 2+ ### headings with bullet lists, or "vs"/"versus" | Side-by-side entity cards with colored headers |
| Steps | Ordered lists with 3+ items, or "Step N"/"Phase N" headings | Vertical stepper with numbered circles and expand/collapse |
| Code + Explanation | Single fenced code block + 2+ paragraphs of prose | Split view — code panel (55%) + explanation panel (45%) |
| Data Table | GFM table with 3+ rows and 3+ columns | Sortable, filterable table with row count |
| Subject/To/From lines, greeting ("Dear X"), sign-off ("Best regards,") | Email card with fields, body, signature, copy button | |
| Verdict | Heading matching "verdict/conclusion/recommendation/summary/tldr" | Accent-bordered card with icon |
| Default | Everything else | Your existing markdown renderer (unchanged) |
npm install semantic-renderer
import { SemanticRenderer } from 'semantic-renderer/react';
import 'semantic-renderer/react/styles.css';
function ChatMessage({ content, isStreaming }) {
return (
<SemanticRenderer
content={content}
isStreaming={isStreaming}
/>
);
}
That's it. The component classifies the markdown and picks the right renderer automatically. During streaming, it bypasses classification and renders plain markdown — zero risk to your streaming UX.
The React entry point uses these (you likely already have them):
{
"react": ">=18.0.0",
"react-dom": ">=18.0.0",
"react-markdown": ">=9.0.0",
"framer-motion": ">=10.0.0",
"lucide-react": ">=0.300.0"
}
All are optional — the core classifier has zero dependencies.
<SemanticRenderer /> (React)interface SemanticRendererProps {
/** The markdown content to render */
content: string;
/** Skip classification — render as plain markdown (useful for streaming) */
isStreaming?: boolean;
/** CSS class for the wrapper div */
className?: string;
/** Custom markdown renderer component (defaults to react-markdown) */
fallback?: React.ComponentType<{ content: string }>;
}
classify() (Core — framework-agnostic)import { classify } from 'semantic-renderer';
const blocks = classify(markdownString);
// Returns: SemanticBlock[]
// Each block has: { id, type, rawMarkdown, meta }
Use this if you want to build your own renderers (React Native, Vue, Svelte, etc.) on top of the classification engine.
type SemanticBlockType =
| 'comparison' // meta: ComparisonMeta
| 'steps' // meta: StepsMeta
| 'pros-cons' // meta: ProsConsMeta
| 'code-explanation' // meta: CodeExplanationMeta
| 'data-table' // meta: DataTableMeta
| 'email' // meta: EmailMeta
| 'verdict' // meta: VerdictMeta
| 'default'; // meta: {}
The default styles use CSS custom properties. Override them to match your app:
:root {
--sem-accent: #6366f1; /* Primary accent (stepper circles, borders) */
--sem-border: #e5e7eb; /* Border color */
}
Or in dark mode:
.dark {
--sem-accent: #818cf8;
--sem-border: #374151;
}
If you already have a custom markdown component, pass it as fallback:
import { SemanticRenderer } from 'semantic-renderer/react';
import 'semantic-renderer/react/styles.css';
import { MyMarkdownRenderer } from './MyMarkdownRenderer';
// Your component must accept a `content` string prop
const MyFallback = ({ content }) => <MyMarkdownRenderer source={content} />;
<SemanticRenderer content={content} fallback={MyFallback} />
The fallback is used for:
isStreaming is true)You can also import renderers individually:
import { classify } from 'semantic-renderer';
import { ProsConsRenderer, VerdictRenderer } from 'semantic-renderer/react';
import 'semantic-renderer/react/styles.css';
const blocks = classify(content);
blocks.map(block => {
if (block.type === 'pros-cons') return <ProsConsRenderer block={block} Fallback={MyMarkdown} />;
if (block.type === 'verdict') return <VerdictRenderer block={block} Fallback={MyMarkdown} />;
return <MyMarkdown content={block.rawMarkdown} />;
});
##/### headingsThe classifier is pure TypeScript with zero dependencies — no ML models, no API calls, no parsing libraries. Just regex heuristics tuned on real LLM output patterns.
Every renderer validates its metadata before rendering. If anything is malformed, it falls back to your markdown renderer with the original text. You'll never see a broken layout — worst case, you see the same markdown you'd see without this package.
Ask any LLM these prompts to see each renderer in action:
const debounce = (fn, ms) => { let t; return (...a) => { clearTimeout(t); t = setTimeout(() => fn(...a), ms); }; }"Coming soon — animated demo of all 7 block types.
MIT - Sagar Kalra / AutoPriseAI
FAQs
Intelligent LLM response renderer that detects semantic intent (comparisons, steps, pros/cons, code explanations, tables, emails, verdicts) and renders with purpose-built visual components instead of generic markdown.
We found that semantic-renderer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.