Courses/GORM Studio
Standalone Course~30 min12 challenges

GORM Studio: The Visual Database Browser

Your database holds all your application's data, but most of the time it's a black box. You send API requests and trust the data is there, but you cannot see it directly. GORM Studio changes that — it's a visual database browser embedded in every Grit project. Browse tables, edit records, run SQL, export data, and generate Go models — all from your browser at /studio.


What is GORM Studio?

Database Browser: A graphical tool for viewing and interacting with a database. Instead of writing SQL in a terminal, you use a visual interface to browse tables, view records, edit data, and run queries. Think of it like a file manager, but for database tables instead of files.
GUI (Graphical User Interface): A visual interface with buttons, tables, forms, and menus — as opposed to a CLI (Command Line Interface) where you type text commands. GORM Studio is a web-based GUI that runs in your browser.

GORM Studio is a database browser built specifically for GORM (Go's most popular ORM). It's embedded in every Grit project and available at /studio. You do not need to install anything — it's part of your API.

What makes GORM Studio different from tools like pgAdmin, DBeaver, or TablePlus:

  • Zero installation — runs inside your Grit API, accessible in the browser
  • GORM-aware — understands GORM conventions (soft delete, relationships, auto-migrate)
  • Go model generation — can generate Go struct code from existing tables
  • Multi-format export — SQL, JSON, CSV, XLSX, YAML, DBML, ERD diagrams
  • Password-protected — secured with its own credentials, separate from your app's auth
1

Challenge: Open GORM Studio

Start your Grit API and open http://localhost:8080/studio in your browser. Log in with the default credentials: username admin, password studio. What do you see? How many tables are listed?

Browsing Tables

When you open GORM Studio, the left sidebar shows all tables in your database. Click any table name to see its records displayed in a data grid on the right.

The table view shows:

  • Column headers — with the column name and data type (varchar, integer, boolean, timestamp)
  • Records as rows — each row is one record in the table
  • Pagination — for tables with many records, navigate between pages
  • Row count — total number of records in the table
What You See
┌─────────────────────────────────────────────────────────────┐
│ Tables          │ users (5 records)                          │
│ ─────────────── │ ─────────────────────────────────────────  │
│ > users         │ ID │ Name     │ Email          │ Role      │
│   uploads       │ ───┼──────────┼────────────────┼────────── │
│   blogs         │ 1  │ Admin    │ admin@test.com │ ADMIN     │
│   categories    │ 2  │ Editor   │ ed@test.com    │ EDITOR    │
│   products      │ 3  │ Alice    │ alice@test.com │ USER      │
│   orders        │ 4  │ Bob      │ bob@test.com   │ USER      │
│                 │ 5  │ Charlie  │ charlie@t.com  │ USER      │
│                 │                                             │
│                 │ Page 1 of 1  │  5 records total            │
└─────────────────────────────────────────────────────────────┘
GORM Studio shows ALL tables, including GORM's internal tables and any tables created by migrations. If you see tables you do not recognize, they may be from GORM's auto-migration or from third-party packages.
2

Challenge: Explore Your Tables

Find the users table in GORM Studio. How many columns does it have? What are their data types? Click through the other tables — which table has the most records? Which has the most columns?

Viewing Records

Click on any row in the table view to see the full record details. The detail view shows every field with its value, including fields that might be truncated in the table view (like long text fields or JSON columns).

For records with relationships, the detail view can show related data. For example, clicking on a blog post might show:

  • The post's own fields (title, content, published, created_at)
  • The category_id foreign key — and which category it points to
  • The user_id — the author of the post

This is especially useful for debugging. When a frontend shows wrong data, you can check GORM Studio to see exactly what's in the database — is it a frontend bug (wrong display) or a backend bug (wrong data)?

3

Challenge: Inspect a Record

Find a specific user in the users table by scrolling or using the search. Click on the row to see the full detail view. What fields can you see? Is the password field visible? (Hint: the password is stored as a bcrypt hash — you should see a long string starting with $2a$.)

Editing Records

GORM Studio lets you edit records directly. Click on a cell in the table view to enter edit mode. Change the value, then save. The change is written directly to the database.

This is incredibly useful for:

  • Debugging — quickly change a value to test how the frontend handles it
  • Fixing data — correct a typo or wrong value without writing a migration
  • Testing roles — change a user's role from USER to ADMIN to test admin features
  • Seeding data — quickly add test data without writing API requests
Be careful with direct edits. GORM Studio bypasses your API's validation layer. If your API requires an email to be unique and properly formatted, GORM Studio will let you set it to anything — including invalid values. Use this power responsibly, especially on production databases.
4

Challenge: Change a Role

Find a user with the USER role in GORM Studio. Edit their role field to ADMIN and save. Now log in as that user in your application. Can they access admin features? Change it back to USER when you are done.

Creating Records

Click the "New" button to create a new record. GORM Studio shows a form with a field for each column. Fill in the values and save to insert a new row directly into the database.

Some fields are auto-populated and you can leave them empty:

  • ID — auto-incremented by the database
  • CreatedAt — set automatically by GORM
  • UpdatedAt — set automatically by GORM
  • DeletedAt — null for active records
If you create a user directly in GORM Studio, the password field needs a bcrypt hash — not a plain text password. You cannot log in with a plain text password stored in the database. Use the API's registration endpoint for proper user creation, or generate a bcrypt hash externally.
5

Challenge: Create a Record

Use GORM Studio to create a new record in a non-user table (e.g., categories or blogs). Fill in the required fields and save. Can you see the new record in the table view? Can you also see it through the API (e.g., GET /api/categories)?

Deleting Records

Select one or more rows in the table view and click Delete. But here's the important question: is the record actually gone?

Soft Delete: Instead of removing the row from the database, GORM sets a DeletedAt timestamp on the record. The record still exists in the database but is automatically excluded from normal queries. This is useful for data recovery, audit trails, and compliance. GORM's default behavior is soft delete for any model that includes gorm.DeletedAt.

When you delete through the API, GORM performs a soft delete. The record's DeletedAt field is set to the current timestamp. It disappears from GET /api/resources but remains in the database.

In GORM Studio, you can see soft-deleted records — they show a non-null DeletedAt value. You can also perform a hard delete (permanent removal) if needed.

Soft Delete vs Hard Delete
-- Soft Delete (what GORM does by default)
UPDATE users SET deleted_at = '2026-03-27 10:00:00' WHERE id = 5;
-- Record still exists, just hidden from normal queries

-- Hard Delete (permanent, irreversible)
DELETE FROM users WHERE id = 5;
-- Record is gone forever
6

Challenge: Observe Soft Delete

Delete a record through the API (e.g., DELETE /api/categories/1). Then open GORM Studio and look at the categories table. Can you still see the deleted record? What value does DeletedAt have? Is the record visible through GET /api/categories?

Running Raw SQL

GORM Studio includes a SQL editor where you can write and execute any SQL query directly against your database. This is the most powerful feature — it gives you the full expressiveness of SQL for data exploration, reporting, and debugging.

Some useful queries to try:

Useful SQL Queries
-- Count users by role
SELECT role, COUNT(*) as count
FROM users
WHERE deleted_at IS NULL
GROUP BY role;

-- Find the most recent records
SELECT name, email, created_at
FROM users
ORDER BY created_at DESC
LIMIT 10;

-- Count published vs draft blogs
SELECT
  CASE WHEN published = true THEN 'Published' ELSE 'Draft' END as status,
  COUNT(*) as count
FROM blogs
WHERE deleted_at IS NULL
GROUP BY published;

-- Products per category with totals
SELECT c.name as category, COUNT(p.id) as product_count,
       COALESCE(SUM(p.price), 0) as total_value
FROM categories c
LEFT JOIN products p ON p.category_id = c.id
  AND p.deleted_at IS NULL
WHERE c.deleted_at IS NULL
GROUP BY c.name
ORDER BY product_count DESC;

-- Find orphaned records (products with no category)
SELECT p.name, p.category_id
FROM products p
LEFT JOIN categories c ON p.category_id = c.id
WHERE c.id IS NULL AND p.deleted_at IS NULL;
The SQL editor executes queries directly against your database. Be careful with UPDATE and DELETE statements — there is no undo. Always use a WHERE clause with DELETE and UPDATE to avoid accidentally modifying all rows in a table.
7

Challenge: Write a SQL Query

Open the SQL editor in GORM Studio. Write a query that counts users by role. Your result should show something like: ADMIN: 1, EDITOR: 2, USER: 10. Try a second query: find the 5 most recently created records across any table.

Schema Export

GORM Studio can export your complete database schema in multiple formats:

FormatUse Case
SQLCREATE TABLE statements — recreate the schema in another database
JSONMachine-readable schema for documentation generators or code tools
YAMLHuman-readable schema for configuration and documentation
DBMLDatabase Markup Language — import into dbdiagram.io for visual ERD
ERDEntity Relationship Diagram — visual representation of tables and relationships

The SQL export is especially useful for documentation and database migrations. It produces the exact CREATE TABLE statements that reproduce your schema:

Schema Export (SQL)
CREATE TABLE users (
  id BIGSERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  role VARCHAR(50) DEFAULT 'USER',
  created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
  deleted_at TIMESTAMPTZ
);

CREATE INDEX idx_users_deleted_at ON users(deleted_at);
CREATE UNIQUE INDEX idx_users_email ON users(email);
8

Challenge: Export Your Schema

Find the schema export feature in GORM Studio. Export your schema as SQL. Open the file — can you read the CREATE TABLE statements? How many tables are in the export? Do the column types match what you defined in your GORM models?

Data Import/Export

Beyond schema export, GORM Studio can export and import the actual data in your tables. This is useful for:

  • Backups — export all data before a risky migration
  • Reporting — export to CSV or XLSX for analysis in Excel or Google Sheets
  • Seeding — import data from a CSV to populate a table with test data
  • Migration — export from one database and import into another

Supported export formats:

FormatBest For
JSONAPI-compatible format, preserves types, easy to parse programmatically
CSVSpreadsheet-compatible, opens in Excel/Sheets, universal format
SQL INSERTExecutable SQL statements, reimport into any SQL database
XLSXExcel native format with formatting, good for reports and sharing
When exporting data for a report, use CSV or XLSX. When exporting for backup or migration, use SQL INSERT statements — they can be directly executed on another database to reproduce the data exactly.
9

Challenge: Export and Reimport

Export the users table as CSV. Open it in Excel, Google Sheets, or any text editor. Can you see all the columns and rows? Now export the same table as JSON. Compare the two formats — which is more readable? Which preserves data types better?

Go Model Generation

One of GORM Studio's most unique features is generating Go model code from your database schema. This is the reverse of the normal workflow: instead of writing a Go struct and letting GORM create the table, you start with an existing table and GORM Studio generates the Go struct.

This is useful when:

  • Working with existing databases — you inherit a database and need Go models for it
  • Database-first development — your DBA designs the schema, you generate the code
  • Verification — compare the generated model with your written model to check for drift
Generated Go Model
// Generated by GORM Studio from the 'users' table
type User struct {
    ID        uint           `gorm:"primaryKey;column:id" json:"id"`
    Name      string         `gorm:"column:name;size:255;not null" json:"name"`
    Email     string         `gorm:"column:email;size:255;not null;uniqueIndex" json:"email"`
    Password  string         `gorm:"column:password;size:255;not null" json:"-"`
    Role      string         `gorm:"column:role;size:50;default:USER" json:"role"`
    CreatedAt time.Time      `gorm:"column:created_at" json:"created_at"`
    UpdatedAt time.Time      `gorm:"column:updated_at" json:"updated_at"`
    DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"-"`
}

The generated code includes all GORM struct tags (gorm:"...") and JSON tags (json:"...") with correct column mappings, sizes, constraints, and indexes.

10

Challenge: Generate a Model

Look for the "Generate Models" feature in GORM Studio. Generate the Go model code for the users table. Compare it with the actual model in your project at apps/api/internal/models/user.go. Are they identical? What differences do you notice?

Configuration

GORM Studio is configured through environment variables:

VariableDefaultPurpose
GORM_STUDIO_ENABLEDtrueEnable or disable GORM Studio
GORM_STUDIO_USERNAMEadminLogin username for GORM Studio
GORM_STUDIO_PASSWORDstudioLogin password for GORM Studio
.env
# GORM Studio Configuration
GORM_STUDIO_ENABLED=true
GORM_STUDIO_USERNAME=admin
GORM_STUDIO_PASSWORD=your-secure-password-here
In production, either disable GORM Studio entirely (GORM_STUDIO_ENABLED=false) or use strong, unique credentials. GORM Studio provides direct database access — anyone who can log in can view, edit, and delete any data. It also bypasses your API's authentication and authorization middleware.
11

Challenge: Secure GORM Studio

Change the GORM Studio password in your .env file to something other than the default. Restart your API. Try accessing /studio — does the old password work? Does the new password work?

Summary

GORM Studio gives you visual access to your database without any external tools:

FeatureWhat You Can Do
BrowseView all tables, columns, types, and records
EditInline cell editing, create new records, delete records
SQL EditorWrite and execute any SQL query
Schema ExportSQL, JSON, YAML, DBML, ERD diagram
Data ExportJSON, CSV, SQL INSERT, XLSX
Model GenerationGo struct code from existing tables
12

Challenge: Final Challenge: Database-Only Workflow

Use ONLY GORM Studio (no API calls, no frontend, no curl) to complete these tasks:

  1. Create 5 categories directly in the categories table
  2. Create 20 products, each linked to a category via category_id
  3. Run a SQL query: SELECT c.name, COUNT(p.id) as product_count FROM categories c LEFT JOIN products p ON p.category_id = c.id WHERE c.deleted_at IS NULL AND p.deleted_at IS NULL GROUP BY c.name ORDER BY product_count DESC
  4. Export all products as CSV
  5. Export the full schema as SQL

This exercise proves you can manage your entire database through GORM Studio without writing a single line of code or making an API request.