I created the same app in React and Vue. Here are the differences.

As a web developer, I‘ve long been curious about the differences between the popular React and Vue JavaScript frameworks. Both let you build dynamic, component-based user interfaces, but how do they really compare in practice?

To find out, I decided to build the same app in both frameworks and compare the development experience. In this post, I‘ll walk through how I implemented a simple To Do list application in both React and Vue, share code samples, and discuss my thoughts on working with each framework.

A bit about me

First, a little background. I‘m a full-stack web developer with a couple years of experience building web apps professionally. I‘ve worked mainly with Vue and AngularJS in my job, but have dabbled in React through some side projects. So while I‘m quite familiar with Vue, I‘d consider myself a relative React novice. Keep that in mind as you read through my impressions!

Setting up the projects

To kick off my experiment, I scaffolded out a basic project for my To Do list app using the official CLI tools for each framework: create-react-app for React, and vue-cli for Vue. Both tools made the setup process pretty painless. They generated the necessary project files and configurations, so I could jump right into coding.

One minor difference I noticed is that create-react-app generates a few more files than vue-cli does by default (like a favicon and web app manifest). But overall, the setup process was very similar between the two.

Component Structure

Once I had my barebones projects ready, I started fleshing out the structure of my To Do app. In both React and Vue, you build the UI by defining reusable components—discrete pieces of the interface that manage their own state and rendering.

For my app, the component hierarchy looked like this:

- App
  - Header 
  - Input (for adding new To Do items)
  - List
    - List Item

The App component is the top-level parent that contains the rest of the components. Conceptually, React and Vue handle this component hierarchy quite similarly.

However, there are some notable differences in the syntax for defining components. Here‘s how a simple component looks in each framework:

React:

import React from ‘react‘;

class MyComponent extends React.Component {
  render() {
    return (
      <div>

      </div>  
    );
  }
}

export default MyComponent;

Vue:

<template>
  <div>

  </div>
</template>

<script>
export default {
  name: ‘MyComponent‘
}
</script>

As you can see, Vue uses a template-based approach where the component‘s structure is defined in a <template> tag using standard HTML. The component‘s JavaScript logic goes inside a <script> tag.

React, on the other hand, uses JSX—an XML-like extension of JavaScript. With JSX, you define a component‘s structure directly in the render function, mixing HTML-like tags with JavaScript code.

Personally, I found the Vue template syntax more intuitive to read and understand as a newcomer. It felt closer to plain HTML and kept the JavaScript logic nicely separated. However, I can see the appeal of JSX for more experienced React developers who are used to mixing markup with JavaScript.

Managing state

Next, let‘s look at how state is managed in the two frameworks. In my To Do app, the key piece of state is the list of to-do items. I needed a way to initialize the list in the app‘s state, and to update it whenever an item is added or removed.

Here‘s how I set up the initial state in the React version:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
  }
}

And here‘s the same thing in Vue:

export default {
  data() {
    return {
      items: []
    }
  }
}

The Vue version feels a bit simpler and more concise to me. React requires a constructor function to initialize state, while Vue just expects you to return an object from a data function.

To modify the state in React, you use the setState function:

addItem(newItem) {
  this.setState(prevState => ({
    items: [...prevState.items, newItem]
  }));
}

Whereas in Vue, you can directly mutate the state object:

addItem(newItem) {
  this.items.push(newItem);
}

Again, the Vue version is more concise and easier to follow for me. With React‘s setState, you have to make sure you‘re always passing an object that represents the new state, rather than mutating the previous state directly. This helps ensure your state updates are predictable, but it does add some extra verbosity to the code.

Passing data between components

Of course, state is only useful if you can pass it between components. In my app, I needed a way to pass the list of to-do items from the parent App component down to the child List component for rendering.

In React, you pass data to child components via "props":

<List items={this.state.items} />

Then in the child component, you access the props via this.props:

render() {
  const itemElements = this.props.items.map(item => (
    <li key={item.id}>{item.text}</li>
  ));

  return (
    <ul>{itemElements}</ul>
  );
}

In Vue, you also pass data down via props, but the syntax is a little different:

<List v-bind:items="items" />

And in the child component:

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.text }}
    </li>
  </ul>
</template>

<script>
export default {
  props: [‘items‘]
}
</script>

The Vue version uses a special v-bind directive to pass the data down as a prop. In the child component, you have to explicitly declare the props it accepts in the props option.

I found the Vue syntax a bit strange at first, but once I got used to it, I actually grew to prefer it over React‘s approach. I like that Vue makes you be explicit about the props a component accepts – it makes the component‘s interface more clear and self-documenting.

Event handling

The last key piece of functionality I had to implement was event handling – in particular, triggering the addItem and deleteItem functions when the user interacts with the UI.

In React, you attach event handlers using special prop names like onClick:

<button onClick={this.addItem}>Add Item</button>

In Vue, you use the v-on directive:

<button v-on:click="addItem">Add Item</button>

Both approaches work well, though I slightly prefer the terseness of Vue‘s v-on syntax. One nice thing about React‘s approach is that onClick and other event prop names mirror the actual DOM event names, so they feel familiar coming from plain JavaScript.

Final thoughts

After finishing my To Do apps in both React and Vue, I came away impressed by both frameworks. They have a lot in common conceptually, and both made it easy to build my app‘s functionality quickly.

However, as a relative newcomer to these frameworks, I found Vue somewhat easier and more intuitive to learn and use. Its template-based component syntax felt comfortable coming from an HTML background, and I appreciated its more concise and less verbose API compared to React.

That said, I can definitely see why React has become so popular. Its component model is incredibly powerful and flexible, and the ability to mix JavaScript logic directly into your component markup using JSX has its advantages.

Ultimately, I don‘t think you can go wrong with either framework. They‘re both excellent tools for building modern web UIs. If I had to pick one to use for my next project, I‘d probably lean towards Vue for its simplicity and gentle learning curve. But I‘m also excited to keep exploring React more deeply and growing my skills with both frameworks.

I hope this comparison has been helpful for any other developers out there considering React vs Vue! Let me know in the comments which framework you prefer and why.

Similar Posts