WLX
Type .wlx in the first line of an input cell and start writing WLX on a new line:
.wlx
<Now/>
Fri 2 Jan 2026 16:11:04 Make sure the first letter in a symbol name is capitalized. This is required by WLX syntax.
This allows you to use Wolfram Language XML extension in your cell. It's extremely powerful and especially useful when creating complex cell structures, components for presentations, mini-apps, or enhancing output with the power of HTML, CSS, and JavaScript.
You can think of WLX as WL and plain HTML extended to work with each other. It allows you to write Wolfram Language using XML tags and build HTML templates using Wolfram Expressions.
Unlike JSX, you can write a plain HTML inside WLX scripts with no restrictions.
Tags
Wolfram expressions always start with a capital letter, while plain HTML tags must remain in a lower case:
.wlx
<div></div> .wlx
<Div></Div> Ownvalues and Downvalues
OwnValue of a symbol corresponds to self-closing tags with no attributes, while DownValue of a symbol corresponds to normal tags with or without attributes. For example:
TimeNow := TextString[Now];
StringReverse[TimeNow]can be written as
.wlx
TimeNow := TextString[Now];
<StringReverse>
<TimeNow/>
</StringReverse>
First child element is the first argument of a given function and etc.
Output form
Any symbol in Wolfram Language has a few predefined output forms. StandardForm is shown in all output cells, while WLXForm is shown in WLX, slide, markdown output cells and is usually some sort of a string.
WLXForm is not defined for a given symbol, ToString is appliedFor example:
SpecialSymbol;
SpecialSymbol /: MakeBoxes[SpecialSymbol, WLXForm] := MakeBoxes["Hey!", WLXForm]
then if you evaluate SpecialSymbol in WLX cell, it will print "Hey!" to a DOM tree:
.wlx
<SpecialSymbol/>
Many symbols have predefined WLXForm, namely: Graphics, Graphics3D, Image, EventObject, any GUI input elements and many more.
However, a basic plot will work out of the box:
MyPlot = Plot[x, {x,0,1}]; .wlx
<MyPlot/> Passing arguments
-
Any argument passed to an expression is converted to a string (or specifically
WLXForm) -
Plain text content counts as an argument too
-
Tags attributes are passed as options
Here is a function, that takes 3 arguments, but prints only the 2nd one:
.wlx
SomeFunction[Arg1_, Arg2_, Arg3_] := <h3><Arg2/></h3>
<SomeFunction>
<div>You will not see me</div>
You will see only me
<Now/>
</SomeFunction> Attributes interpolation
This is a crucial thing, when it comes to a markup. Curly braces with double quotes can be used to interpolate strings in HTML attributes:
.wlx
With[{
url = "upload.wikimedia.org/wikipedia/commons/7/70/Oftheunicorn.jpg"
},
<img width="300" src="https://{url}"/>
]
Any Wolfram expressions are allowed inside the braces
.wlx
With[{
url = {"upload.wikimedia.org/wikipedia/commons/7/70/Oftheunicorn.jpg"}
},
<img width="300" src="https://{url[[1]]}"/>
]
Attributes of symbols
If you pass an HTML attribute to a Wolfram symbol, it will be translated to an option, i.e.
.wlx
<Heading title={"Some title"}/>
where we defined Heading as
.wlx
Heading[OptionsPattern[]] := With[{Title = OptionValue["title"]},
<h1>This is some <Title/></h1>
]
Options[Heading] = {"title" -> "Empty title"}
The same can be done for tags with children:
.wlx
<TagName option1={1+1} option2={Now}>
whatever
</TagName> where all passed arguments go firstly and before the OptionsPattern[]:
.wlx
TagName[child_, OptionsPattern[]] := ...
TagName[children__, OptionsPattern[]] := ...
Escaping
Use special <Escape> tag to avoid interpretation of tags inside:
.wlx
<Escape>
<Div>It won't be parsed by WLX</Div>
</Escape>
The inner content will not be parsed and, but will be returned as string
Iterators, branching?
HTML/XML is a markup language by its nature. Therefore we recommend to use Wolfram Language making tables, conditional rendering for that:
.wlx
Columns[YourList__] := Table[
<div class="lg:pr-4">
<div class="text-base leading-7 text-gray-700 ">
<Child/>
</div>
</div>
, {Child, List[YourList]}];
<div class="flex flex-col">
<Columns>
<p>This is column 1</p>
<p>This is column 2</p>
<p>This is column 3</p>
</Columns>
</div>
Here a multiple <p> tags are substituted as a sequence of arguments to Columns function, that iterates over them and forms a wrapper HTML structure. Then the result is substituted into the bottom div col structure.
Here is another way to build lists from raw data:
.wlx
With[{
TableList = Table[
With[{SomeField = item["Field"]},
<li class="red"><SomeField/></li>
]
, {item, YouList}]
},
<ul>
<TableList/>
</ul>
]
<span> or <p> or <Identity> if you want them to be separableA few things to keep in mind
There are certain rules you should sticked to in order to avoid headaches
Keep only one or zero root element
This implies that this one will be exported to the output, like in CompoundExpression.
Always close any XML tags
Modern web-browsers are quite forgiving, when it comes to the syntax mistakes. WLX parser decodes the whole tree of HTML and WL and, then, builds an AST. Therefore, always close tags explicitly
.wlx
<img src="http://..."/>
More examples
Embed Figures into a Custom Layout
Plot a function and assign it to a symbol:
Figure = Plot[Sinc[5x], {x, -5, 5}]
Then, in a new cell, type:
.wlx
<div>
<style>
@keyframes tilt-shaking {
0% { transform: rotate(0deg); }
25% { transform: rotate(5deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-5deg); }
100% { transform: rotate(0deg); }
}
</style>
<div style="animation: tilt-shaking 0.35s infinite">
<Figure/>
</div>
</div>
Now your plot will shake infinitely 😉
Creating Components
Let's define a hybrid WL function:
Heading[Text_, OptionPattern[]] := With[{color = OptionValue["Color"]},
<h2 style="color: {color}"><Text/></h2>;
]
Options[Heading] = {"Color" -> "black"};
You can now use it in your layout:
.wlx
<Heading Color={"blue"}>
Hello World!
</Heading>
this will work on slides and markdown cells as well:
.slide
# Slide title
<Heading Color={"red"}>
Hello World!
</Heading>
Two-Column Layout Using Flexbox
You can fine-tune the layout since you're working directly with HTML and CSS. For example, here's a slider and a plot aligned in a row:
.wlx
Module[{Slider = InputRange[0.1, 1, 0.1, 0.5], Figure, lines},
EventHandler[Slider, Function[data, lines = {#, Sinc[#/data]} & /@ Range[-5, 5, 0.1]]];
Slider // EventFire;
Figure = Graphics[Line[lines // Offload], ImageSize -> 350];
<div style="display: flex">
<div><Slider/></div>
<div><Figure/></div>
</div>
]