Choosing the Best JS Framework: Insights From Building the Same App 6 Times

Written by johnrush | Published 2023/06/19
Tech Story Tags: front-end-development | web-development | frameworks | react | vue | angular | elm | javascript-frameworks

TLDRAngular, React, Vue, Elm, and MarsX are the frontend frameworks I've used in the past. In this article, we'll build a simple To-Do app in five steps. We'll use five different frontend framework to build the app.via the TL;DR App

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 five different frontend frameworks.

In this roller-coaster ride of an article, we'll build a simple To-Do app (yeah, another one) in five steps:

  1. Angular
  2. React
  3. Vue.js
  4. Svelte
  5. Elm
  6. MarsX

You might be thinking - what about jQuery? Well...that's so 2010! ๐Ÿ™…โ€โ™‚๏ธ Let's dive into some modern stuff!

Step 1: Acing it with 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.

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.

Step 2: Reacting with React โš›๏ธ

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).

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;

Step 3: Viewing it through Vue.js ๐Ÿ’š

Vue.js entered our lives as this cool kid on the block that 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>

Step 4: Svelte-ing into Simplicity ๐Ÿงก

Svelte arrived fashionably late but was worth the wait! This framework promised something different - no virtual DOM!

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>

Step 5: Elm-inating Complexity with Elm ๐ŸŒณ

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, h1, input, li, text, ul)
import Html.Attributes as Attrs exposing (value)
import Html.Events as Events exposing (onClick)


type alias Model =
    { todos : List String
    , newTodo : String
    }


init : Model
init =
    { todos = []
    , newTodo = ""
    }


type Msg
    = AddTodo


update msg model =
     case msg of 
        AddTodo ->
            { model | todos=model.todos++[model.newTodo],new_todo=""}


view model =
      div []
          [ h1 [] [text "To-Do App"]
          , ul [] <| List.map (\todo -> li [] [text todo]) <| model.todos 
          , form [Events.onSubmit |> Events.preventDefault |> onClick add_todo]
              [
                inputAttr [ value model.new_todo,
                           on_input set_new_to_do] [],
                submit_button []
             ]
         ]


main=
Browser.sandbox{
	init=initial_model,
	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.

Step 6: MarsX - It took less time to code the todo list here than it took time to write this sentence :D

<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!

๐Ÿ˜„


Also published here.

The lead image for this article was generated by HackerNoon's AI Image Generator via the prompt "App development"

Follow me on twitter Credits to fireship


Written by johnrush | Founder of MarsX & 20 more projects
Published by HackerNoon on 2023/06/19