Aurelia 2 vs Marko: A Comprehensive Comparison

This website is powered by ItGalaxy.io

In the world of frontend development, Aurelia 2 and Marko represent two distinct approaches to building web applications. While Aurelia 2 offers a modern, convention-based approach with powerful data binding, Marko introduces a unique template-first approach with powerful streaming capabilities and compile-time optimizations. Let’s explore their differences and use cases.

Table of Contents

  1. Core Concepts
  2. Reactivity and State Management
  3. Templating and Components
  4. DOM Manipulation
  5. Event Handling
  6. Component Composition
  7. Form Handling
  8. Lifecycle Management
  9. Web App Features
  10. Performance and Bundle Size
  11. Learning Curve
  12. Conclusion

Core Concepts

Aurelia 2 and Marko take fundamentally different approaches to building web applications:

  • Aurelia 2 employs a modern, convention-based approach with powerful data binding and dependency injection
  • Marko uses a template-first approach with powerful streaming capabilities and compile-time optimizations

Reactivity and State Management

Declare State

Aurelia 2

<h1>Hello ${name}</h1>

Marko

<let/name = "John"/>
<h1>Hello ${name}</h1>

Update State

Aurelia 2

<h1>Hello ${name}</h1>

Marko

<let/name = "John"/>
<effect() { name = "Jane" }/>
<h1>Hello ${name}</h1>

Computed State

Aurelia 2

<div>${doubleCount}</div>

Marko

<let/count = 10/>
<const/doubleCount = count * 2/>
<div>${doubleCount}</div>

Templating

Minimal Template

Aurelia 2

<h1>Hello world</h1>

Marko

<h1>Hello world</h1>

Styling

Aurelia 2

/* css-style.css */
.title {
  color: red;
}

Marko

<h1.title>I am red</h1>
<button style={ fontSize: "10rem" }>I am a button</button>
<button class=scopedButton>I am a style-scoped button</button>

<style>
  .title {
    color: red;
  }
</style>
<style/{ scopedButton }>
  .scopedButton {
    font-size: 10rem;
  }
</style>

Loop

Aurelia 2

<ul>
  <li repeat.for="color of colors">${color}</li>
</ul>

Marko

<ul>
  <for|color| of=["red", "green", "blue"]>
    <li>${color}</li>
  </for>
</ul>

Event Click

Aurelia 2

<p>Counter: ${count}</p>
<button click.trigger="incrementCount">+1</button>

Marko

<let/count = 0/>
<p>Counter: ${count}</p>
<button onClick() { count++ }>+1</button>

DOM Reference

Aurelia 2

<input ref="inputElement" />

Marko

<input/inputElement>
<effect() { inputElement().focus() }/>

Conditional

Aurelia 2

<button click.trigger="nextLight()">Next light</button>
<p>Light is: ${light}</p>
<p switch.bind="light">
  You must
  <span case="red">STOP</span>
  <span case="orange">SLOW DOWN</span>
  <span case="green">GO</span>
</p>

Marko

static const TRAFFIC_LIGHTS = ["red", "orange", "green"];
<let/lightIndex = 0/>
<const/light = TRAFFIC_LIGHTS[lightIndex]/>

<button onClick() { lightIndex = (lightIndex + 1) % TRAFFIC_LIGHTS.length }>
  Next light
</button>
<p>Light is: ${light}</p>
<p>
  You must
  <if=light === "red">STOP</if>
  <else-if=light === "orange">SLOW DOWN</else-if>
  <else>GO</else>
</p>

Lifecycle

On Mount

Aurelia 2

<p>Page title is: ${pageTitle}</p>

Marko

<let/pageTitle = ""/>
<effect() { pageTitle = document.title }/>
<p>Page title: ${pageTitle}</p>

On Unmount

Aurelia 2

<p>Current time: ${time}</p>

Marko

<let/time = new Date()/>
<lifecycle
  onMount() { this.timer = setInterval(_ => time = new Date(), 1000) }
  onDestroy() { clearInterval(this.timer) }
/>
<p>Current time: ${time.toLocaleTimeString()}</p>

Component Composition

Props

Aurelia 2

<user-profile
  name.bind
  age.bind
  favourite-colors.bind="colors"
  is-available.bind="available"
></user-profile>

Marko

<UserProfile
  name="John"
  age=20
  favouriteColors=["green", "blue", "red"]
  isAvailable
/>

Emit to Parent

Aurelia 2

<p>Can I come ?</p>
<answer-button action-handler.bind="handleAnswer"></answer-button>
<p style="font-size: 50px">${isHappy ? "😀" : "😥"}</p>

Marko

<let/isHappy = true/>
<p>Are you happy?</p>
<AnswerButton
  onYes() { isHappy = true }
  onNo() { isHappy = false }
/>
<p style={ fontSize: 50 }>${isHappy ? "😀" : "😥"}</p>

Slot

Aurelia 2

<funny-button>Click me !</funny-button>

Marko

<FunnyButton>Click me!</FunnyButton>

Slot Fallback

Aurelia 2

<funny-button></funny-button> <funny-button>Click me !</funny-button>

Marko

<FunnyButton/>
<FunnyButton>I got content!</FunnyButton>

Context

Aurelia 2

<h1>Welcome back, {{ user.username }}</h1>
<user-profile />

Marko

<let/user = {
  id: 1,
  username: "unicorn42",
  email: "unicorn42@example.com",
}/>
<const/updateUsername(newUsername) {
  user = { ...user, username: newUsername };
}/>

<h1>Welcome back, ${user.username}</h1>
<set={ ...user, updateUsername }>
  <UserProfile />
</set>

Form Input

Input Text

Aurelia 2

<p>${text}</p>
<input value.bind />

Marko

<let/text = "Hello world"/>
<p>${text}</p>
<input value:=text/>

Checkbox

Aurelia 2

<input id="is-available" type="checkbox" checked.bind="isAvailable" />
<label for="is-available">Is available</label>: ${isAvailable}

Marko

<input#is-available
  type="checkbox"
  checked:=input.isAvailable
/>
<label for="is-available">Is available</label>

Radio

Aurelia 2

<div>Picked: ${picked}</div>

<input id="blue-pill" checked.bind="picked" type="radio" value="blue" />
<label for="blue-pill">Blue pill</label>

<input id="red-pill" checked.bind="picked" type="radio" value="red" />
<label for="red-pill">Red pill</label>

Marko

<let/picked = "red"/>
<const/handleChange(event) {
  picked = event.target.value;
}/>

<div>Picked: ${picked}</div>
<input#blue-pill
  type="radio"
  checked=picked === "blue"
  value="blue"
  onChange=handleChange
/>
<label for="blue-pill">Blue pill</label>

<input#red-pill
  type="radio"
  checked=picked === "red"
  value="red"
  onChange=handleChange
/>
<label for="red-pill">Red pill</label>

Select

Aurelia 2

<select value.bind="selectedColorId">
  <option value="">Select A Color</option>
  <option
    repeat.for="color of colors"
    value.bind="color.id"
    disabled.bind="color.isDisabled"
  >
    ${color.text}
  </option>
</select>

Marko

static const colors = [
  { id: 1, text: "red" },
  { id: 2, text: "blue" },
  { id: 3, text: "green" },
  { id: 4, text: "gray", isDisabled: true },
];
<let/selectedColorId = 2/>

<select onChange(event) { selectedColorId = event.target.value }>
  <for|{ id, isDisabled, text }| of=colors>
    <option value=id disabled=isDisabled selected=id === selectedColorId>
      ${text}
    </option>
  </for>
</select>

Web App Features

Render App

Aurelia 2

<!DOCTYPE html>
<html>
  <head>
    <script type="module" src="./main.ts"></script>
  </head>

  <body>
    <app></app>
  </body>
</html>

Marko

<!DOCTYPE html>
<html>
  <App/>
</html>

Fetch Data

Aurelia 2

<template promise.bind="useFetchUsers.fetchData()">
  <p pending>Fetching users...</p>
  <p catch>An error ocurred while fetching users</p>
  <ul then.from-view="users">
    <li repeat.for="user of users">
      <img src.bind="user.picture.thumbnail" alt="user" />
      <p>${ user.name.first } ${ user.name.last }</p>
    </li>
  </ul>
</template>

Marko

<await(fetch("https://randomuser.me/api/?results=3").then(res => res.json()))>
  <@placeholder>
    <p>Fetching users...</p>
  </@placeholder>
  <@catch|error|>
    <p>An error occurred while fetching users</p>
  </@catch>
  <@then|{ results: users }|>
    <ul>
      <for|{ picture, name }| of=users>
        <li>
          <img src=picture.thumbnail alt="user">
          <p>${name.first} ${name.last}</p>
        </li>
      </for>
    </ul>
  </@then>
</await>

Performance and Bundle Size

Aurelia 2

  • Modern, optimized architecture
  • Tree-shakeable modules
  • Efficient template compilation
  • Strong performance characteristics
  • Convention over configuration

Marko

  • Compile-time optimizations
  • Streaming rendering
  • Partial hydration
  • Automatic code splitting
  • Small runtime footprint

Learning Curve

Aurelia 2

  • Convention-based approach
  • Object-oriented programming
  • Strong TypeScript support
  • Comprehensive documentation
  • Active community support

Marko

  • Template-first approach
  • Unique syntax to learn
  • Built-in streaming capabilities
  • Growing documentation and community
  • Innovative development patterns

Conclusion

Choose Aurelia 2 if you:

  • Prefer convention over configuration
  • Need powerful dependency injection
  • Want strong data binding capabilities
  • Value object-oriented programming
  • Are building medium to large applications

Choose Marko if you:

  • Need streaming server rendering
  • Want compile-time optimizations
  • Need partial hydration
  • Value template-first development
  • Are building large, scalable applications

Both frameworks excel in different scenarios:

  • Aurelia 2 shines in applications that benefit from conventions and strong architecture
  • Marko excels in applications that need streaming capabilities and compile-time optimizations

The choice between Aurelia 2 and Marko often depends on your specific needs:

  • Use Aurelia 2 for applications that need strong conventions and architecture
  • Use Marko for applications that need streaming capabilities and compile-time optimizations






Decouvrez plus d’Offres de la plateform ItGalaxy.io :

Découvrez notre gamme complète de services et formations pour accélérer votre carrière.

1. Nous contactez

  • Description: Besoin de Formation et des Solutions cloud complètes pour vos applications
  • Links:

2. Infra as a Service

  • Description: Infrastructure cloud évolutive et sécurisée
  • Links:

3. Projets Développeurs


4. Développeurs


5. Formations Complètes


6. Marketplace

7. Blogs


This website is powered by ItGalaxy.io