Skip to Content
AdvancedCode Generation

Code Generation

Generate type-safe client models from your Prisma schema automatically.

The Problem

Currently, you must define models twice:

// Server: Prisma schema model User { id String @id email String name String? userId String version Int }
// Client: Manual model class @ClientModel('user') export class User extends Model { @Property() id: string = '' @Property() email: string = '' @Property() name: string = '' @Property({ server: true }) userId: string = '' @Property({ server: true }) serverCreatedAt?: number }

Problems:

  • 2x maintenance burden
  • Easy to drift out of sync
  • Repetitive boilerplate
  • Error-prone

The Solution

Generate client models automatically:

npx gluonic codegen --prisma=./prisma/schema.prisma --out=./src/models

Output:

âś“ Generated User model (5 fields, 2 relationships) âś“ Generated Post model (8 fields, 3 relationships) âś“ Generated Comment model (4 fields, 2 relationships) âś“ Generated index.ts (warmup + exports) âś“ Generated types.ts (shared types) Created 5 files in ./src/models

Generated Code

Model Classes

// Generated: src/models/User.ts import { Model, ClientModel, Property, OneToMany, LazyCollection } from '@gluonic/client' import type { Post } from './Post' @ClientModel('user') export class User extends Model { @Property() id: string = '' @Property() email: string = '' @Property() name: string = '' @Property({ server: true }) userId: string = '' @Property({ server: true }) version: number = 0 @Property({ server: true }) createdAt: number = 0 @Property({ server: true }) updatedAt: number = 0 // Auto-detected relationships from Prisma schema @OneToMany('author') posts: LazyCollection<Post> = new LazyCollection<Post>() // Computed properties get displayName(): string { return this.name || this.email.split('@')[0] } }

Index File

// Generated: src/models/index.ts import { warmUpModelRegistry } from '@gluonic/client' export * from './User' export * from './Post' export * from './Comment' import { User } from './User' import { Post } from './Post' import { Comment } from './Comment' // Auto-warm registry warmUpModelRegistry([User, Post, Comment])

Storage Configuration

// Generated: src/models/storage.config.ts import { user, post, comment } from '../db/schema' export const tableConfig = { user: { model: user, idField: 'id' }, post: { model: post, idField: 'id' }, comment: { model: comment, idField: 'id' } }

CLI Options

Basic Usage

gluonic codegen [options]

Options

--prisma <path> # Path to Prisma schema file (required) --out <path> # Output directory (default: ./src/models) --format <style> # Code style: decorators|imperative (default: decorators) --relationships # Generate relationships (default: true) --computed # Generate computed properties (default: true) --validate # Add validation helpers (default: false) --watch # Watch mode for development (default: false)

Examples

# Basic generation npx gluonic codegen --prisma=./prisma/schema.prisma # Custom output directory npx gluonic codegen --prisma=./schema.prisma --out=./models # Without decorators (imperative API) npx gluonic codegen --prisma=./schema.prisma --format=imperative # With validation helpers npx gluonic codegen --prisma=./schema.prisma --validate # Watch mode (regenerate on schema changes) npx gluonic codegen --prisma=./schema.prisma --watch

Configuration File

For complex projects, use gluonic.config.ts:

// gluonic.config.ts export default { codegen: { prisma: './prisma/schema.prisma', output: './src/models', format: 'decorators', // Customize generation exclude: ['_prisma_migrations', 'Session'], // Field transformations transformers: { // Convert Prisma DateTime to timestamps DateTime: () => 'number', // Custom serialization Json: () => 'Record<string, any>' }, // Computed properties computed: { user: [ { name: 'displayName', type: 'string', code: 'return this.name || this.email.split("@")[0]' } ] } } }

Then run:

npx gluonic codegen

Integration with Development Workflow

npm script

{ "scripts": { "db:migrate": "prisma migrate dev", "db:generate": "prisma generate", "models:generate": "gluonic codegen", "postmigrate": "npm run models:generate" } }

Result: Client models regenerate automatically after Prisma migrations!

Watch Mode

# Terminal 1: Watch Prisma schema npx gluonic codegen --watch # Terminal 2: Run dev server npm run dev # Edit prisma/schema.prisma # → Models regenerate automatically ✓

Type Safety Benefits

Before (Manual)

// Typo in field name - compiles but breaks at runtime! đź’Ą @Property() emial: string = '' // Should be 'email'

After (Generated)

// Generated from Prisma schema @Property() email: string = '' // Always correct âś“ // Typo in Prisma schema caught by database migration

Relationship Auto-Detection

Codegen analyzes Prisma relationships:

model Post { id String @id authorId String author User @relation(fields: [authorId], references: [id]) } model User { id String @id posts Post[] }

Generates:

// Post.ts @ManyToOne('posts', 'authorId') author?: User // User.ts @OneToMany('author') posts: LazyCollection<Post> = new LazyCollection<Post>()

Perfect inference! No manual relationship configuration needed.

Monorepo Support

For shared models across packages:

# Generate to shared package npx gluonic codegen \ --prisma=../../packages/database/prisma/schema.prisma \ --out=../../packages/models/src

Project structure:

monorepo/ ├── packages/ │ ├── database/ # Prisma schema │ ├── models/ # Generated models (shared) │ ├── api/ # Server (imports models) │ └── app/ # Client (imports models)

Custom Templates

Override default templates:

gluonic codegen --template=./templates/model.ts.hbs
// templates/model.ts.hbs import { Model, ClientModel, Property } from '@gluonic/client' @ClientModel('{{modelName}}') export class {{className}} extends Model { {{#each fields}} @Property({{#if serverOnly}}{ server: true }{{/if}}) {{name}}: {{type}} = {{default}} {{/each}} // Custom computed property get id(): string { return this.id } }

Next Steps

Last updated on