Hi, I'm John, Multi Startup Builder.
I enjoy both coding and marketing.
See all my 20 products here
โ johnrush.me
โ my BIO
โ Say Hi to me On Twitter
โ Try my website builder
Warning: This post contains a high dose of code, humor, and life-changing revelations. Proceed at your own risk. ๐
When people ask me which frontend framework is my favorite, I usually reply with "all of them." But recently, I decided to put that statement to the test by building the same app using not one or two but seven different frontend frameworks.
I'll build a simple To-Do app 6 times using:
- Angular
- React
- Vue.js
- Svelte
- Elm
- AlpineJS
- MarsX
1: First love: Angular ๐ฅ
Angular has been around for quite some time now and is known for being powerful yet opinionated (thanks Google). It gave birth to concepts like components and Dependency Injection while rocking our worlds with Two-Way Data Binding. It was my first frontend framework I fell in love with. I tried knockout and few others, didnt like those. But AngularJS won my heart.
ng new todo-app --routing=false --style=css
Inside app.component.ts
:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>To-Do App</h1>
<ul>
<li *ngFor="let todo of todos">{{todo}}</li>
</ul>
<form (submit)="addTodo()">
<input [(ngModel)]="newTodo" name="newTodo">
<button type="submit">Add</button>
</form>`,
})
export class AppComponent {
todos = [];
newTodo = '';
addTodo() {
this.todos.push(this.newTodo);
this.newTodo = '';
}
}
Don't forget to import and include FormsModule in app.module.ts
.
2: React. The mainstreamer. โ๏ธ
React came as Facebook's gift ๐ to us developers who were tired of manually updating DOM elements every single time something changed in the data model (cries in vanilla JS) or seeing our browser freeze once an angularjs app got too much data or constant refresh loops.
npx create-react-app todo-app
Inside App.js
:
import React, { useState } from 'react';
function App() {
const [todos, setTodos] = useState([]);
const [newTodo, setNewToDo] = useState('');
const addTodo = e => {
e.preventDefault();
setTodos([...todos, newTodo]);
setNewToDo('');
};
return (
<div className="App">
<h1>To-Do App</h1>
<ul>{todos.map(todo => (<li key={todo}>{todo}</li>))}</ul>
<form onSubmit={add_todo}>
<input value={new_todo} onChange={(e) => set_new_todo(e.target.value)} />
submit_button
</form>
</div>
);
}
export default App;
3: My second wife: Vue.js ๐
Vue.js entered our lives as this cool kid on the block who wanted to make things simpler for us developers while giving Angular & React a run for their money.
vue create todo-app
Inside App.vue
:
<template>
<div id="app">
<h1>To-Do App</h1>
<ul>
<li v-for="(todo, index) in todos" :key="index">{{todo}}</li>
</ul>
<form @submit.prevent="addTodo">
<input v-model="newTodo"/>
<button type="submit">Add</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
todos: [],
newTodo: '',
};
},
methods: {
addTodo() {
this.todos.push(this.newTodo);
this.newTodo = '';
},
},
};
</script>
I lost my feeling to VUE once they came up with composition API. Sorry VUE.
4: Svelte-ing into Simplicity ๐งก
Svelte arrived fashionably late but was worth the wait! This framework promised something different - no virtual DOM! (I know lately they turned into react by adding almost same stuff, but I don't use that stuff, I'm still using the old svelte).
npx degit sveltejs/template todo-app
Inside App.svelte
:
<script>
let todos = [];
let newTodo = '';
function add_todo(e) {
e.preventDefault();
todos = [...todos, new_todo];
new_todo= '';
}
</script>
<main>
<h1>To-Do App</h1>
<ul>{#each todos as todo}<li>{todo}</li>{/each}</ul>
<form on_submit|prevent_default={add_todo}>
<input bind:value={new_todo} />
<button type="submit">Add</button>
</form>
</main>
<style>
/* Add your styles here */
</style>
5: Elm-inator ๐ณ
Elm stepped into our journey as this purely functional language based on Haskell offering "no runtime exceptions" (cue angelic music).
Inside src/Main.elm
:
module Main exposing (..)
import Browser
import Html exposing (Html, button, div, form, h1, input, li, text, ul)
import Html.Attributes exposing (value)
import Html.Events exposing (onInput, onSubmit)
-- MODEL
type alias Model =
{ todos : List String
, newTodo : String
}
init : Model
init =
{ todos = []
, newTodo = ""
}
-- MESSAGES
type Msg
= AddTodo
| SetNewTodo String
-- UPDATE
update : Msg -> Model -> Model
update msg model =
case msg of
AddTodo ->
{ model | todos = model.todos ++ [model.newTodo], newTodo = "" }
SetNewTodo newTodo ->
{ model | newTodo = newTodo }
-- VIEW
view : Model -> Html Msg
view model =
div []
[ h1 [] [text "To-Do App"]
, ul [] (List.map (\todo -> li [] [text todo]) model.todos)
, form [onSubmit AddTodo]
[ input [value model.newTodo, onInput SetNewTodo] []
, button [] [text "Add"]
]
]
-- MAIN
main : Program () Model Msg
main =
Browser.sandbox
{ init = init
, update = update
, view = view
}
Although Elm took some getting used to, its type system & pattern matching helped us build robust components along with The Elm Architecture(T.E.A) making sure everything stayed organized even when complexity increased.
6: Alpine, the most underrated one.
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/alpine.min.js" defer></script>
</head>
<body>
<div x-data="todoApp()" class="todo-container">
<h1>To-Do App</h1>
<form @submit.prevent="addTodo">
<input type="text" x-model="newTodo" placeholder="Add new todo">
<button type="submit">Add</button>
</form>
<ul>
<template x-for="todo in todos" :key="todo">
<li x-text="todo"></li>
</template>
</ul>
</div>
<script>
function todoApp() {
return {
newTodo: '',
todos: [],
addTodo() {
if (this.newTodo.trim() === '') {
return;
}
this.todos.push(this.newTodo);
this.newTodo = '';
}
}
}
</script>
</body>
</html>
7: MarsX - It took less time to code the todo list here than it took time to write this sentence :D
Disclamer, I'm the author of marsx, so feel free to ignore this, but it's not bad I'd say.
<schema>
<array name="todo">
<object>
<string name="title" />
</object>
</array>
</schema>
Now that you've witnessed how I built the same app using different frontend frameworks, you might be wondering which one is the best. Well, my friend, that's like asking a parent to pick their favorite child - it just doesn't work that way.
Each framework has its strengths and weaknesses; what works for me may not work for you. So go ahead, take your pick and start building some amazing apps! ๐
And remember: no matter which framework you choose, don't forget to have fun while coding! ๐
Hi, I'm John, Multi Startup Builder.
I enjoy both coding and marketing.
See all my 20 products here
โ johnrush.me
โ my BIO
โ Say Hi to me On Twitter
โ Try my website builder
Top comments (62)
Hello Angular, my old friend <3 currently I am checking out react, but honestly it doesn't feel like "home", so I think I will stick in angular for later projects until a shiny knight.. eeh framework comes around and saves me from my angular tower. ;-)
I have the opposite experience ๐ . Attempted some projects in Angular, but it didn't quite feel like home. I'm leaning towards React ๐คฃ.
Each has its pros and cons. As you delve deeper into learning, you'll likely discover which suits different projects best. ๐ฌ
for simple projects, alpine is great. so easy to get started
I loved angularjs, but lost the love once it moved past Angular 2
Could be the name but I love angular too โค๏ธ
The Elm version shows off very nicely was is possible if you let a smart person design things rather than a company - we wouldn't have Python or Ruby without these sorts of people.
Vue is simply the best in my point of view. Composition API is nice. Itโs fast and have a great DX. But everyone is different which is nice. If there are multiple JS-Frameworks we have competition which benefits all and brings new innovations.
my fav is VUE too
Point of Vue ๐
But then you are not using TypeScript in your Vue JS project.
Iโm using typescript in all of my projects and actually vue is a great fit and itโs a pleasure to work with.
Markup for Angular and Vue are understandable even if one doesn't know about them and who is familiar with HTML. Other looks like assembly language code. The difference seems like simple & affordable things vs flashy & costly things, both working well for a same purpose.
I have same feeling tbh
ngIf looks like html? This is news to me.
Really so a student fresh out of school who learned html, css and nothing else, is going to understand how something like ngFor works? Tbh that's just a factual lie...
You missed a factual reality. What happens when a web browser encounters an unknown tag or attribute within HTML code? The HTML developer can consider the same (obviously, if he knows how HTML and web browser work).
Nothing in HTML spec or documentation will prepare you for the nightmare that is ngFor syntax. What the developer has to do is go to the angular documentation site and learn how it works, which is knowledge that is only applicable to angular and nothing else. Same goes for vue and htmx. All these frameworks face the same issue of wanting to make something dynamic that was never intended to be dynamic (html). Its a markup language, let's keep it that way.
It seems you misinterpreted my previous comment. What I mean by
is - a web browser will ignore the unknown tag and attributes; so similarly, the HTML-CSS designer can ignore unknown code too.
The problem with React is a traditional web designer would wonder about where the HTML and CSS code is!
I agree with your other concerns, though.
Iยดm curious to see, which bundle size each package delivers...
with the modern internet speed and device perf, the size doesn't matter as much as it did in old days
If you are talking about application performance and responsiveness, you're probably right. I donยดt think there is a direct relation between bundle size and performance. I am just curious to see, how much overhead a framework will pack ontop of a relatively small application.
Anyway, comparing start up performance and responsiveness would be an interestion comparison too!
Angular != AngularJS
true
The point I was making is that it seems like framework #1 you list is Angular, but then you say "AngularJS won my heart." It seems like you don't understand there is a difference.
Angular !== AngularJS. Code reviewed! ๐๐
Also what is wrong with using pure JavaScript and HTML
The best solution for a todolist if you ask me :) The only counterpoint is that in the previous code snippets, the todolist state can also be modified by other processes and then the DOM would automatically be updated.
You think in 2024 is maybe minimize the use of front-end frameworks? There was a good article I read. Today Astro and tomorrow another solution. We need to write code so that we can switch out frameworks easy not lock yourself into one.
I often miss the part where a new framework actually explains why we need it at all. Is it only so we don't have to type
document.querySelector()
anymore? Is a framework actually faster than native js+html without any framework? Can't you have a design system that just works with native js+html? (MVC, MVVM, etc).Awesome. Saved me the trouble.
"Well, my friend, that's like asking a parent to pick their favorite child - it just doesn't work that way."
Love it ๐
I don't care what anyone says I love React <3
your first kid is often your favorite kid ;)
Well said
just to make sure I don't start a framework war
I missing the qwik from the list
I can add, if you help me with the code snippet
Aren't there any frameworks besides React which just allow Javascript in "HTML"? I know, it's not really HTML but JSX, and I still think it's the best feature of React.
In all other frameworks presented here you have to learn a templating language and write things like
#each
,x-for
or*ngFor="let todo of todos"
SolidJS has JSX.
It's like Svelte and React had a baby
That's because React doesn't even have a
ngFor
:( You have to write a whole loop yourself... I still can't believe it...You don't have to invent the for loop yourself, JavaScript has many different ways to loop over things built in.
Solidjs uses jsx natively and a lot of frameworks like Astro support mdx files, which support jsx.