Cada vez que empiezo una app iOS que necesita algo más que guardar datos en local, me toca montar lo mismo: registro e inicio de sesión, Sign in with Apple, notificaciones push, algún tipo de pago y, últimamente, un chat con IA. Nada de eso es difícil por separado, pero juntarlo bien (tokens que caducan, claves .p8, webhooks firmados, streaming…) se come fácilmente una semana.
Así que lo he empaquetado: el iOS Backend Starter es un backend en Node.js + TypeScript y una app de ejemplo en SwiftUI que ya hablan entre sí. Lo descomprimes, sigues la guía y en unos 20 minutos tienes el servidor y la app funcionando en tu Mac, sin necesitar todavía cuenta de Apple Developer, ni Stripe, ni Ollama.
Qué incluye
1. Login completo y Sign in with Apple verificado en servidor
Registro con email y contraseña (bcrypt), JWT de acceso de corta duración y refresh tokens que rotan en cada uso: si alguien reutiliza un refresh token antiguo, el servidor lo detecta como robo y cierra todas las sesiones de ese usuario. Sign in with Apple se valida en el backend contra las claves públicas de Apple, con nonce, y el borrado de cuenta (que Apple exige si permites crear cuentas) ya viene hecho.
En la app, los tokens se guardan en el Llavero. Si quieres entender por qué no en UserDefaults, lo expliqué en cómo almacenar tokens de forma segura con el Keychain en Swift.
2. Notificaciones push sin Firebase
Un cliente APNs nativo sobre HTTP/2 que firma con tu clave .p8 (ES256), reutiliza la conexión y el JWT, y borra automáticamente los tokens de dispositivos que Apple marca como inválidos. Soporta también Live Activities. Para probar tu clave contra tu iPhone en segundos hay un comando:
npm run push:test -- <device-token> "Hola" "Desde mi Mac"
Si nunca has configurado APNs, empieza por mi guía para configurar APNs: el starter usa exactamente esa clave.
3. Pagos con Stripe y webhooks seguros
Endpoint para el PaymentSheet de Stripe en iOS, webhooks firmados e idempotentes (un mismo evento no se procesa dos veces), activación de un plan Pro con fecha de caducidad, reembolsos que retiran el plan y una push de confirmación al usuario cuando el pago entra. Lo de verificar firmas y evitar duplicados lo conté con más detalle en cómo construir webhooks seguros en Node.js y PHP.
Ojo: Apple obliga a usar compras in-app para el contenido digital que se consume dentro de la app. Stripe sirve para bienes físicos, servicios fuera de la app o pagos desde tu web. Si lo tuyo es contenido digital, mira mi tutorial de StoreKit 2 en SwiftUI sin RevenueCat.
4. Chat con IA en streaming (Ollama)
Un proxy de IA que responde palabra a palabra mediante Server-Sent Events, con el prompt de sistema en el servidor (no en la app, donde cualquiera podría leerlo) y un límite de peticiones por usuario. Por defecto apunta a un modelo local con Ollama, como Llama 3.2, así que no pagas por token. En la app, la respuesta se consume con AsyncSequence y se puede cortar con un botón «Parar». Si te interesa por qué SSE y no WebSockets para esto, lo comparé en SSE vs WebSockets en Swift.
5. App SwiftUI de ejemplo
Cliente HTTP con async/await y renovación automática del token cuando caduca, registro de push, Sign in with Apple con nonce, chat con IA y pago con Stripe. Sin Alamofire ni dependencias raras: la misma filosofía que en capa de red moderna con Swift 6. El proyecto de Xcode se genera con XcodeGen en un comando.
Empieza sin cuentas de pago
Cada servicio tiene un modo de prueba: las push se guardan en una bandeja que puedes ver en /dev/outbox, la IA responde con un texto de ejemplo y los pagos se desactivan solos si no hay clave de Stripe. Así pruebas la app entera desde el primer minuto y activas cada pieza cuando la necesitas:
npm install
cp .env.example .env
npm run jwt:secret # pega el resultado en JWT_SECRET
npm test # ✔ 30 tests, 0 fallos
npm run dev # Servidor escuchando en http://localhost:3000
Luego xcodegen en la carpeta ios, abres el proyecto y lo lanzas en el simulador. Lo he probado con Xcode 26 en el simulador de iOS 26: registro, sesión persistente, push de prueba, chat en streaming, borrado de cuenta… todo funcionando contra el backend local.
La tecnología
- Backend: Node.js 22 + TypeScript, Express, Zod para validar datos y el SQLite nativo de Node (sin dependencias que compilar).
- App: SwiftUI para iOS 17 o superior.
- Calidad: 30 tests automáticos (incluido un servidor APNs simulado sobre HTTP/2), errores con formato uniforme y límite de peticiones.
- Despliegue: Dockerfile y guía. Corre en cualquier VPS barato; tienes opciones en VPS baratos para el backend de tu app.
- Idioma: todo el código comentado y la documentación en español.
¿Por qué Node y no PHP? Para un backend con streaming, HTTP/2 hacia APNs y mucho JSON, Node encaja muy bien; si dudas entre los dos, tienes la comparativa en PHP 8.5 vs Node.js para el backend de tu app móvil.
Para quién es (y para quién no)
Es para ti si sabes Swift, quieres un backend propio sin depender de Firebase y prefieres partir de algo que ya funciona y está probado en vez de pelearte con la configuración desde cero. No es para ti si buscas un servicio gestionado sin servidor que mantener, o si nunca vas a necesitar push, login ni pagos.
La licencia te permite usarlo en todos tus proyectos, propios o de clientes. Lo único que no puedes es revenderlo como plantilla. Las actualizaciones (la versión actual es la 1.0.1) te llegan a tu biblioteca de Gumroad.
Si tienes dudas antes de comprarlo, déjalas en los comentarios y te respondo.