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/modelsOutput:
âś“ 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/modelsGenerated 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 --watchConfiguration 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 codegenIntegration 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 migrationRelationship 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/srcProject 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
- CLI Reference - All CLI commands
- Prisma Integration - Prisma-specific tips
- TypeScript Configuration - Decorator setup
Last updated on