–
Unsung Hero of
Scalable Web
Frameworks
How isomorphic UI framework
excels in SSR and CSR performance
Eugene Fidelin
introduction
2
3
class {
onCreate() {
this.state = {
count: 0
};
}
increment() {
this.state.count++;
}
}
<div>
<p>Count: ${state.count}</p>
<button on-click("increment")>
Increment
</button>
</div>
import React, { useState } from
'react';
export default function Counter()
{
const [count, setCount] =
useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>
Increment
</button>
</div>
);
}
<script>
export default {
data() {
return { count: 0 };
},
methods: {
increment() { this.count++; }
}
}
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">
Increment
</button>
</div>
</template>
marko react vue.js
Superset of HTML
4
Conditionals Loops
<if(user.loggedOut)>
<a href="/login">Log in</a>
</if>
<else-if(!user.trappedForever)>
<a href="/logout">Log out</a>
</else-if>
<else>
Hey ${user.name}!
</else>
<ul>
<for|color, index| of=colors>
<li>${index}: ${color}</li>
</for>
</ul>
<ul>
<for|key, value| in=user>
<li>${key}: ${value}</li>
</for>
</ul>
Superset of HTML
5
Dynamic content & attrs Async rendering
<div>
Hello ${"world".toUpperCase()}
</div>
<custom-tag string="Hello"/>
<custom-tag number=1/>
<custom-tag boolean=true/>
<custom-tag array=[1, 2, 3]/>
<custom-tag object={ hello: "world" }/>
<custom-tag variable=name/>
<custom-tag function-call=user.getName()/>
$ const personPromise = new Promise(
(resolve) => {
setTimeout(() => resolve({ name: 'Frank' }),
1000);
});
<await(personPromise)>
<@placeholder>Loading...</@placeholder>
<@then|person|>
<p>Hello ${person.name}!</p>
</@then>
</await>
Components
6
Components
7
Input & state Events
class {
onInput(input) {
this.state = { count: input.start };
}
inc() {
this.state.count += this.input.step
}
}
<p>Count is: ${state.count}</p>
<button on-click('inc')>+${input.step}</button>
<counter start=1 step=2 />
class {
handleChange(event) {
this.emit("email-change",
{ email: event.target.value });
}
}
<input type="email" on-change("handleChange")/>
class {
handleEmailChange({ email }) { ... }
}
<email on-email-change("handleEmailChange")/>
counter.marko
app.marko
email.marko
app.marko
Components
8
Single & multi-files Lifecycle
class {
onCreate(input, out) { }
onInput(input, out) { }
onRender(out) { }
onMount() { }
onUpdate() { }
onDestroy() { }
}
superpowers
9
Code Elimination
Marko only sends the code for
interactive components
(islands) to the browser.
Its compiler automatically
detects which components only
need to be rendered on the
server
This means less code to
download and less to execute.
10
Progressive Rendering
Marko streams content to the
browser as soon as it’s ready.
No waiting for client side
JavaScript bundles or data
requests to start rendering.
HTML, assets, and images are
loaded as soon as possible with
asynchronous data loading in
as it completes.
11
High SSR & CSR Performance
Marko 's compiler generates
code optimized for both the
server and browser.
This is especially apparent on
the server where Marko is
several times faster than other
popular solutions.
2x faster than React
1.2x faster than Vue
* based on Platformatic SSR Performance Showdown
12
Batteries included
Marko Run meta framework
makes it easy to get started
with little to no config and is the
recommended starting point for
a new Marko project.
● File-based routing
● Modern developer tooling
using Vite
● TypeScript powered
● Testing library & Storybook
● Support for
micro-frontends
● Deploy to multiple
platforms (Node.js, Netlify
Functions, static files)
13
Proven and Trusted
Marko has powered high-traffic
sites like eBay.com since 2014
and continues to evolve with
frequent updates and new
features.
Marko pioneered many ideas
that become widely adopted by
other frameworks: SSR
streaming, fine-grained
reactivity, partial hydration,
resumability.
14
<let/count = 0/>
<p>${count} clicks</p>
<button
onClick() { count++ }
>
Click me
</button>
6
Tags API
* in beta now
challenges
15
Developer Impression
HTML-based syntax - not a JSX.
No explicit import of components, but auto
discoverability.
Seen as eBay-specific, not general-purpose
Less community buzz.
Ecosystem Realities
Full IDE support is limited to VSCode.
Few open-source libraries available (i.e. only
one UI library from eBay).
Limited AI assistance, as not enough Marko
code is publicly available for training.
Minimal Third-Party learning resource
Learn & build with
markojs.com/try-online
16
Official site
markojs.com
Discord
discord.gg/marko
Twitter/X
@MarkoDevTeam
Try online Start building
$ npm init marko
eBayUI widgets
github.com/eBay/ebayui-cor
e
Community libs
github.com/marko-js-polo
CREDITS: This presentation template was
created by Slidesgo , including icons by Flaticon
and infographics & images by Freepik
Thanks!
Eugene Fidelin
Engineering Manager @
eugene.fidelin@gmail.com
linkedin.com/in/eugef
medium.com/@EugeneFidelin
17

Marko.js - Unsung Hero of Scalable Web Frameworks (DevDays 2025)

  • 1.
    – Unsung Hero of ScalableWeb Frameworks How isomorphic UI framework excels in SSR and CSR performance Eugene Fidelin
  • 2.
  • 3.
    3 class { onCreate() { this.state= { count: 0 }; } increment() { this.state.count++; } } <div> <p>Count: ${state.count}</p> <button on-click("increment")> Increment </button> </div> import React, { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); const increment = () => { setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}> Increment </button> </div> ); } <script> export default { data() { return { count: 0 }; }, methods: { increment() { this.count++; } } } </script> <template> <div> <p>Count: {{ count }}</p> <button @click="increment"> Increment </button> </div> </template> marko react vue.js
  • 4.
    Superset of HTML 4 ConditionalsLoops <if(user.loggedOut)> <a href="/login">Log in</a> </if> <else-if(!user.trappedForever)> <a href="/logout">Log out</a> </else-if> <else> Hey ${user.name}! </else> <ul> <for|color, index| of=colors> <li>${index}: ${color}</li> </for> </ul> <ul> <for|key, value| in=user> <li>${key}: ${value}</li> </for> </ul>
  • 5.
    Superset of HTML 5 Dynamiccontent & attrs Async rendering <div> Hello ${"world".toUpperCase()} </div> <custom-tag string="Hello"/> <custom-tag number=1/> <custom-tag boolean=true/> <custom-tag array=[1, 2, 3]/> <custom-tag object={ hello: "world" }/> <custom-tag variable=name/> <custom-tag function-call=user.getName()/> $ const personPromise = new Promise( (resolve) => { setTimeout(() => resolve({ name: 'Frank' }), 1000); }); <await(personPromise)> <@placeholder>Loading...</@placeholder> <@then|person|> <p>Hello ${person.name}!</p> </@then> </await>
  • 6.
  • 7.
    Components 7 Input & stateEvents class { onInput(input) { this.state = { count: input.start }; } inc() { this.state.count += this.input.step } } <p>Count is: ${state.count}</p> <button on-click('inc')>+${input.step}</button> <counter start=1 step=2 /> class { handleChange(event) { this.emit("email-change", { email: event.target.value }); } } <input type="email" on-change("handleChange")/> class { handleEmailChange({ email }) { ... } } <email on-email-change("handleEmailChange")/> counter.marko app.marko email.marko app.marko
  • 8.
    Components 8 Single & multi-filesLifecycle class { onCreate(input, out) { } onInput(input, out) { } onRender(out) { } onMount() { } onUpdate() { } onDestroy() { } }
  • 9.
  • 10.
    Code Elimination Marko onlysends the code for interactive components (islands) to the browser. Its compiler automatically detects which components only need to be rendered on the server This means less code to download and less to execute. 10
  • 11.
    Progressive Rendering Marko streamscontent to the browser as soon as it’s ready. No waiting for client side JavaScript bundles or data requests to start rendering. HTML, assets, and images are loaded as soon as possible with asynchronous data loading in as it completes. 11
  • 12.
    High SSR &CSR Performance Marko 's compiler generates code optimized for both the server and browser. This is especially apparent on the server where Marko is several times faster than other popular solutions. 2x faster than React 1.2x faster than Vue * based on Platformatic SSR Performance Showdown 12
  • 13.
    Batteries included Marko Runmeta framework makes it easy to get started with little to no config and is the recommended starting point for a new Marko project. ● File-based routing ● Modern developer tooling using Vite ● TypeScript powered ● Testing library & Storybook ● Support for micro-frontends ● Deploy to multiple platforms (Node.js, Netlify Functions, static files) 13
  • 14.
    Proven and Trusted Markohas powered high-traffic sites like eBay.com since 2014 and continues to evolve with frequent updates and new features. Marko pioneered many ideas that become widely adopted by other frameworks: SSR streaming, fine-grained reactivity, partial hydration, resumability. 14 <let/count = 0/> <p>${count} clicks</p> <button onClick() { count++ } > Click me </button> 6 Tags API * in beta now
  • 15.
    challenges 15 Developer Impression HTML-based syntax- not a JSX. No explicit import of components, but auto discoverability. Seen as eBay-specific, not general-purpose Less community buzz. Ecosystem Realities Full IDE support is limited to VSCode. Few open-source libraries available (i.e. only one UI library from eBay). Limited AI assistance, as not enough Marko code is publicly available for training. Minimal Third-Party learning resource
  • 16.
    Learn & buildwith markojs.com/try-online 16 Official site markojs.com Discord discord.gg/marko Twitter/X @MarkoDevTeam Try online Start building $ npm init marko eBayUI widgets github.com/eBay/ebayui-cor e Community libs github.com/marko-js-polo
  • 17.
    CREDITS: This presentationtemplate was created by Slidesgo , including icons by Flaticon and infographics & images by Freepik Thanks! Eugene Fidelin Engineering Manager @ eugene.fidelin@gmail.com linkedin.com/in/eugef medium.com/@EugeneFidelin 17