Make the code examples in your Docusaurus docs runnable, in 46 languages
Most docs have the same problem with code examples. The reader copies the snippet, opens a terminal or a playground in another tab, pastes it, fixes the indentation, and only then finds out what it does. Many give up before that. Docusaurus has a fix for React: @docusaurus/theme-live-codeblock turns a jsx live block into a live editor. But it only renders JSX in the browser. If your docs show Python, Go, C++, SQL or anything that isn't a React component, you're back to copy and paste. So I built a small plugin for that: docusaurus-plugin-onlinecompiler. You add one word to an ordinary code block, and readers get an editor with a Run button right in the page. The code runs on OnlineCompiler.io (I build it), in a fresh sandbox for each run with no network access. Nothing runs in the reader's browser or on your server, which is why the same docs can run Python, C++ or SQL as easily as JavaScript. Install it npm install docusaurus-plugin-onlinecompiler Add it to d
Most docs have the same problem with code examples. The reader copies the snippet, opens a terminal or a playground in another tab, pastes it, fixes the indentation, and only then finds out what it does. Many give up before that.
Docusaurus has a fix for React: @docusaurus/theme-live-codeblock turns a jsx live block into a live editor. But it only renders JSX in the browser. If your docs show Python, Go, C++, SQL or anything that isn't a React component, you're back to copy and paste.
So I built a small plugin for that: docusaurus-plugin-onlinecompiler. You add one word to an ordinary code block, and readers get an editor with a Run button right in the page.
The code runs on OnlineCompiler.io (I build it), in a fresh sandbox for each run with no network access. Nothing runs in the reader's browser or on your server, which is why the same docs can run Python, C++ or SQL as easily as JavaScript.
Install it
npm install docusaurus-plugin-onlinecompiler
Add it to docusaurus.config.js with a widget key:
export default {
// ...the rest of your config
plugins: [['docusaurus-plugin-onlinecompiler', { key: 'YOUR_WIDGET_KEY' }]],
};
The widget key is free, from the Widgets page of the OnlineCompiler.io dashboard. It's made to sit in public pages: it can run code in the widget but can't call the REST API. Set its allowed domain to your docs domain so other sites can't use it, and make a second key for localhost previews.
If you'd rather keep the key out of the config file, read it from the environment: { key: process.env.ONLINECOMPILER_WIDGET_KEY }.
Write runnable
Any fenced code block, in a .md or .mdx page, becomes a runner when you add runnable after its language:
```python runnable
for n in range(1, 4):
print(n, "squared is", n * n)
```
After Run, the output panel shows:
1 squared is 1
2 squared is 4
3 squared is 9
Readers can change the range and run it again, and the Input tab holds whatever the program reads from standard input.
Code blocks without the word stay exactly as they are, so you can make one example runnable and leave the rest alone.
The code comes through as written, <, & and quotes included, because it goes into the page as text and the editor reads it from there:
```cpp runnable
#include
#include
int main() {
std::vector v{1, 2, 3};
int sum = 0;
for (int x : v) sum += x;
std::cout << "sum & done: " << (sum < 10 ? "<10" : ">=10") << "\n";
}
```
That one printed sum & done: <10.
Picking the compiler
The block's language picks the compiler: python runs Python 3.14, cpp runs C++ with G++ 15, js runs Node.js 24, sql runs SQLite, and full compiler ids like openjdk-25 work too. When the language alone isn't enough, lang= names another compiler, and the other options on the line still work:
```python title="frame.py" runnable lang=python-3.14-pandas2
import pandas as pd
print(pd.__version__)
```
That prints 2.3.3, from the Python build that ships pandas 2.
If a block names a language the service doesn't run, it stays a normal code block, and the build prints a warning naming the language, so a typo doesn't fail silently.
Inside Tabs and admonitions
Runnable blocks work anywhere Docusaurus renders a code block, including Tabs and admonitions:
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
```js runnable
console.log([1, 2, 3].map((x) => x * 2));
```
```go runnable
package main
import "fmt"
func main() { fmt.Println("hi from Go") }
```
The JavaScript tab printed [ 2, 4, 6 ] and the Go tab hi from Go.
How it works
The plugin is small, and the source is on GitHub, but three choices are worth knowing about if you care what ends up in your docs.
It wraps Docusaurus's own The code is in the HTML. Because the server render puts the code in the page as text, search engines index your examples and readers see them before the editor loads. If the service can't be reached, the code is still there; only the Run button needs it.
The widget script loads only where it's needed. The script is added the first time a page with a runnable block mounts, not on every page of your site. Each runner connects only when it scrolls into view. As readers move between pages without a reload, new runners start and the ones that left the page close their connection. Runners also follow your site's light and dark mode as the reader switches it.
One limitation to know: The plugin is free and MIT licensed. Each press of Run is one run on your OnlineCompiler.io account, and the free plan has 100,000 runs a month with no credit card. You can give the widget key its own monthly limit to cap what a public page can use.
If you use MkDocs instead, there's a plugin for that too: mkdocs-onlinecompiler. And if your docs run on something else, tell me which. We build integrations for other platforms free of charge.
CodeBlock. The plugin provides a theme component that wraps the original one. A block without runnable goes straight to the normal CodeBlock, so your syntax highlighting, titles and line numbers don't change. A runnable block renders a plain , and the widget turns that into the editor.
@docusaurus/theme-live-codeblock also replaces the code block component, and a Docusaurus site can only have one such wrapper. If you list both, the one listed last in themes wins. Use the live code block for React component demos and this plugin for programs in other languages, not both on one site.
What it costs
Links
Share