Back to News & Insights
Web Development October 4, 2026 ยท 6 min read

๐Ÿ–ฅ๏ธ Code RS: CDN-Free Syntax-Highlighted Code Components for WASM

Privyet ๐Ÿ‘‹! You know that moment when you paste a <pre><code> block into your app and...

๐Ÿ–ฅ๏ธ Code RS: CDN-Free Syntax-Highlighted Code Components for WASM

You know that moment when you paste a block into your app and it looks like it was styled in 2003 by someone who had just discovered color: green? No theme. No copy button. No language badge. Just raw, uncolored text sitting in a box that someone called "good enough"?

Code RS is a production-ready, fully-themed, accessible code display component for Yew, Dioxus, and Leptos. It does everything the ecosystem was missing: Inline : colored, sized, variant-aware, with ARIA semantics. *: a composable container with header, title, language badge, copy trigger, and scrollable content area. Pure-Rust syntax highlighting: zero CDN, zero JavaScript, compiles to clean WASM, 20+ languages. 8 built-in themes: OneDark, Dracula, NightOwl, GitHub Dark/Light, Solarized, Monokai, Nord, all switchable via a single theme prop.

No Prism.js. No highlight.js. No 10MB script tag loaded from a CDN you definitely trust completely. Just Rust, bytes, and inline style= spans.

Here's the thing about syntax highlighting in WASM apps: every existing solution assumes JavaScript. Prism.js needs a DOM. highlight.js needs a runtime. Shiki needs Node. Tree-sitter is great, but it weighs as much as a sedan.

The highlightcode(code, lang, theme) function in common.rs is a hand-rolled, char-by-char tokenizer that handles: Block comments (/ /), single-line comments (//, #, --) Double/single-quoted strings and JS template literals Hex and float number literals with suffixes (0xFF, 1.0f32) Rust macros (println!, vec!) Python/CSS decorators (@dataclass, @media) HTML tag names (, ) PascalCase โ†’ type, ALLCAPS โ†’ constant, ident( โ†’ function call Language-specific keyword sets (Rust, Python, TypeScript, SQL, Bash, 16 more)

All token spans get inline style= attributes from the chosen theme. No CSS classes. No external stylesheet. Just fn, and it works everywhere, including iframes and shadow DOM.

Variants work exactly as you'd expect from the rest of Open SASS Kit: Solid, Subtle, Outline, Surface, Plain. Colors are the full palette: Default, Red, Orange, Yellow, Green, Teal, Accent, Pink, Success, Warning, Danger, and Custom("your-inline-css").

The Block pushes a BlockContext containing code, language, and theme into a provider tree. All child components read from context. Content calls highlightcode and injects the result via innerhtml / dangerousinnerhtml / Html::fromhtmlunchecked, the framework-appropriate unsafe-but-correct escape hatch for pre-rendered HTML. No prop drilling. No callback chains. Just context.

| Theme | Background | Vibe | | ------------- | ---------- | ---------------------------------------- | | OneDark | #1a1a2e | The classic. Atom's gift to the world. | | Dracula | #282a36 | Halloween every day. Pink keywords. | | NightOwl | #011627 | Deep blue, warm salmon numbers. | | GithubDark | #0d1117 | Feels like GitHub, because it is. | | GithubLight | #ffffff | For those who dare use light mode. | | Solarized | #002b36 | Ethan Schoonover's gift to the terminal. | | Monokai | #272822 | The Sublime Text nostalgia trip. | | Nord | #2e3440 | Arctic. Clean. Borderline peaceful. |

Switch themes at runtime by simply changing the theme prop. The ThemeColors struct drives inline style generation, every pushspan() call pulls the exact CSS value from the active theme's fields.

Need your brand colors? Theme::Custom(ThemeColors { keyword: "color:#ff0099;font-weight:600", ... }) and you're done.

We are not going to pretend this was a relaxing weekend project. Here is an honest accounting.

Rust Edition 2024 changed how string-like identifiers in macro positions are parsed. The yew::html! macro started rejecting class names like text-black and whitespace-pre, specifically the hyphen-adjacent tokens that look like prefix expressions.

The error: prefix 'black' is unknown. The fix: add a trailing space after the class name. Simple, but it wasted an embarrassing amount of time because the error message looks nothing like what it actually is.

Explodes with Failed to parse formatted segment: Expected Ident or Exp. Because { inside a string prop is format syntax to Dioxus, not a literal curly brace.

In Dioxus, dangerousinnerhtml takes ownership of a String. In Leptos, innerhtml takes a &str. In Yew, Html::fromhtmlunchecked takes an AttrValue. Three frameworks, three signatures, three slightly different ways to inject a pre-rendered HTML string.

Each one worked fine once you knew the exact type expected. Getting there required reading the framework source, not the docs, because the docs had helpfully omitted the borrow semantics.

Adding Custom(&'static str) to the Variant enum immediately broke every match in all three Code component implementations. Expected. Annoying. The fix is the following:

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation