React es una librería de JavaScript para construir interfaces de usuario, y Angular es un framework completo para construir aplicaciones web. Con React escribes componentes como funciones que devuelven JSX y eliges herramientas aparte para el enrutamiento, los formularios y los datos; con Angular escribes clases de TypeScript con plantillas HTML y recibes de serie enrutamiento, formularios, un cliente HTTP e inyección de dependencias. Aquí está el mismo contador en ambos.
La versión Angular de ese componente:
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">Clicked {{ count() }} times</button>
`,
})
export class CounterComponent {
count = signal(0);
increment() {
this.count.update((n) => n + 1);
}
}
Las ideas se corresponden una a una: el useState(0) de React es el signal(0) de Angular, onClick={...} es (click)="...", y {count} es {{ count() }}. La diferencia es dónde vive el código: una función que devuelve marcado en React, una clase más una cadena de plantilla en Angular.
Librería vs framework
Esta es la diferencia que explica casi todas las demás. React cubre el renderizado y el estado de los componentes. Todo lo demás lo eliges tú:
- Enrutamiento: React Router, TanStack Router, o las rutas basadas en archivos de un framework.
- Obtención de datos:
fetchen un efecto, TanStack Query, o los loaders y server components de un framework. - Formularios: inputs controlados simples, acciones de formulario de React 19, o React Hook Form.
- Estado global: contexto, Zustand, Redux Toolkit, Jotai.
Muchos equipos se saltan la mayoría de esas decisiones empezando con un framework de React como Next.js o React Router en modo framework, que incluye enrutamiento, carga de datos y renderizado en el servidor.
Angular toma esas decisiones por ti: @angular/router, formularios reactivos y basados en plantillas, HttpClient, inyección de dependencias, una configuración de pruebas y la CLI ng que genera componentes y servicios. Todos los proyectos de Angular se parecen bastante, que es una razón habitual por la que las organizaciones grandes lo eligen. El costo es una superficie más grande que aprender y menos libertad para cambiar una pieza.
JSX vs plantillas
Los componentes de React devuelven JSX, que es JavaScript. Las condiciones son && o un ternario, las listas son .map(), y todo lo que puedes hacer en JavaScript lo puedes hacer en el marcado. Las plantillas de Angular son HTML con su propia sintaxis: @if, @for con track, bindings [property], bindings (event) e interpolación {{ }}. Las plantillas mantienen el marcado y la lógica visiblemente separados; JSX los mantiene en un solo lugar y te da el lenguaje completo. Aquí tienes una lista filtrada, la segunda funcionalidad a comparar.
Escribe an en la caja y mira la consola: toda la función se vuelve a ejecutar en cada pulsación, y visible simplemente se vuelve a calcular. El mismo componente en Angular, con la plantilla en su propio archivo:
import { Component, computed, signal } from '@angular/core';
@Component({
selector: 'app-fruit-filter',
templateUrl: './fruit-filter.component.html',
})
export class FruitFilterComponent {
fruits = ['Apple', 'Banana', 'Cherry', 'Grape', 'Mango', 'Peach'];
query = signal('');
visible = computed(() =>
this.fruits.filter((f) => f.toLowerCase().includes(this.query().toLowerCase()))
);
}
<input #box [value]="query()" (input)="query.set(box.value)" placeholder="Filter fruit" />
<ul>
@for (fruit of visible(); track fruit) {
<li>{{ fruit }}</li>
} @empty {
<li>No match</li>
}
</ul>
En Angular, computed declara que visible depende de query, así que Angular sabe qué plantilla lo lee y vuelve a calcular visible solo cuando cambia query. En React no hay declaración: el componente se vuelve a ejecutar y vuelve a calcular. El key={fruit} de React y el track fruit de Angular hacen el mismo trabajo: le dicen al framework qué elemento de la lista es cuál.
Primero JavaScript vs primero TypeScript
React es JavaScript puro con JSX, y TypeScript es una opción que agregas (npm create vite@latest my-app -- --template react-ts). La mayoría de los proyectos nuevos de React lo agregan, pero puedes aprender React sin saber de tipos. Angular está construido para TypeScript: los decoradores, la inyección de dependencias y el comprobador de tipos de las plantillas lo dan por hecho. Si tu equipo ya escribe código tipado, no es un problema; si eres nuevo en la programación, es una cosa más que aprender a la vez. La página de React con TypeScript muestra cómo funcionan los tipos del lado de React.
Flujo de datos y detección de cambios
Ambos pasan datos hacia abajo mediante inputs (props en React, input() o @Input() en Angular) y envían eventos hacia arriba mediante callbacks (funciones pasadas como props en React, output() o @Output() en Angular). La diferencia es cómo nota cada uno un cambio.
React trata el estado como instantáneas inmutables. Llamas a un setter con un valor nuevo, React vuelve a ejecutar la función del componente, compara el JSX nuevo con el viejo y parchea el DOM. Nada se sigue automáticamente: la función de renderizado es el grafo de dependencias. Es fácil de razonar, y el costo es que a veces agregas memo, useMemo o useCallback (o dejas que el React Compiler los agregue) para ahorrar trabajo.
Angular usaba históricamente Zone.js para detectar cualquier evento async y luego revisaba el árbol de componentes en busca de bindings que hubieran cambiado. El Angular moderno se está pasando a los signals: signal, computed y effect siguen qué valores lee cada plantilla, así que Angular revisa solo los componentes cuyos signals cambiaron, y las versiones recientes pueden funcionar sin Zone.js por completo. Las plantillas de Angular no vuelven a ejecutar una función completa en cada cambio como hacen los componentes de React.
En el código del día a día los dos se sienten más parecidos de lo que sugiere su mecánica: guardas estado, derivas valores a partir de él y la pantalla lo sigue.
Gestión del estado
En React, el estado local es useState o useReducer, el estado compartido se eleva a un padre o se pone en contexto, y el estado global de la app suele vivir en una pequeña librería de store. En Angular, el estado local son signals en el componente, y el estado compartido suele vivir en un servicio que se inyecta donde se necesite; la inyección de dependencias es la respuesta integrada de Angular a "cómo comparten datos dos componentes lejanos". NgRx existe para los equipos que quieren un store al estilo Redux. React no tiene un sistema de inyección de dependencias; el contexto cumple un papel parecido.
Tabla comparativa
| React | Angular | |
|---|---|---|
| Qué es | Librería de UI | Framework de aplicaciones completo |
| Lenguaje | JavaScript o TypeScript | TypeScript |
| Marcado | JSX dentro de JavaScript | Plantillas HTML con sintaxis de Angular |
| Forma de un componente | Función que devuelve JSX | Clase con un decorador y una plantilla |
| Estado local | useState, useReducer | Signals (signal, computed) |
| Cómo ocurren las actualizaciones | El componente se vuelve a ejecutar y React compara el resultado | Los signals y la detección de cambios actualizan los bindings |
| Estado compartido | Props, contexto, una librería de store | Servicios inyectados, signals, NgRx |
| Enrutamiento | Librería aparte o framework | Integrado (@angular/router) |
| Formularios | Lo que elijas, más las acciones de formulario de React 19 | Integrados (formularios reactivos y de plantilla) |
| HTTP | fetch o una librería | Integrado (HttpClient) |
| Inyección de dependencias | Ninguna (lo más parecido es el contexto) | Integrada |
| Herramientas | Vite o la CLI de un framework | Angular CLI (ng) |
| Renderizado en el servidor | Next.js, React Router en modo framework | Angular SSR |
| Apps móviles | React Native | Ionic con Capacitor, NativeScript |
| Mantenido por | Meta y la comunidad |
Curva de aprendizaje
Con React se empieza más rápido. Un principiante que sabe JavaScript puede construir algo real después de aprender componentes, props, estado y efectos, y la página de qué es React cubre toda la idea en pocos minutos. El aprendizaje se traslada a después: tienes que elegir un router, un enfoque para obtener datos y una estrategia de formularios, y cada código de React toma decisiones distintas.
Angular tiene un comienzo más empinado: TypeScript, decoradores, plantillas, signals, inyección de dependencias, los módulos de router y formularios, y RxJS para algunas APIs. Pero una vez que lo conoces, todos los proyectos de Angular usan las mismas piezas de la misma forma, así que moverse entre proyectos es más fácil.
Cuándo elegir cuál
Elige React cuando:
- Quieres un núcleo pequeño y libertad para elegir el resto, o quieres un framework como Next.js para el renderizado en el servidor y las rutas basadas en archivos.
- Piensas construir también apps móviles, donde React Native reutiliza el mismo modelo de componentes.
- El equipo se siente cómodo sobre todo con JavaScript, o estás aprendiendo desarrollo frontend y quieres el camino más corto hacia una app que funcione.
Elige Angular cuando:
- Un equipo grande necesita una estructura estándar en muchos proyectos, con menos decisiones de arquitectura que discutir.
- Quieres que los formularios, HTTP, el enrutamiento y la inyección de dependencias los mantenga un solo equipo, y que la CLI los actualice juntos.
- El equipo ya escribe TypeScript y le gustan los servicios basados en clases y una separación clara entre plantilla y lógica.
Ambos son maduros, se usan mucho en producción y son buenos para una carrera. Las habilidades se trasladan: componentes, flujo de datos en una dirección, estado derivado y actualizaciones reactivas son las mismas ideas en ambos.
Preguntas frecuentes
¿Qué es mejor, React o Angular?
Ninguno es mejor en general. Angular te da un conjunto de herramientas completo y con opiniones fuertes, que encaja con equipos grandes que quieren la misma estructura en cada proyecto. React te da un núcleo pequeño y libertad para elegir el resto, que encaja con equipos que quieren flexibilidad o un framework como Next.js.
¿React es más fácil de aprender que Angular?
Normalmente sí, al principio. El núcleo de React son componentes, props, estado y unos pocos hooks, todo en JavaScript. Angular te pide aprender TypeScript, decoradores, plantillas, inyección de dependencias, signals y el módulo que elijas para formularios y HTTP antes de construir mucho. Después, Angular necesita menos decisiones.
¿Angular es un framework y React una librería?
Sí. Angular incluye enrutamiento, formularios, un cliente HTTP, inyección de dependencias, configuración de pruebas y una CLI como un solo framework. React solo renderiza UI; el enrutamiento, la obtención de datos y los formularios vienen de librerías aparte o de un framework de React como Next.js o React Router.
¿Angular usa TypeScript y React usa JavaScript?
Angular está pensado para TypeScript y sus herramientas lo dan por hecho. React funciona igual de bien con JavaScript puro y con TypeScript; la mayoría de los proyectos nuevos de React eligen TypeScript, pero es opcional.
¿Puedo pasar de Angular a React?
Sí, los conceptos se trasladan: componentes, inputs (props), outputs (props de callback) y estado reactivo. Los ajustes principales son JSX en lugar de plantillas, hooks en lugar de miembros de clase, y elegir librerías para el enrutamiento y los formularios.