---
# System prepended metadata

title: Marko Syntax (Tweet Thread)

---

# Marko Syntax (Tweet Thread)

Some people, especially those of you unfamiliar with it, tend to look at Marko and wonder why in the world we’d introduce weird, special syntax for things like loops.  Why not use “Just HTML” or “Just JS”?

That’s because this is Just Marko™️

🧵 👇

<table>
<tr>
<td>

**Marko**
```marko
<ul>
  <for|item| of=items>
    <li>${item.name}</li>
  </for>
</ul>
```

</td>
<td><img width="161" alt="image" src="https://user-images.githubusercontent.com/1958812/165683948-a43ef12d-f217-4e8d-b814-019c8264cbf9.png"></td>
</tr>
<tr>
<td>

**Vue**
```vue
<ul>
  <li v-for="item in items">{{item.name}}</li>
</ul>
```
  
**React**
```jsx
<ul>
  {items.map(item => <li>{item.name}</li>)}
</ul>
```
  
**Svelte**
```svelte
<ul>
  {#each items as item}
    <li>{item.name}</li>
  {/each}
</ul>
```

</td>
<td><img width="164" alt="image" src="https://user-images.githubusercontent.com/1958812/165683986-1c4d11e3-49de-4fdf-930d-768d30fd30ff.png"></td>
</tr>
</table>

---

Marko is a superset of HTML.  Yes, that means you can copy/paste examples from resources like StackOverflow or MDN.

But it adds additional syntax.

<table>
<tr>
<td>
  
**HTML**
```html
<TAGNAME ATTRIBUTES>
  
</TAGNAME>
```
  
</td>
<td>
  
**Marko**
```marko
<TAGNAME/VARIABLE|PARAMS| ATTRIBUTES>
  
</TAGNAME>
```
  
</td>
</tr>
</table>

---

Marko's attributes are a mix between HTML's attributes and JavaScript's object properties.  All values are Javascript expressions - you don't need to wrap everything in {}.  Plus you get methods and spreads.

```marko
<a class="link" href=someUrlVar></a>
<input value=12 + 5 type="number">
```

```marko
<button onClick() { alert("Hello!") }>
  Click me
</button>
```

```marko
<div ...extraAttrs></div>
```

---

As a bonus, Marko has default value attributes.  This allows passing data to a tag when a named attribute would be redundant.


```marko
<if=someCondition>
</if>

// same as
<if value=someCondition>
</if>
```

---

Marko's tag variables allow you to receive data from a tag.  For example, native elements expose a getter for the reference to their DOM node.

```marko
<div/el>
  el is a getter for the HTMLDivElement!
</div>
```

---

Tag variables are also used by core tags such as `<const>` and `<let>` to introduce new a variable into scope.  Custom tags can return variables as well.

```marko
<let/count = 0/>
<const/message = "Hello"/>
```

```marko
<FancyButton/el>...</FancyButton>
<WindowSize/{ width, height }/> // yes, you can destructure tag vars
```

---

Tag parameters allow tags to pass data to their body content. They're used natively by the `<for>` tag and can be used by custom tags as well.

```marko
<ul>
  <for|item| of=items>
    <li>${item.name}</li>
  </for>
</ul>
```

```marko
<VirtualList|item| of=items>
  ${item.name}
</VirtualList>
```

---

Sure, it some new syntax to learn.  But it also means we don't need a lot of the "extras" of other frameworks.  We don't need hooks, nor special blocks, nor special meaning for certain attributes or existing syntax.

<table>
<tr>
<td>
  
**React ❌**
```jsx
const [count, setCount] = useState(0);
```
```jsx
<div key="foo"/>
```
```jsx
const el = useRef(null);
<div ref={el}/>
```
```jsx
const SubmitButton = forwardRef(({ title }, ref) => (
  <Button ref={ref}>{title}</Button>
));
```
  
</td>
<td>
  
**Svelte ❌**
```js
let x = 0;
$: console.log(x);
```
```svelte
{#each boxes as box}
  {@const area = box.width * box.height}
  {box.width} * {box.height} = {area}
{/each}
```
```svelte
<FancyList {items} let:prop={thing}>
  <div>{thing.text}</div>
</FancyList>
```

</td>
<td>
  
**Vue ❌**
```vue
<li v-for="item in items" :key="item.id">
```
```vue
<FancyList {items} v-slot:item="thing">
  <div>{{thing.text}}</div>
</FancyList>
```
```vue
<button v-on:click="doThis"></button>
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
<button @click="doThis"></button>
<button @click="count++"></button>
```
</td>
</tr>
</table>

---

So let's flip the meme.  Say we want to have a button that focuses an input.

<table>
<tr>
<td>

**Vue**
```vue
<script setup>
  import { ref } from 'vue';
  const el = ref(null);
</script>

<template>
  <input ref="el" value="Hello" />
  <button @click="el.focus()">Focus</button>
</template>
```
  
**React**
```jsx
import { useRef } from 'react';

export default () => {
  const el = useRef(null);
  return <>
      <input ref={el} value="Hello" />
      <button onClick={() => el.current.focus()}>Focus</button>
  </>;
}
```
  
**Svelte**
```svelte
<script>
  let el;
</script>

<input bind:this={el} value="Hello"/>
<button on:click={() => el.focus()}>Focus</button>
```

</td>
<td><img width="161" alt="image" src="https://user-images.githubusercontent.com/1958812/165683948-a43ef12d-f217-4e8d-b814-019c8264cbf9.png"></td>
</tr>
<tr>
<td>
  
**Marko**
```marko
<input/el value="Hello"/>
<button onClick() { el().focus() }>Focus</button>
```

</td>
<td><img width="164" alt="image" src="https://user-images.githubusercontent.com/1958812/165683986-1c4d11e3-49de-4fdf-930d-768d30fd30ff.png"></td>
</tr>
</table>

---


Or we want to switch from a "built-in" loop to a custom, `<VirtualList>` component.  

<table>
<tr>
<td>

**Vue** _(-13, +44)_
```diff
+ <VirtualList {items} v-slot:item="{ name }">
- <Item v-for="{ name } in items">{{name}}</Item>
+   <Item>{{name}}</Item>
+ </VirtualList>
```
  
**React** _(-6, +34)_
```diff 
+ <VirtualList items=items>
- {items.map(({ name }) => <Item>{name}</Item>)}
+   {({ name }) => <Item>{name}</Item>}
+ </VirtualList>
```
  
**Svelte** _(-19, +42)_
```diff
- {#each items as { name }}
+ <VirtualList {items} let:item={{ name }}>
    <Item>{name}</Item>
- {/each}
+ </VirtualList>
```

</td>
<td><img width="161" alt="image" src="https://user-images.githubusercontent.com/1958812/165683948-a43ef12d-f217-4e8d-b814-019c8264cbf9.png"></td>
</tr>
<tr>
<td>
  
**Marko** _(-6, +22)_
```diff
- <for|{ name }| of=items>
+ <VirtualList|{ name }| of=items>
    <Item>${name}</Item>
- </for>
+ </VirtualList>
```

</td>
<td><img width="164" alt="image" src="https://user-images.githubusercontent.com/1958812/165683986-1c4d11e3-49de-4fdf-930d-768d30fd30ff.png"></td>
</tr>
</table>

