Desarrollo Web 5-8 minutos

NativePHP para Laravel 13: tu app web como aplicación de Windows, macOS y Linux

Diego Cortés
Diego Cortés
Full Stack Developer & SEO Specialist
Compartir:
NativePHP para Laravel 13: tu app web como aplicación de Windows, macOS y Linux
Imagen generada con IA

Tu app Laravel funciona en el navegador y ahora te piden "una app de escritorio": NativePHP empaqueta tu proyecto Laravel como aplicación nativa para Windows, macOS y Linux sin reescribir el frontend. Esta guía recorre instalación, primera ventana y empaquetado paso a paso.

Qué es NativePHP y por qué te puede servir

NativePHP es un ecosistema para construir aplicaciones de escritorio y móviles con Laravel: tu app Laravel se sirve en local y un runtime la abre en una ventana nativa, mientras el código PHP accede a funciones del sistema operativo con facades y clases. Para escritorio, la versión estable actual es NativePHP desktop v2, con documentación oficial separada de la de móvil porque cada plataforma tiene sus matices.

El caso típico es reconocible: el gestor interno que tu equipo usa a medias porque hay que abrir Chrome y teclear una URL, la herramienta que un cliente quiere instalada en su Mac o su Windows, el panel que debe notificar al usuario aunque la pestaña esté cerrada. Hasta hace unos años, cumplir ese requisito significaba aprender un stack nuevo o mantener un frontend de escritorio paralelo. NativePHP ataca justo ese problema: te quedas en Laravel.

Laravel como backend de escritorio: la misma app, otra ventana

Lo primero que hay que entender es que no construyes una aplicación nueva: la misma app Laravel, con sus rutas, controladores, Eloquent y colas, se sirve en local y se muestra dentro de una ventana nativa. Las vistas de Blade o los componentes de Livewire o Inertia se renderizan igual que en el navegador, porque técnicamente la ventana carga tu web. La diferencia está en la experiencia: el usuario ve un programa con su ícono, su menú y sus notificaciones del sistema, no una pestaña más.

Qué hay por debajo: el runtime y la ventana nativa

Para que eso ocurra, NativePHP desktop v2 empaqueta un runtime de escritorio, con Electron por debajo, junto con tu aplicación. No necesitas dominar Electron ni escribir JavaScript de puente: el runtime lo gestiona NativePHP y tu código sigue siendo PHP. Piensa en ello como un navegador de una sola pestaña que siempre abre tu app y que, además, te deja tocar el sistema operativo desde Laravel.

Cuándo tiene sentido pasar tu web a escritorio (y cuándo no)

NativePHP brilla cuando necesitas integración real con el sistema: menús de aplicación, notificaciones nativas que llegan aunque la ventana esté en segundo plano, diálogos de archivos o almacenamiento local persistente. También cuando quieres entregar un instalador a un cliente o a tu equipo sin montar un segundo proyecto. En cambio, si el requisito real es "acceso rápido" o "que funcione sin internet", una PWA instalable o una buena URL suelen bastar; lo vemos al final, porque es la decisión que más tiempo ahorra.

Requisitos y preparación

Qué necesitas: Laravel 13 con PHP actual y Node/NPM

Partimos de una app Laravel 13 funcionando. Si vienes de Laravel 12, repasa la guía de novedades y actualización a Laravel 13 antes de meterte en el escritorio. También necesitas PHP moderno, Composer 2 y Node con NPM, porque NativePHP compila los assets con Vite igual que tu web. No hace falta experiencia con Electron, Tauri ni lenguajes nativos.

Instalar el paquete de NativePHP y publicar config/nativephp.php

composer require nativephp/desktop

php artisan native:install

El primer comando instala el paquete del runtime de escritorio de NativePHP v2. El segundo, php artisan native:install, es el instalador: publica el service provider que arranca las dependencias del runtime Electron y publica la configuración en config/nativephp.php.

Qué añade la instalación a tu proyecto

Además del archivo de configuración, la instalación publica un service provider, el lugar natural para configurar menús y ventanas, y añade un script native:dev al composer.json. También registra php artisan native:install como post-update-cmd: después de cada composer update, el entorno de escritorio queda sincronizado sin que tengas que acordarte de nada.

Tu primera ventana: php artisan native:run

Arrancar la app en desarrollo como escritorio

Con el paquete instalado, el comando de desarrollo es php artisan native:run: levanta tu app Laravel en local y la abre dentro de la ventana nativa mostrando la home de tu proyecto. El consejo de la documentación oficial es sensato: antes de abrir la ventana, prueba la app en el navegador, porque las excepciones de arranque se ven mucho mejor en una pestaña que dentro del runtime.

Trabajar con Blade, Livewire o Inertia dentro de la ventana

Como la ventana carga tu web, todo tu frontend funciona igual. Si usas Livewire 4 o Inertia 3 con Laravel 13, los componentes responden igual dentro de la ventana; si usas Blade plano o Alpine, también. No hay una capa especial que aprender: lo que ves en el navegador es lo que ves en la ventana.

Funciones nativas desde PHP

Aquí está la gracia de NativePHP: las funciones del sistema operativo se llaman desde PHP con facades, sin mantener una capa de puente en JavaScript. La documentación agrupa las APIs por área (menús, ventanas, diálogos, notificaciones, portapapeles, atajos globales, sistema y más); con tres o cuatro ya cubres la mayoría de las aplicaciones de gestión.

Menú de aplicación con la facade de menús

El menú de la aplicación se configura en el boot del service provider que publicó la instalación, con la facade Menu. Este ejemplo monta los menús estándar de macOS y abre la primera ventana:

<?php

use Native\Desktop\Facades\Menu;
use Native\Desktop\Facades\Window;

public function boot(): void
{
    Menu::create(
        Menu::app(),   // solo en macOS
        Menu::file(),
        Menu::edit(),
        Menu::view(),
        Menu::window(),
    );

    Window::open();
}

Si no necesitas personalizar nada, Menu::default() monta el mismo conjunto con una línea. Para menús propios, la facade ofrece items como Menu::link(), Menu::route() o Menu::label(), que puedes anidar en submenús y asociar a rutas de Laravel o a URLs externas.

Notificaciones del sistema desde un controlador

Enviar una notificación nativa es directo desde cualquier controlador:

<?php

use Native\Desktop\Facades\Notification;

public function remind(): void
{
    Notification::title('Tarea por vencer')
        ->message('Revisa la lista antes de las 18:00')
        ->show();
}

Conviene distinguirla de las notificaciones de Laravel (las de base de datos, correo o cola): esta es una notificación del sistema operativo, la que aparece en el centro de notificaciones de macOS o Windows aunque tu ventana no esté enfocada. Ideal para avisar de una tarea completada, un respaldo terminado o un error silencioso.

Diálogos de archivos y otras APIs del sistema

Para pedir al usuario que elija un archivo o una carpeta, o que indique dónde guardar uno nuevo, usas la clase Dialog:

<?php

use Native\Desktop\Dialog;

$path = Dialog::new()
    ->title('Selecciona el archivo CSV')
    ->open();

El método open() devuelve la ruta elegida, o null si el usuario cancela, y save() devuelve la ruta donde quiere guardar. Es la base para importar inventarios, exportar reportes o abrir un proyecto concreto desde el disco.

Almacenamiento local seguro para los datos de la app

Para preferencias que deben sobrevivir al cierre de la aplicación, como la última carpeta abierta, el tema elegido o un token de sincronización, la facade Settings guarda valores en un archivo config.json dentro del directorio de datos de la app:

<?php

use Native\Desktop\Facades\Settings;

Settings::set('last_folder', $path);

$lastFolder = Settings::get('last_folder', '/');

En get() puedes pasar un valor por defecto, o un closure si el dato todavía no existe. Es el reemplazo natural del localStorage cuando necesitas persistencia del lado nativo; para datos realmente sensibles, revisa la guía de seguridad de NativePHP en lugar de guardar secretos en claro.

Empaquetar para producción: php artisan native:build

Build por plataforma: el instalador de cada sistema

Cuando la app está lista, php artisan native:build compila tu aplicación junto con el runtime Electron en un ejecutable único para la plataforma donde corres el comando: genera un .dmg en macOS, un setup.exe en Windows y un AppImage o .deb en Linux, con los artefactos de salida en la carpeta dist del proyecto. También puedes indicar la plataforma destino para compilar en cruz, por ejemplo php artisan native:build win desde un Mac. Eso sí, la documentación recomienda compilar y probar en cada sistema operativo real antes de distribuir: el build cruzado no sustituye una prueba nativa.

El archivo de configuración de la app: nombre, versión e identificadores

Antes de compilar revisa config/nativephp.php: ahí defines la versión de la app (NATIVEPHP_APP_VERSION), el app_id en formato de dominio inverso (NATIVEPHP_APP_ID) y otros valores con los que el sistema operativo identifica tu programa en el dock, el menú inicio o el instalador. Es la ficha de identidad del binario: cambiarla después complica las actualizaciones, así que merece la pena dejarla bien desde el primer build.

Secretos y .env dentro del binario: qué vigilar

Este es el punto que casi nadie menciona antes de que pierdas un fin de semana: al empaquetar, los archivos de tu proyecto, incluido el .env, viajan dentro del binario. Si tu .env contiene claves de producción reales, como las de la base de datos, Stripe o APIs de terceros, las estarías distribuyendo a cualquiera que abra el instalador. Para una app de escritorio local conviene un .env mínimo con credenciales generadas para ese despliegue, y nunca las mismas que usa tu servidor de producción. La documentación oficial tiene guías específicas de entornos y seguridad para este punto.

Limitaciones y alternativas honestas

Tamaño y memoria: el runtime va dentro de tu app

El precio de no mantener un segundo frontend es que el runtime de escritorio viaja dentro del binario: los instaladores pesan bastante más que una app web y, en ejecución, la aplicación consume más memoria que una pestaña del navegador. Para herramientas internas suele ser irrelevante; para apps que distribuyes en público, es un dato que conviene manejar antes de prometer algo ligero.

Firma de código y distribución pública

Distribuir en público tiene su propio trámite: macOS pide firma y notarización para evitar los avisos de Gatekeeper, y Windows muestra SmartScreen si el ejecutable no está firmado. Para distribución directa fuera de la Mac App Store hay vías sin certificado de desarrollador, pero el usuario verá advertencias. Si tu plan es vender o regalar la app en abierto, presupuesta la firma desde el principio y no la improvises al final.

¿Y si solo necesitas una PWA o una URL?

La pregunta más honesta es si necesitas NativePHP o solo una mejor web. Una PWA instalable se abre desde el escritorio, funciona sin conexión con un service worker y pesa nada; una URL bien puesta en el dock de tu equipo también resuelve muchos "¿me haces una app?". NativePHP aporta cuando de verdad necesitas integración con el sistema operativo, menús, notificaciones nativas, archivos locales o un instalador que entregar, o cuando el cliente no va a aceptar "abre Chrome y teclea esto". Si no es tu caso, ahorra el runtime.

Conclusión

El camino de la web al escritorio con NativePHP es corto: instalas el paquete, ejecutas native:install, corres native:run y en menos de una hora ya estás viendo tu app Laravel en una ventana nativa. Después añades menú, notificaciones y almacenamiento con facades de PHP, y cuando el cliente lo pide, native:build te deja el instalador de su plataforma. Si mañana el requisito salta al móvil, NativePHP Mobile extiende el mismo enfoque a iOS y Android reutilizando la lógica Laravel que ya tienes. En este blog seguimos cubriendo Laravel 13 con guías prácticas: si te quedas con ganas de más, pásate por los artículos de desarrollo web.

Categorías