Saltar al contenido

Rust para desarrolladores de JavaScript: el salto que vale la pena dar

Andrés Ujpán
Fecha de publicación:
2 min de lectura

Rust apareció en el radar de los desarrolladores web hace años, pero la adopción fue lenta. En 2026 el panorama cambió: Rust impulsa herramientas críticas en el ecosistema JS (Biome, Oxc, Rolldown, el compilador SWC) y WebAssembly lo hace indispensable en el frontend. Es hora de aprenderlo.

Tabla de contenido

El mayor cambio de mentalidad: ownership

En JavaScript, el recolector de basura (garbage collector) gestiona la memoria. En Rust, la responsabilidad pasa al compilador a través del sistema de ownership (propiedad).

// In JS: this works
// let a = [1, 2, 3];
// let b = a; // a is still valid

// In Rust:
fn main() {
    let a = vec![1, 2, 3];
    let b = a;          // a is "moved" to b
    println!("{:?}", a); // ✗ ERROR: a was moved
    println!("{:?}", b); // ✓
}ownership.rs

La solución: borrowing (préstamo) con referencias.

fn main() {
    let a = vec![1, 2, 3];
    let b = &a;          // immutable borrow
    println!("{:?}", a); // ✓ a is still valid
    println!("{:?}", b); // ✓
}

fn print_vec(v: &Vec<i32>) { // receives reference, not ownership
    for n in v {
        print!("{} ", n);
    }
}borrowing.rs

Tipos: de any al sistema más seguro del mundo

JavaScript/TypeScriptEquivalente en Rust
numberi32, u32, f64, …
stringString (heap) / &str (slice)
T | nullOption<T>
T | ErrorResult<T, E>
any[]Vec<T>
{ [key: string]: T }HashMap<String, T>
fn divide(a: f64, b: f64) -> Option<f64> {
    if b == 0.0 {
        None   // equivalent to null without the billion-dollar mistake
    } else {
        Some(a / b)
    }
}

fn main() {
    match divide(10.0, 0.0) {
        Some(result) => println!("Result: {result}"),
        None => println!("Division by zero"),
    }
}types.rs

Manejo de errores: Result es la Promise of Rust

En JS manejas los errores con try/catch o cadenas de Promise. En Rust, Result<T, E> es la forma idiomática:

use std::fs;
use std::io;

// Before: without the ? operator
fn read_config_verbose() -> Result<String, io::Error> {
    let content = match fs::read_to_string("config.toml") { 
        Ok(c) => c,                                            
        Err(e) => return Err(e),                               
    };                                                         
    Ok(content.to_uppercase())
}

// With the ? operator (equivalent to JS await, but for errors)
fn read_config() -> Result<String, io::Error> {               
    let content = fs::read_to_string("config.toml")?;       
    Ok(content.to_uppercase())                               
}errors.rs

Closures y funciones de orden superior

La sintaxis es diferente pero el concepto es idéntico:

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // map + filter + collect (like Array.map + filter in JS)
    let double_evens: Vec<i32> = numbers
        .iter()
        .filter(|&&x| x % 2 == 0)  
        .map(|&x| x * 2)            
        .collect();

    println!("{:?}", double_evens); // [4, 8]
}closures.rs

Rust → WebAssembly: el puente al frontend

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n - 1) + fibonacci(n - 2),
    }
}lib.rs
# Compile to WASM
wasm-pack build --target web
import init, { fibonacci } from "./pkg/my_project.js";

await init();
console.log(fibonacci(40)); // ~10x faster than pure JS versionmain.js

Dónde empezar

  1. The Rust Book: la mejor documentación de cualquier lenguaje.
  2. Rustlings: ejercicios interactivos en la terminal.
  3. Rust by Example: aprende con ejemplos reales.
  4. Construye algo con wasm-pack y úsalo desde tu proyecto web actual.

La curva de aprendizaje es real, pero el compilador de Rust es el mejor maestro que encontrarás: sus mensajes de error son detallados, precisos y casi siempre incluyen la solución.

Artículo Anterior
TypeScript 5.x: características que cambian cómo escribes código
Fecha de publicación:
2 min de lectura
Lectura Recomendada
React 19: useActionState, useOptimistic y el fin de los estados de carga manuales
Fecha de publicación:
1 min de lectura
100%