Indice Tutorial >>
- Tutorial de Tauri - Capítulo 1: Qué es Tauri y por qué deberías aprenderlo
- Tutorial de Tauri - Capítulo 2: Configuración del Entorno de Desarrollo
- Tutorial de Tauri - Capítulo 3: Tu primera aplicación Tauri
- Tauri 2.0: Aplicaciones de Escritorio con React y Rust — Ya disponible en Amazon
- Tauri vs Electron: ¿cuál elegir para tu aplicación de escritorio en 2026?
- Tutorial de Tauri - Capítulo 4: Estructura de un proyecto Tauri
- Tutorial de Tauri - Capítulo 5: Integración con React
- Tutorial de Tauri - Capítulo 6: Rust básico para desarrolladores web
- Tutorial de Tauri - Capítulo 7: Commands - Comunicación de JavaScript a Rust
- Tutorial de Tauri - Capítulo 8: Eventos - Comunicación bidireccional
- Tutorial de Tauri - Capítulo 9: Acceso al sistema de archivos
- Tutorial de Tauri - Capítulo 10: Bases de datos con SQLite
- Tutorial de Tauri - Capítulo 11: Menús, diálogos y bandejas del sistema
- Tutorial de Tauri - Capítulo 12: Proyecto práctico - Aplicación de notas
Una de las razones principales para usar una aplicación de escritorio es el acceso al sistema de archivos. Las aplicaciones web no pueden leer ni escribir archivos en tu ordenador, pero con Tauri sí puedes.
En este capítulo vamos a crear un proyecto nuevo para construir un editor de notas sencillo que guarde y cargue archivos de verdad.
Crear el proyecto
Si tienes la aplicación anterior ejecutándose, párala con Ctrl+C en la terminal. Vamos a crear un proyecto nuevo para empezar limpio.
Abre la terminal y ejecuta:
npm create tauri-app@latest
Responde a las preguntas:
- Project name: tauri-notas
- Identifier: com.tutorial.taurinotas
- Frontend language: TypeScript / JavaScript
- Package manager: npm
- UI template: React
- UI flavor: JavaScript
Entra en el proyecto e instala las dependencias:
cd tauri-notas
npm install
Instalar el plugin de sistema de archivos
Tauri 2.0 usa un sistema de plugins para funcionalidades extra. El acceso al sistema de archivos no viene incluido por defecto — necesitas instalar el plugin fs. Ejecuta este comando desde la raíz del proyecto:
npm run tauri add fs
Este comando hace todo automáticamente:
- Instala el paquete npm
@tauri-apps/plugin-fs - Añade
tauri-plugin-fsa las dependencias desrc-tauri/Cargo.toml - Registra el plugin en
src-tauri/src/lib.rs
Si quieres verificar que todo se ha instalado, abre src-tauri/src/lib.rs. Deberías ver algo como:
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_opener::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
La línea .plugin(tauri_plugin_fs::init()) es la que activa el plugin. Si no aparece, añádela manualmente.
Configurar permisos
Tauri tiene un sistema de seguridad que impide que tu aplicación acceda a archivos sin permiso explícito. Esto es una ventaja: el usuario sabe exactamente qué puede hacer tu app.
Los permisos se configuran en el archivo src-tauri/capabilities/default.json. Ábrelo y reemplaza su contenido por:
{
"identifier": "default",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default",
{
"identifier": "fs:allow-read-text-file",
"allow": [{ "path": "$APPDATA/**" }]
},
{
"identifier": "fs:allow-write-text-file",
"allow": [{ "path": "$APPDATA/**" }]
},
{
"identifier": "fs:allow-exists",
"allow": [{ "path": "$APPDATA/**" }]
},
{
"identifier": "fs:allow-mkdir",
"allow": [{ "path": "$APPDATA" }, { "path": "$APPDATA/**" }]
}
]
}
Veamos qué significa cada permiso:
core:default: permisos básicos de Tauri (ventana, commands, etc.)opener:default: permite abrir enlaces externos (viene por defecto en proyectos nuevos)fs:allow-read-text-file: permite leer archivos de texto en las carpetas especificadas enallowfs:allow-write-text-file: permite escribir archivos de textofs:allow-exists: permite comprobar si un archivo existefs:allow-mkdir: permite crear carpetas"allow": [{ "path": "$APPDATA/**" }]: es el scope, que limita cada permiso a la carpeta de datos de la app. Sin el scope, Tauri bloquea el acceso por seguridad. El**significa «esta carpeta y todas las subcarpetas».
Directorios seguros (BaseDirectory)
Tu aplicación no puede acceder a cualquier carpeta del sistema. Tauri limita el acceso a directorios específicos y seguros. Cada uno tiene un nombre que usarás en tu código:
| BaseDirectory | Descripción | Ejemplo en macOS |
|---|---|---|
| AppData | Datos de tu aplicación | ~/Library/Application Support/com.tutorial.taurinotas |
| AppConfig | Configuración de tu app | ~/Library/Application Support/com.tutorial.taurinotas |
| Document | Carpeta Documentos del usuario | ~/Documents |
| Download | Carpeta Descargas | ~/Downloads |
| Desktop | Escritorio | ~/Desktop |
| Temp | Carpeta temporal | /tmp |
Para nuestro editor de notas usaremos AppData, que es la carpeta propia de tu aplicación. Es el lugar correcto para guardar datos que la app necesita recordar.
Construir el editor de notas
Vamos a crear un editor de notas sencillo que:
- Cargue la nota guardada al abrir la app
- Guarde el contenido en un archivo cuando pulses «Guardar»
- Muestre un mensaje de confirmación al guardar
Primero, borra los archivos que no necesitamos. Elimina src/App.css y el contenido por defecto de src/assets/ si quieres empezar limpio (es opcional).
Ahora crea el componente del editor. Crea el archivo src/EditorNotas.jsx:
import { useState, useEffect } from "react";
import {
readTextFile,
writeTextFile,
exists,
mkdir,
BaseDirectory,
} from "@tauri-apps/plugin-fs";
function EditorNotas() {
const [nota, setNota] = useState("");
const [guardando, setGuardando] = useState(false);
const [mensaje, setMensaje] = useState("");
// Al montar el componente, cargar la nota guardada
useEffect(() => {
cargarNota();
}, []);
async function cargarNota() {
try {
// Comprobar si el archivo existe antes de leerlo
const hayArchivo = await exists("mi-nota.txt", {
baseDir: BaseDirectory.AppData,
});
if (hayArchivo) {
const contenido = await readTextFile("mi-nota.txt", {
baseDir: BaseDirectory.AppData,
});
setNota(contenido);
setMensaje("Nota cargada");
} else {
setMensaje("No hay nota guardada. Escribe algo y pulsa Guardar.");
}
} catch (error) {
console.error("Error cargando la nota:", error);
setMensaje("Error al cargar la nota");
}
}
async function guardarNota() {
setGuardando(true);
try {
// Crear la carpeta AppData si no existe
await mkdir("", {
baseDir: BaseDirectory.AppData,
recursive: true,
});
// Escribir el archivo
await writeTextFile("mi-nota.txt", nota, {
baseDir: BaseDirectory.AppData,
});
setMensaje("Nota guardada correctamente");
} catch (error) {
console.error("Error guardando:", error);
setMensaje("Error al guardar la nota");
}
setGuardando(false);
}
return (
<div style={{ maxWidth: "600px", margin: "0 auto", padding: "2rem" }}>
<h1>Editor de Notas</h1>
<textarea
value={nota}
onChange={(e) => setNota(e.target.value)}
placeholder="Escribe tu nota aquí..."
rows={12}
style={{
width: "100%",
padding: "1rem",
fontSize: "1rem",
borderRadius: "8px",
border: "1px solid #444",
background: "#2a2a2a",
color: "white",
resize: "vertical",
}}
/>
<div style={{ marginTop: "1rem", display: "flex", alignItems: "center", gap: "1rem" }}>
<button
onClick={guardarNota}
disabled={guardando}
style={{
padding: "0.8rem 2rem",
background: "#24c8db",
color: "#1a1a1a",
border: "none",
borderRadius: "8px",
fontWeight: "bold",
cursor: "pointer",
}}
>
{guardando ? "Guardando..." : "Guardar"}
</button>
<span>{mensaje}</span>
</div>
</div>
);
}
export default EditorNotas;
Veamos qué hace cada parte del código:
import { readTextFile, writeTextFile, exists, mkdir, BaseDirectory } from "@tauri-apps/plugin-fs": importamos las funciones del plugin de archivos. Fíjate en que se importan de@tauri-apps/plugin-fs, no de@tauri-apps/api.useEffect(() => { cargarNota(); }, []): al abrir la app, intenta cargar la nota guardada.exists("mi-nota.txt", { baseDir: BaseDirectory.AppData }): comprueba si el archivo existe antes de intentar leerlo. Si no lo comprobáramos y el archivo no existe, daría error.readTextFile("mi-nota.txt", { baseDir: ... }): lee el contenido del archivo de texto. ElbaseDirle dice a Tauri en qué carpeta buscar.mkdir("", { baseDir: BaseDirectory.AppData, recursive: true }): crea la carpeta de datos de la app si no existe. La primera vez que ejecutas la app, esta carpeta puede no existir todavía.writeTextFile("mi-nota.txt", nota, { baseDir: ... }): escribe el contenido del textarea en el archivo.
Ahora abre src/App.jsx y reemplaza todo su contenido por:
import EditorNotas from "./EditorNotas";
function App() {
return <EditorNotas />;
}
export default App;
Ejecuta la aplicación:
npm run tauri dev
Escribe algo en el textarea y pulsa «Guardar». Cierra la aplicación y vuelve a abrirla — tu nota seguirá ahí, cargada desde el archivo.

Referencia: otras operaciones con archivos
El plugin de archivos ofrece más funciones además de leer y escribir. No las necesitas para el editor de notas, pero te serán útiles en proyectos futuros:
import {
readDir,
remove,
rename,
copyFile,
BaseDirectory,
} from "@tauri-apps/plugin-fs";
// Listar archivos de una carpeta
const archivos = await readDir("", {
baseDir: BaseDirectory.Document,
});
archivos.forEach((archivo) => {
console.log(archivo.name); // nombre de cada archivo
});
// Eliminar un archivo
await remove("archivo-viejo.txt", {
baseDir: BaseDirectory.AppData,
});
// Renombrar un archivo
await rename("nombre-viejo.txt", "nombre-nuevo.txt", {
oldPathBaseDir: BaseDirectory.AppData,
newPathBaseDir: BaseDirectory.AppData,
});
// Copiar un archivo
await copyFile("original.txt", "copia.txt", {
fromPathBaseDir: BaseDirectory.AppData,
toPathBaseDir: BaseDirectory.AppData,
});
Resumen
En este capítulo has aprendido a:
- Instalar plugins de Tauri con
npm run tauri add - Configurar permisos en
capabilities/default.json - Usar
BaseDirectorypara acceder a carpetas seguras - Leer archivos con
readTextFile - Escribir archivos con
writeTextFile - Comprobar si un archivo existe con
exists - Crear carpetas con
mkdir
En el próximo capítulo trabajaremos con bases de datos SQLite para guardar datos estructurados.
¿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.
