Documentation Index Fetch the complete documentation index at: https://docs.edgespark.dev/llms.txt
Use this file to discover all available pages before exploring further.
Every EdgeSpark project includes a Cloudflare D1 database. You define your app tables in server/src/defs/db_schema.ts, generate migrations with the CLI, and query the database from the runtime SDK.
Define your schema
Add app tables to server/src/defs/db_schema.ts:
server/src/defs/db_schema.ts
import { integer , sqliteTable , text } from "drizzle-orm/sqlite-core" ;
export const posts = sqliteTable ( "posts" , {
id: integer ( "id" ). primaryKey ({ autoIncrement: true }),
title: text ( "title" ). notNull (),
content: text ( "content" ),
authorId: text ( "author_id" ). notNull (),
createdAt: text ( "created_at" ). notNull (). default ( "(datetime('now'))" ),
});
If you need relations, add them in server/src/defs/db_relations.ts.
Generate and apply migrations
After editing db_schema.ts, run:
edgespark db generate
edgespark db migrate
Useful related commands:
edgespark db generate --name add_posts
edgespark db check
edgespark db studio
Use edgespark pull schema only for platform-managed tables that EdgeSpark generates into server/src/__generated__/. Your app tables live in server/src/defs/ and use the migration workflow above.
Query data
Use the runtime SDK inside route handlers:
import { db } from "edgespark" ;
import { auth } from "edgespark/http" ;
import { desc , eq } from "drizzle-orm" ;
import { Hono } from "hono" ;
import { posts } from "@defs" ;
const app = new Hono ()
. get ( "/api/posts" , async ( c ) => {
const rows = await db
. select ()
. from ( posts )
. orderBy ( desc ( posts . createdAt ));
return c . json ( rows );
})
. get ( "/api/posts/:id" , async ( c ) => {
const id = Number ( c . req . param ( "id" ));
const [ post ] = await db . select (). from ( posts ). where ( eq ( posts . id , id ));
if ( ! post ) return c . json ({ error: "Not found" }, 404 );
return c . json ( post );
})
. post ( "/api/posts" , async ( c ) => {
const body = await c . req . json <{ title : string ; content ?: string }>();
const [ post ] = await db
. insert ( posts )
. values ({
title: body . title ,
content: body . content ?? null ,
authorId: auth . user . id ,
})
. returning ();
return c . json ( post , 201 );
});
export default app ;
Update and delete data
import { db } from "edgespark" ;
import { auth } from "edgespark/http" ;
import { eq } from "drizzle-orm" ;
import { Hono } from "hono" ;
import { posts } from "@defs" ;
const app = new Hono ()
. patch ( "/api/posts/:id" , async ( c ) => {
const id = Number ( c . req . param ( "id" ));
const body = await c . req . json <{ title ?: string ; content ?: string }>();
const [ post ] = await db
. update ( posts )
. set ( body )
. where ( eq ( posts . id , id ))
. returning ();
return c . json ( post );
})
. delete ( "/api/posts/:id" , async ( c ) => {
const id = Number ( c . req . param ( "id" ));
await db
. delete ( posts )
. where ( eq ( posts . id , id ))
. returning ({ authorId: posts . authorId });
return c . body ( null , 204 );
});
export default app ;
Run ad-hoc SQL
For inspection or one-off data changes, use:
edgespark db sql "SELECT * FROM posts"
edgespark db sql "DELETE FROM posts WHERE id = 42" --confirm-dangerous
Constraints
Runtime DDL is blocked. Do not use edgespark db sql for CREATE TABLE, ALTER TABLE, or DROP TABLE. Apply schema changes through edgespark db generate and edgespark db migrate.
Transactions are not available. Use db.batch([...]) for atomic multi-step operations, and see platform limits whenever you are working near database or bundle constraints.
See also
db reference Complete API for selects, inserts, updates, deletes, relational queries, and batching.
Declarative workflow How schema files, generated types, and migrations stay in sync.