<div align="center">
<h1>dioxus-code</h1>
<p><strong>Syntax-highlighted code blocks for Dioxus.</strong></p>
</div>
<div align="center">
<a href="https://crates.io/crates/dioxus-code">
<img src="https://img.shields.io/crates/v/dioxus-code.svg?style=flat-square" alt="Crates.io version" />
</a>
<a href="https://crates.io/crates/dioxus-code">
<img src="https://img.shields.io/crates/d/dioxus-code.svg?style=flat-square" alt="Downloads" />
</a>
<a href="https://docs.rs/dioxus-code">
<img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square" alt="docs.rs" />
</a>
</div>
---
A small Dioxus component for rendering source code with proper highlighting. Parsing is powered by [arborium](https://crates.io/crates/arborium); themes ship as scoped CSS so you can mix several on one page.
Two ways to highlight:
- **[`code!`] macro** — parses at compile time and embeds the highlighted spans. Default.
- **[`SourceCode`]** — parses at runtime. Opt in with the `runtime` feature for dynamic source text.
## Quick start
```toml
[dependencies]
dioxus-code = "0.1"
```
```rust
use dioxus::prelude::*;
use dioxus_code::{Code, Theme, code};
#[component]
fn ReadMe() -> Element {
rsx! {
Code {
src: code!("/snippets/demo.rs"),
theme: Theme::TOKYO_NIGHT,
}
}
}
```
The path is resolved from the consumer's `CARGO_MANIFEST_DIR`. `concat!` and `env!` work too.
When the file extension is ambiguous, pass [`CodeOptions::builder`] with [`CodeOptions::with_language`].
## Runtime highlighting
For editor-style use cases with dynamic source text:
```toml
[dependencies]
dioxus-code = { version = "0.1", features = ["runtime"] }
```
```rust
# use dioxus::prelude::*;
use dioxus_code::{Code, Language, SourceCode, Theme};
# let user_input = String::new();
# let _ =
rsx! {
Code {
src: SourceCode::new(Language::Rust, user_input),
theme: Theme::GITHUB_LIGHT,
}
}
# ;
```
Pass a [`Language`] variant when building [`SourceCode`]. The `runtime` feature includes Rust; enable the matching `lang-*` feature, or `all-languages`, for additional grammars.
## Editor
[`dioxus-code-editor`] is a sibling crate that pairs the highlighter with a textarea input layer:
```rust
# use dioxus::prelude::*;
use dioxus_code_editor::{CodeEditor, Language};
use dioxus_code::Theme;
# fn editor() -> Element {
let mut source = use_signal(|| String::new());
rsx! {
CodeEditor {
value: source(),
language: Language::Rust,
theme: Theme::TOKYO_NIGHT,
oninput: move |value| source.set(value),
}
}
# }
```
It is controlled — drive [`CodeEditorProps::value`] from your own signal and update it inside [`CodeEditorProps::oninput`].
## Themes
Thirty-odd built-ins, including Tokyo Night, Catppuccin (all four), Dracula, GitHub Light/Dark, Gruvbox, Nord, One Dark, Rosé Pine, Solarized, the Rustdoc themes, and others. Each is exposed as a [`Theme`] constant; pages with multiple themes render side-by-side without leaking styles.
```rust
# use dioxus::prelude::*;
# use dioxus_code::{Code, Theme, code};
# let _ = rsx! {
Code { src: code!("/snippets/demo.rs"), theme: Theme::CATPPUCCIN_MOCHA }
# };
```
Use [`CodeTheme::system`] to select a light and dark theme with CSS media
queries. This is JavaScript-free and works during SSR:
```rust
# use dioxus::prelude::*;
use dioxus_code::{Code, CodeTheme, Theme, code};
# let _ = rsx! {
Code {
src: code!("/snippets/demo.rs"),
theme: CodeTheme::system(Theme::GITHUB_LIGHT, Theme::TOKYO_NIGHT),
}
# };
```
## Examples
```sh
dx serve --example dioxus-code-basic # macro + runtime side by side
dx serve --example dioxus-code-macro-only # compile-time highlighted spans
dx serve --example dioxus-code-live-input # textarea bound to runtime highlighter
```
## Workspace layout
| [`dioxus-code`] | The [`Code`] component, themes, and runtime/macro entry points. |
| [`dioxus-code-editor`] | Editable code surface built on [`Code`]. |
| [`dioxus-code-macro`] | Implementation of [`code!`]. Re-exported by [`dioxus-code`] under the `macro` feature. |
## License
MIT. See the repository `LICENSE` file.
[`code!`]: https://docs.rs/dioxus-code/latest/dioxus_code/macro.code.html
[`Code`]: https://docs.rs/dioxus-code/latest/dioxus_code/fn.Code.html
[`CodeEditorProps::oninput`]: https://docs.rs/dioxus-code-editor/latest/dioxus_code_editor/struct.CodeEditorProps.html#structfield.oninput
[`CodeEditorProps::value`]: https://docs.rs/dioxus-code-editor/latest/dioxus_code_editor/struct.CodeEditorProps.html#structfield.value
[`CodeOptions`]: https://docs.rs/dioxus-code/latest/dioxus_code/struct.CodeOptions.html
[`CodeOptions::builder`]: https://docs.rs/dioxus-code/latest/dioxus_code/struct.CodeOptions.html#method.builder
[`CodeOptions::with_language`]: https://docs.rs/dioxus-code/latest/dioxus_code/struct.CodeOptions.html#method.with_language
[`CodeTheme::system`]: https://docs.rs/dioxus-code/latest/dioxus_code/struct.CodeTheme.html#method.system
[`dioxus-code`]: https://crates.io/crates/dioxus-code
[`dioxus-code-editor`]: https://crates.io/crates/dioxus-code-editor
[`dioxus-code-macro`]: https://crates.io/crates/dioxus-code-macro
[`SourceCode`]: https://docs.rs/dioxus-code/latest/dioxus_code/struct.SourceCode.html
[`Theme`]: https://docs.rs/dioxus-code/latest/dioxus_code/struct.Theme.html