Add a database

Your app needs to remember things — forms people create and submissions people send in. That's what a database is for. Think of it as a spreadsheet that your app can read and write to.

Your starter already has the database wiring done. In this step, you define your app's first real tables.

?What is a database? ?Why SQLite? ?Why Drizzle?

Define your schema

Before you can store data, you need to tell the database what shape the data will have. That's called a schema — it's like setting up the column headers in a spreadsheet before entering any rows.

?What are schemas and migrations?

Your form builder needs two tables:

  • forms — Each row is a form someone created. Columns: id, title, the list of fields, and a secret token for viewing results.
  • submissions — Each row is one form submission. Columns: id, which form it belongs to, and the submitted data.

Ask your AI:

Create a database schema with two tables. A "forms" table with columns for id, title, fields (as JSON), and a unique token string. A "submissions" table with columns for id, form_id (linking to the forms table), and data (as JSON). Use Drizzle ORM with SQLite.

The AI will create a schema file that describes your tables. It's just code that says "a form has a title, some fields, and a token." It should look something like this:

app/.server/db/schema.ts
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'

export const forms = sqliteTable('forms', {
  id: integer().primaryKey({ autoIncrement: true }),
  title: text().notNull(),
  fields: text({ mode: 'json' }).notNull(),
  token: text().notNull().unique(),
})

export const submissions = sqliteTable('submissions', {
  id: integer().primaryKey({ autoIncrement: true }),
  form_id: integer().notNull().references(() => forms.id),
  data: text({ mode: 'json' }).notNull(),
})

Notice the import at the top and the export on each table? That's how files share code with each other in JavaScript — you'll see this pattern everywhere.

?What are exports and imports?

Apply the schema to the database

Now tell the database to actually create those tables. Run:

atlas schema apply --env dev

Atlas apply

Atlas will show you the planned changes it's about to make and ask you to approve.

Hit Enter to approve and apply. This creates the tables in your local SQLite database.

See it for yourself

Want proof it worked? Open data/dev.db in VS Code — the SQLite Viewer extension lets you browse your database right in the editor.

Tables

You should see two empty tables: forms and submissions. The column headers match what you defined in the schema. Ignore sqlite_sequence — SQLite creates it automatically.

No data yet — that comes next when you build the form creator.