Bring Your Own Stack: A Truly Framework Agnostic Widget
Why we rejected NPM packages and React wrappers in favor of a universal HTML drop-in.

When building a third-party integration, the industry standard is to release a suite of NPM packages: @markreply/react, @markreply/vue, @markreply/svelte.
We took a different path. MarkReply is 100% framework agnostic, requiring zero build steps, zero package managers, and zero bundle-size bloat.
💥 The Problem with NPM Wrappers
Shipping framework-specific packages creates immediate technical debt for both the maintainer and the consumer:
- Version conflicts: Your site uses React 18, but the widget demands React 19.
- Bundle Bloat: You are forced to ship duplicate dependencies to the client.
- Fragility: Every major framework update requires a refactor of the widget wrapper.
💡 The Universal HTML Solution
Because the MarkReply engine is powered by Rust and HTMX, the client browser only needs to know how to render raw HTML. You don’t need a virtual DOM to display a comment thread.
To embed MarkReply on any site—whether it is built with Astro, Next.js, Hugo, WordPress, or just plain HTML—you simply drop in two lines of code where you want the comments to appear:
<div id="markreply-comments"></div><script src="https://comments.example.com/widget.js" async></script>That single, asynchronous script handles everything: injecting the lightweight CSS, pulling in HTMX, and dynamically rendering the comment thread for that specific URL.
✅ Styling Made Simple
Because the widget renders native HTML directly into your DOM (no restrictive <iframe>), it automatically inherits your site’s typography.
If you want to customize the colors, you don’t need to pass massive configuration objects through JavaScript. You just override our CSS variables in your own stylesheet:
:root { --markreply-bg: #111111; --markreply-text: #f3f4f6; --markreply-primary: #6366f1;}It works everywhere you can paste a <div>.