Tutorial de Tauri – Capítulo 4: Estructura de un proyecto Tauri

Ahora que tienes tu primera aplicación funcionando, es momento de entender qué hay dentro. Conocer la estructura del proyecto te ayudará a saber dónde tocar cuando quieras modificar algo.

Vista general

Un proyecto Tauri tiene esta estructura:

hola-mundo-tauri/
├── src/                    # Frontend (HTML, CSS, JS)
│   ├── assets/
│   │   ├── javascript.svg
│   │   └── tauri.svg
│   ├── index.html
│   ├── main.js
│   └── styles.css
├── src-tauri/              # Backend (Rust)
│   ├── capabilities/
│   │   └── default.json
│   ├── icons/
│   ├── src/
│   │   ├── lib.rs
│   │   └── main.rs
│   ├── build.rs
│   ├── Cargo.toml
│   └── tauri.conf.json
└── package.json

He omitido algunos archivos que se generan automáticamente (node_modules/, target/, Cargo.lock, package-lock.json, etc.) para centrarnos en lo importante.

El proyecto está dividido en dos partes claramente separadas:

  • src/: El frontend, tu código web
  • src-tauri/: El backend, código Rust y configuración de Tauri

El frontend (src/)

Aquí vive todo el código de la interfaz de usuario. Es exactamente igual que cualquier proyecto web:

  • index.html: El punto de entrada, el HTML que verá el usuario
  • main.js: Tu código JavaScript
  • styles.css: Los estilos CSS
  • assets/: Recursos estáticos (imágenes, iconos SVG, etc.)

Esta carpeta puede tener la estructura que quieras. Si usas React, Vue o Svelte, los componentes irán aquí. Tauri no te impone ninguna restricción sobre cómo organizas tu frontend.

El backend (src-tauri/)

Aquí está la magia de Tauri. Contiene el código Rust y toda la configuración del framework.

src/lib.rs

El punto de entrada del backend. Aquí defines la lógica de tu aplicación:

#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_opener::init())
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Vamos por partes:

El command greet: Es una función Rust que puede ser llamada desde JavaScript. El atributo #[tauri::command] la convierte en un «command» de Tauri. Este es el mecanismo principal de comunicación entre frontend y backend.

La función run(): Configura e inicia la aplicación:

  • tauri::Builder::default() crea la aplicación con configuración base
  • .plugin(tauri_plugin_opener::init()) registra el plugin para abrir enlaces externos
  • .invoke_handler(tauri::generate_handler![greet]) registra los commands disponibles
  • .run(tauri::generate_context!()) carga la configuración e inicia la app

En el capítulo de Commands profundizaremos en cómo crear tus propias funciones y llamarlas desde JavaScript.

Cargo.toml

Es el equivalente a package.json pero para Rust. Define las dependencias y metadatos:

[package]
name = "hola-mundo-tauri"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"

[lib]
name = "hola_mundo_tauri_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

Las secciones importantes:

  • [package]: Metadatos del proyecto (nombre, versión, autor)
  • [lib]: Configuración de la biblioteca Rust
  • [build-dependencies]: Dependencias necesarias para compilar (tauri-build)
  • [dependencies]: Las librerías que usa tu aplicación

Cuando necesites añadir plugins (acceso a archivos, base de datos, etc.), añadirás las dependencias aquí.

tauri.conf.json

Este es el archivo de configuración más importante. Controla el comportamiento de tu aplicación:

{
  "$schema": "https://schema.tauri.app/config/2",
  "productName": "hola-mundo-tauri",
  "version": "0.1.0",
  "identifier": "com.tauri.dev",
  "build": {
    "frontendDist": "../src"
  },
  "app": {
    "withGlobalTauri": true,
    "windows": [
      {
        "title": "hola-mundo-tauri",
        "width": 800,
        "height": 600
      }
    ],
    "security": {
      "csp": null
    }
  },
  "bundle": {
    "active": true,
    "targets": "all",
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ]
  }
}

Las secciones más importantes:

SecciónQué controla
productNameNombre de la aplicación
identifierID único (com.empresa.app)
build.frontendDistDónde está tu código frontend
app.withGlobalTauriExpone la API de Tauri globalmente en JavaScript
app.windowsConfiguración de ventanas (tamaño, título)
bundleOpciones de empaquetado e iconos

La carpeta capabilities/

Esta es una novedad importante de Tauri 2.0. Aquí defines los permisos de tu aplicación.

El archivo default.json se ve así:

{
  "identifier": "default",
  "description": "Permisos para la ventana principal",
  "windows": ["main"],
  "permissions": [
    "core:default"
  ]
}

Por defecto, tu aplicación tiene permisos mínimos. Si quieres acceder al sistema de archivos, mostrar notificaciones o usar otras APIs, tendrás que añadir los permisos correspondientes aquí.

Este sistema de seguridad por defecto es una de las grandes ventajas de Tauri sobre Electron.

La carpeta icons/

Contiene los iconos de tu aplicación en diferentes formatos:

  • .ico para Windows
  • .icns para macOS
  • .png en varios tamaños para Linux

Tauri incluye un comando para generar todos los formatos desde una imagen:

npm run tauri icon ruta/a/tu/icono.png

Cómo se conectan frontend y backend

El frontend y el backend están separados pero se comunican mediante un puente:

  1. El frontend se ejecuta dentro de un WebView (navegador embebido)
  2. El backend se ejecuta como proceso nativo de Rust
  3. Se comunican mediante commands (JavaScript llama a Rust) y events (comunicación bidireccional)

El paquete @tauri-apps/api proporciona las funciones JavaScript para esta comunicación.

Archivos de la raíz

package.json

El archivo estándar de npm con tus dependencias y scripts:

{
  "name": "hola-mundo-tauri",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "tauri": "tauri"
  },
  "devDependencies": {
    "@tauri-apps/cli": "^2"
  }
}

Los campos importantes:

  • type: "module": Permite usar imports de ES6
  • scripts.tauri: El comando para ejecutar Tauri
  • @tauri-apps/cli: La herramienta de línea de comandos de Tauri

Los comandos que usarás:

  • npm run tauri dev: Inicia la aplicación en modo desarrollo
  • npm run tauri build: Compila para producción

Resumen

La estructura de un proyecto Tauri es clara:

  • Frontend: Tu código web en src/
  • Backend: Código Rust y configuración en src-tauri/
  • tauri.conf.json: El cerebro de la configuración
  • capabilities/: Sistema de permisos

En el próximo capítulo integraremos React con Tauri para crear interfaces más potentes.

Nos vemos en el Capítulo 5.


¿Te está gustando este tutorial?

Este tutorial forma parte del libro Tauri 2.0: Aplicaciones de Escritorio con React y Rust, disponible en Amazon en formato papel y ebook. El libro incluye todos los capítulos, tres proyectos completos paso a paso y contenido exclusivo que no encontrarás en el blog.

Un saludo, y si aún no lo has hecho no olvides suscribirte a mi blog para no perderte los próximos posts  :-),

También puedes seguirme en Twitter en ‎@revi_apps y no olvides que me ayudas mucho si compartes este post en las redes sociales.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Scroll al inicio