@flixy-dev/prisma-json-types-generator
v1.0.5
Published
High-performance Prisma generator for strongly typed JSON and string union fields.
Readme
Prisma JSON Types Generator
A high-performance Prisma generator that adds strong typing support for JSON fields and string enums in your Prisma schema.
✨ Features
- 🎯 Type-safe JSON fields - Replace
JsonValuewith your custom TypeScript types - 🔤 String literal unions - Transform string fields to union types (
'draft' | 'published') - ⚡ Blazing fast - Optimized with incremental caching and AST-based patching
- 🔄 Zero runtime overhead - Pure TypeScript type transformations
- 🎨 IDE support - Full autocomplete and type checking in your editor
- 📦 Array support - Type JSON arrays with custom element types
- 🔧 Flexible syntax - Namespace references or inline type definitions
📦 Installation
npm install --save-dev @flixy-dev/prisma-json-types-generator
# or
yarn add -D @flixy-dev/prisma-json-types-generator
# or
pnpm add -D @flixy-dev/prisma-json-types-generator
# or
bun add -D @flixy-dev/prisma-json-types-generatorNote: in
schema.prisma, useprovider = "prisma-json-types-generator"(binary name), not the scoped npm package name.
🚀 Quick Start
1. Add the generator to your Prisma schema
generator client {
provider = "prisma-client-js"
}
generator jsonTypes {
provider = "prisma-json-types-generator"
namespace = "PrismaJson"
// Optional on v1.0.1+ (default: ./generated-json-types)
// Keep it explicit if you want a custom location:
// output = "./generated-json-types"
}
model User {
id String @id @default(cuid())
email String @unique
/// [UserProfile]
profile Json
/// [UserSettings]
settings Json?
}
model Post {
id String @id @default(cuid())
title String
/// ![{ views: number; likes: number }]
stats Json
/// !['draft' | 'published' | 'archived']
status String @default("draft")
}2. Create a type definition file
Create prisma/json-types.ts:
export {};
declare global {
namespace PrismaJson {
// Define types referenced in your schema with [TypeName]
type UserProfile = {
bio: string;
avatar: string;
website?: string;
};
type UserSettings = {
theme: 'light' | 'dark';
language: string;
notifications: boolean;
};
}
}3. Configure TypeScript
Add to your tsconfig.json:
{
"compilerOptions": {
"types": ["./prisma/json-types"]
}
}4. Generate Prisma Client
npx prisma generate5. Use your typed models
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const user = await prisma.user.create({
data: {
email: '[email protected]',
profile: {
bio: 'Software engineer',
avatar: 'https://example.com/avatar.jpg',
website: 'https://example.com'
},
settings: {
theme: 'dark',
language: 'en',
notifications: true
}
}
});
// ✅ Full type safety and autocomplete!
console.log(user.profile.bio); // string
console.log(user.settings?.theme); // 'light' | 'dark' | undefined
const post = await prisma.post.create({
data: {
title: 'Hello World',
stats: { views: 0, likes: 0 },
status: 'draft' // ✅ Only accepts 'draft' | 'published' | 'archived'
}
});
post.stats.views++; // ✅ Type-safe property access📖 Type Annotation Syntax
Namespace Reference (Recommended)
Reference types from your global namespace:
/// [TypeName]
field JsonExample:
model User {
/// [UserProfile]
profile Json
}Inline Type Definitions
Define types inline using TypeScript syntax:
/// ![TypeScript type here]
field JsonExamples:
model Post {
/// ![{ views: number; likes: number }]
stats Json
/// !['draft' | 'published']
status String
/// ![string]
tags Json[]
}Array Fields
JSON array fields automatically wrap the element type:
model Article {
/// [Author]
authors Json[] // Becomes: PrismaJson.Author[]
/// ![string]
tags Json[] // Becomes: string[]
}⚙️ Configuration
Add options to the generator in your schema.prisma:
generator jsonTypes {
provider = "prisma-json-types-generator"
namespace = "PrismaJson" // default: "PrismaJson"
clientOutput = "../src/.generated" // default: auto-detected
cache = "true" // default: "true"
cacheDir = ".pjtg-cache" // default: ".pjtg-cache"
profile = "false" // default: "false"
}Options
| Option | Default | Description |
|--------|---------|-------------|
| namespace | "PrismaJson" | Global namespace for type references |
| clientOutput | Auto-detected | Path to Prisma Client output (usually auto-detected) |
| cache | "true" | Enable incremental caching for faster rebuilds |
| cacheDir | ".pjtg-cache" | Directory for cache files (relative to schema) |
| profile | "false" | Enable profiling output to see timing information |
🎯 Advanced Usage
Using Type Maps
For large projects with many types, use the useType option:
generator jsonTypes {
provider = "prisma-json-types-generator"
namespace = "PrismaJson"
useType = "Types"
}Then define a type map:
declare global {
namespace PrismaJson {
type Types = {
UserProfile: { bio: string; avatar: string };
UserSettings: { theme: 'light' | 'dark' };
// ... more types
};
}
}Fields will use PrismaJson.Types["TypeName"] syntax.
Multi-file Schemas
The generator automatically handles multi-file Prisma schemas. Just point to the schema directory:
// prisma/schema/main.prisma
generator jsonTypes {
provider = "prisma-json-types-generator"
}
// prisma/schema/user.prisma
model User {
/// [UserProfile]
profile Json
}Complex Nested Types
You can use any TypeScript type syntax in inline definitions:
model Product {
/// ![{
/// name: string;
/// variants: Array<{
/// id: string;
/// price: number;
/// stock: number
/// }>;
/// metadata?: Record<string, unknown>;
/// }]
data Json
}⚡ Performance
This generator is optimized for performance:
- Incremental caching - Only processes changed files
- Concurrent processing - Parallel file operations
- AST-based patching - No regex, just precise TypeScript AST transformations
- Minimal overhead - Typically adds <100ms to
prisma generate
Benchmarks
On a production schema with 50+ models:
- Cold run (no cache): ~190ms
- Warm run (cached): ~10ms
- Memory usage: <50MB
Enable profiling to see detailed timing:
PJTG_PROFILE=1 npx prisma generate🔧 Troubleshooting
Types not recognized
Ensure your type definition file is included in
tsconfig.json:{ "compilerOptions": { "types": ["./prisma/json-types"] } }Restart your TypeScript server in your IDE
Check that you're using
declare global { namespace PrismaJson }in your type file
Generator not running
- Make sure the generator is listed in
schema.prisma - Run
npx prisma generateexplicitly - Check for errors in the output
- If you use the new Prisma client generator (
provider = "prisma-client"), update to@flixy-dev/[email protected]+
Can't resolve output dir for generator ...
If Prisma asks for output in the generator block:
generator jsonTypes {
provider = "prisma-json-types-generator"
output = "./generated-json-types"
}- In v1.0.1+ this is optional (the generator provides a default output).
- In older versions, set
outputexplicitly.
Cache issues
If you experience stale types, clear the cache:
rm -rf prisma/.pjtg-cache
npx prisma generateOr disable caching temporarily:
generator jsonTypes {
provider = "prisma-json-types-generator"
cache = "false"
}📝 Examples
Check the test/fixtures/ directory for complete examples:
basic/- Simple namespace types and inline definitionscomplex/- Nested objects and arraysedge-cases/- Complex scenarios and edge cases
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
# Clone the repository
git clone https://github.com/yourusername/prisma-json-types-generator.git
cd prisma-json-types-generator
# Install dependencies
bun install
# Run tests
bun test
# Run tests in watch mode
bun test:watch
# Run with coverage
bun test:coverageRunning Benchmarks
# In-memory benchmark
bun bench/bench-patcher.ts path/to/index.d.ts
# End-to-end benchmark
bun bench/bench-prisma-generate.ts --warmup 3 --runs 10📄 License
MIT
📦 Build & Publish
# 1) build distributable package into ./dist
bun run build
# 2) dry-run package contents
bun run pack:check
# 3) run publish safety checks
bun run prepublishOnly
# 4) publish to npm (public scoped package)
npm publish --access publicNotes:
- Make sure you are logged in:
npm login - If package name/version already exists, bump version first:
npm version patch(orminor/major)
🙏 Acknowledgments
Inspired by prisma-json-types-generator by Arthur Fiorette, completely rewritten for performance and maintainability.
