Payload no tiene un adaptador «de Turso». Turso es SQLite en un servidor, y Payload ya sabe hablar con SQLite, así que se conecta con el mismo adaptador que usarías con un archivo local. Esto es lo que hacemos en este sitio, sin saltos.
Antes de entrar, conviene saber qué es Turso y cuándo tiene sentido. Lo dejamos corto: es una base de datos basada en libSQL (una bifurcación de SQLite) a la que te conectas por red con una URL y un token. Si lo que quieres es comparar con Postgres o MongoDB, mira qué bases de datos soporta Payload CMS.
Paso 1: crea la base en Turso
Con la CLI de Turso instalada (está en su documentación):
turso auth login
turso db create mi-sitio
turso db show mi-sitio --url
turso db tokens create mi-sitioEl tercer comando te da una URL que empieza por libsql://. El cuarto, un token. Guarda las dos cosas. Si quieres que caduque, turso db tokens create acepta --expiration, y --read-only crea uno de solo lectura, útil para una réplica o un script de consulta.
Paso 2: instala el adaptador
pnpm add @payloadcms/db-sqlitePaso 3: configura Payload
En payload.config.ts:
import { sqliteAdapter } from '@payloadcms/db-sqlite';
export default buildConfig({
// …
db: sqliteAdapter({
client: {
url: process.env.DATABASE_URL ?? 'file:./data/payload.db',
authToken: process.env.DATABASE_AUTH_TOKEN,
},
}),
});Y en .env:
# Local
DATABASE_URL=file:./data/payload.db
# Producción
# DATABASE_URL=libsql://mi-sitio-tu-usuario.turso.io
# DATABASE_AUTH_TOKEN=…El mismo código sirve para los dos entornos. En local, file: abre un archivo SQLite y no hace falta token. En producción, libsql:// más el token apuntan a Turso. No hay if en el código, solo cambian las variables.
Paso 4: desarrollo con archivo, sin red
En desarrollo, el adaptador sincroniza el esquema solo cada vez que cambias una colección. Es cómodo: editas un campo y la tabla se actualiza. Verás una fila llamada dev en la tabla payload_migrations; es la marca de que la base se ha ido ajustando de esa forma, y es normal.
Trabajar contra un archivo local tiene otra ventaja: no gastas red ni cuota de Turso mientras desarrollas, y puedes borrar la base y sembrarla de nuevo en segundos.
Paso 5: migraciones para producción
Ese ajuste automático no es lo que quieres en producción. Ahí se usan migraciones, que son archivos versionados en Git. Cuando termines un cambio de esquema:
pnpm payload migrate:create nombre-del-cambioGenera un archivo en src/migrations/ con las sentencias SQL. Lo revisas, lo subes con tu código y en el despliegue se aplica:
pnpm payload migrateEn nuestro package.json el script de build de Vercel hace las dos cosas seguidas:
"vercel-build": "payload migrate && next build"Así, cada despliegue aplica las migraciones pendientes contra Turso antes de compilar. Para que funcione, el entorno de build necesita DATABASE_URL y DATABASE_AUTH_TOKEN, no solo el de ejecución. Es el olvido más común.
Lo que nos ha tocado vigilar
- Un solo proceso a la vez sobre el archivo local. Si tienes el servidor de desarrollo abierto y corres un script de seed sobre la misma base, puede fallar con
disk I/O error. Usamos una base aparte para esas pruebas. - No mezcles
pushy migraciones en la misma base. Si ya aplicaste cambios con el ajuste automático de desarrollo y luego creas la migración, la base local y el archivo pueden no coincidir. Ante la duda, recrea la base local desde cero. - Revisa el SQL de cada migración. Sobre todo si renombras o eliminas columnas: SQLite maneja esos cambios con menos libertad que Postgres.
Cuándo no usar Turso con Payload
SQLite admite un escritor a la vez. Para un sitio de contenido, donde se escribe poco y se lee mucho, no es un problema. Para una aplicación con muchas escrituras concurrentes (pedidos, sesiones, eventos en tiempo real), Postgres es la opción más cómoda.
Si quieres ver cómo encaja todo esto en un sitio real, en así está construido codegea.com contamos el stack completo.
Escrito por
Derian Pinto
Founder & Full Stack Developer
Fundador de Codegea. Desarrolla sitios, tiendas y plataformas a medida, e integra y da soporte a Arc XP para medios.