How to Seed Turso (LibSQL) with Realistic Test Data
The Problem
Turso brings SQLite to the edge with embedded replicas and global distribution. But edge databases start empty, and seeding them with realistic data is not straightforward. You cannot just dump a SQL file into a Turso database like you would with local SQLite. The LibSQL client requires programmatic inserts, and you need data that respects your schema's foreign keys and constraints.
Faker.js can produce random values, but you are still responsible for generating parent records first, collecting their IDs, and wiring child records manually. For an edge-first database like Turso, you want seeding to be fast and reproducible across replicas.
The Solution: MockHero API
MockHero generates relationally-consistent test data in a single API call. Define your tables with ref fields for foreign keys, and get back JSON you can insert directly using the LibSQL client. No ORM required, no manual ID management.
Quick Setup
curl -X POST https://api.mockhero.dev/api/v1/generate \
-H "x-api-key: mh_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"tables": [
{
"name": "authors",
"count": 10,
"fields": [
{ "name": "id", "type": "uuid" },
{ "name": "name", "type": "full_name" },
{ "name": "bio", "type": "sentence" },
{ "name": "email", "type": "email" }
]
},
{
"name": "articles",
"count": 40,
"fields": [
{ "name": "id", "type": "uuid" },
{ "name": "author_id", "type": "ref", "params": { "ref": "authors.id" } },
{ "name": "title", "type": "sentence" },
{ "name": "body", "type": "paragraphs" },
{ "name": "published_at", "type": "datetime" }
]
}
],
"format": "json"
}'
Step-by-Step Guide
1. Install dependencies
npm install @libsql/client
2. Get your MockHero API key
Sign up at mockhero.dev/sign-up and copy your API key.
3. Write the seed script
Create seed.mjs:
import { createClient } from "@libsql/client";
const db = createClient({
url: process.env.TURSO_DATABASE_URL,
authToken: process.env.TURSO_AUTH_TOKEN,
});
const res = await fetch("https://api.mockhero.dev/api/v1/generate", {
method: "POST",
headers: {
"x-api-key": process.env.MOCKHERO_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
tables: [
{
name: "authors",
count: 10,
fields: [
{ name: "id", type: "uuid" },
{ name: "name", type: "full_name" },
{ name: "bio", type: "sentence" },
{ name: "email", type: "email" },
],
},
{
name: "articles",
count: 40,
fields: [
{ name: "id", type: "uuid" },
{ name: "author_id", type: "ref", params: { ref: "authors.id" } },
{ name: "title", type: "sentence" },
{ name: "body", type: "paragraphs" },
{ name: "published_at", type: "datetime" },
],
},
],
format: "json",
}),
});
const { data } = await res.json();
for (const a of data.authors) {
await db.execute({
sql: "INSERT INTO authors (id, name, bio, email) VALUES (?, ?, ?, ?)",
args: [a.id, a.name, a.bio, a.email],
});
}
for (const art of data.articles) {
await db.execute({
sql: "INSERT INTO articles (id, author_id, title, body, published_at) VALUES (?, ?, ?, ?, ?)",
args: [art.id, art.author_id, art.title, art.body, art.published_at],
});
}
console.log("Seeded", data.authors.length, "authors and", data.articles.length, "articles");
4. Run the script
node seed.mjs
5. Verify in the Turso CLI
Use turso db shell your-db-name and run SELECT * FROM articles LIMIT 5; to confirm the data is in place with valid foreign keys.
Why MockHero vs Faker / Manual Seeds
- Edge-friendly — generate data once, seed all replicas. The JSON response works with any LibSQL client.
- Relational integrity — every
author_idin articles references a real author record. - SQLite-native types — MockHero's output maps cleanly to SQLite column types.
Get Started
Seed your Turso database with realistic data in minutes. Sign up free at mockhero.dev and get 1,000 rows per month, no credit card required.
MockHero Team
Guides and tutorials for generating realistic test data with the MockHero API.
Start generating test data for free
1,000 rows/month on the free tier. No credit card required.
Get Your API Key