Database and File Storage
Choose the production database in cloud.config.ts. Without db.remote, Vercel
uses Turso, while Cloudflare and Azure use D1. An explicit db.remote.provider
overrides the host default, so you can keep the same database when moving hosts.
Local development continues to use SQLite and local files. Production requires the configured remote services; it never falls back to temporary local storage.
Use Turso on Vercel
Create a Turso database and obtain its URL
and auth token. Add them to the ignored .env file or process environment:
TURSO_DATABASE_URL=libsql://your-database.turso.io
TURSO_AUTH_TOKEN=your-database-token
Turso is the default when deploy.target is vercel. To select it explicitly
on any supported app host:
db: {
remote: { provider: 'turso' },
},
CloudConfig uses its libSQL adapter for Turso, applies SQL migrations, and uploads the credentials as server settings. It does not provision the Turso service or copy local development data. No Cloudflare account or Wrangler installation is needed for a project using Turso without Cloudflare services.
Both cloudconfig db status --remote and cloudconfig db migrate --remote
follow the selected database. Override the credential names with
db.remote.urlEnv and db.remote.tokenEnv when needed.
Use D1 from Vercel or Azure
On Cloudflare, the database driver uses the native D1 binding. On Vercel and Azure, it accesses the same database over HTTPS.
Select D1 explicitly before moving a Cloudflare app to Vercel, or when upgrading an existing Vercel app that used the previous D1 default:
db: {
remote: { provider: 'd1' },
},
Keep the existing Wrangler database ID and migrations. This retains the current database rather than selecting Vercel's new Turso default. An omitted provider continues to select D1 on Cloudflare and Azure.
Keep Wrangler installed for provisioning and migrations:
pnpm add -D wrangler
Add these server-only settings to the ignored .env file or process environment:
CLOUDFLARE_ACCOUNT_ID=your-account-id
CLOUDCONFIG_D1_API_TOKEN=your-d1-api-token
Create the token in Cloudflare → My Profile → API Tokens → Create Custom Token:
- Select Account → D1 → Edit.
- Include the account that owns the database.
- Set an expiry and plan how to rotate it.
Read permission alone cannot execute writes. This token grants account-level D1
access: keep it server-side, never in a public Nuxt or Next.js environment
variable. CLOUDFLARE_API_TOKEN is accepted as a fallback.
The Wrangler file supplies the database name and ID. Existing databases are reused; a new one is provisioned after a successful build when needed. Wrangler OAuth can handle interactive provisioning, but its expiring login is not uploaded to the Node application.
Queries from another host use Cloudflare's REST API. Account API limits and an additional network round trip apply.
Keep an Existing R2 Bucket
Cloudflare uses the native R2 binding. For Vercel or Azure, supply bucket-scoped S3 credentials:
CLOUDCONFIG_STORAGE_ACCESS_KEY_ID=your-r2-access-key
CLOUDCONFIG_STORAGE_SECRET_ACCESS_KEY=your-r2-secret-key
CloudConfig derives the endpoint and bucket name from the account and Wrangler
config, or deploy.r2. File metadata and authorization stay in CloudConfig.
Use an Existing libSQL Database
For another hosted libSQL service, select it independently of the app host:
db: {
remote: { provider: 'libsql' },
},
Supply its server credentials:
CLOUDCONFIG_DATABASE_URL=libsql://your-database.example.com
CLOUDCONFIG_DATABASE_TOKEN=your-database-token
The URL can use libsql:// or https://. Override the variable names with
db.remote.urlEnv and db.remote.tokenEnv.
CloudConfig applies generated SQL migrations, checks drift, and records checksums in an atomic batch. Remote migration commands follow this setting:
pnpm exec cloudconfig db status --remote
pnpm exec cloudconfig db migrate --remote
The service must already exist. CloudConfig does not create it or import D1 rows. Changing providers requires an explicit data migration.
Other Database Engines
The built-in data stack currently supports SQLite-compatible databases: local SQLite, D1, Turso, and other libSQL services. Neon and Supabase require PostgreSQL support across schema compilation, queries, authentication, and migrations. PlanetScale also requires an adapter for its selected PostgreSQL or MySQL/Vitess engine. These providers are not supported yet.
Switching between SQLite-compatible providers reuses the schema and migrations; it does not move existing rows. A connection URL alone cannot convert SQLite migrations into PostgreSQL or MySQL migrations. Cosmos DB and AWS database services need adapters for the specific database engine or API.
Use an Existing S3-Compatible Bucket
Select S3 storage and your service's region:
storage: {
provider: 's3',
region: 'your-region',
},
Supply the endpoint, bucket, and credentials:
CLOUDCONFIG_STORAGE_ENDPOINT=https://your-s3-endpoint.example.com
CLOUDCONFIG_STORAGE_BUCKET=blog-uploads
CLOUDCONFIG_STORAGE_ACCESS_KEY_ID=your-access-key
CLOUDCONFIG_STORAGE_SECRET_ACCESS_KEY=your-secret-key
The service and bucket must already exist. Selecting them does not copy files from another bucket.
Update an Older Mount
Newly generated standalone and Next.js mounts use configuredDatabase(config);
the Nuxt module selects it automatically. Update older projects once:
pnpm add @cloudconfig/core@beta
In Nuxt projects, update @cloudconfig/nuxt@beta at the same time. In standalone
and Next.js projects, replace an explicit sqliteFile() or d1() driver in the
existing backend mount:
import { configuredDatabase } from '@cloudconfig/core/drivers/configured'
const app = createBackend(config, { db: configuredDatabase(config) })
Keep your existing config and createBackend imports. The configured driver
uses db.local in development and the selected remote service in production.