Generate lightweight TypeScript types from your Prisma schema. Perfect for frontend type sharing without importing heavy Prisma Client. Make sure to not add/edit the generated files as they vanishes after the new generate.
1. Installation :
npm install prisma-type-generator
# ni prisma-type-generator (@antfu/ni)2. Add generator to schema.prisma:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
}3. Generate:
npx prisma generate --no-hints4. Use:
import type { User, Profile } from "../generated/types/prisma";
const user: User = {
id: "123",
name: "John Doe",
email: "[email protected]",
};Problem: Prisma Client is heavy (~2MB+) and includes runtime code. You don't want it in your frontend bundle.
Solution: Generate lightweight TypeScript interfaces that are perfect for:
- β Frontend/Client-Side - Type-safe API responses without Prisma Client
- β API Response Types - Clean interfaces for REST/GraphQL APIs
- β Monorepo Sharing - Share types between packages without Prisma Client
- β Form Validation - Use types for form schemas and validation
- β Type-Only Imports - Zero runtime code, types only
Example:
// β Don't do this in frontend - Prisma Client is too heavy!
import { Prisma } from "@prisma/client";
// β
Do this instead - lightweight types only!
import type { User, Profile } from "../generated/types/prisma";Generates TypeScript interfaces from Prisma models and enum types with const objects.
Example:
model User {
id String @id @default(uuid())
name String
email String? @unique
createdAt DateTime @default(now())
}
enum UserRole {
ADMIN
USER
}Generated TypeScript:
export type UserRole = "ADMIN" | "USER";
export declare const UserRole: {
readonly ADMIN: "ADMIN";
readonly USER: "USER";
};
export interface User {
id: string;
name: string;
email: string | null;
createdAt: Date;
}where to have your generated files, to be in ( ie: generated/types, ) or in your shared monorepo lib.
Example:
generator types {
provider = "prisma-type-generator"
output = "../shared/types" // Custom output path
}Clears the output directory before generating new types. CI/CD pipelines, ensuring clean builds, or when debugging type generation issues. Prevents stale files from previous generations, ensures consistency, and helps catch issues early.
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
clear = true // Remove old files first
}Generates only enum types, skipping all model types. Faster generation, smaller output size, and focused type generation for enum-only use cases.
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
enumOnly = true // Only generate enums
}Generates types in the global namespace with a T prefix (e.g., TUser instead of User). No imports needed - types are available globally. Works well with global type declaration files.
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
global = true // Generate global types
}
model User {
id String @id
name String
}Generated TypeScript:
// Types are in global namespace with T prefix
declare type TUser = {
id: string;
name: string;
};Usage:
// No import needed!
const user: TUser = { id: "1", name: "John" };Generates types only for the specified models (comma-separated list). Selective type generation. Make sure to select the referential enums, models as well.
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
include = "User,UserTypeEnum"
}Skips specified models during type generation (comma-separated list). Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
exclude = "InternalModel,AdminUser,AuditLog" // Skip these
}Splits output into separate files - one file per model and enum. Faster IDE performance, better tree-shaking, easier navigation, and selective imports reduce bundle size.
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
splitFiles = true // One file per model/enum
}
model User {
id String @id
name String
}
model Post {
id String @id
title String
}
enum UserRole {
ADMIN
USER
}Generated File Structure:
generated/types/
βββ User.ts
βββ Post.ts
βββ UserRole.ts
βββ index.ts // Barrel export (if barrelExports = true)
Splits types by Prisma schema file names. Models are matched by name prefix (e.g., User* β user.ts).
Schema Files:
prisma/
βββ schema.prisma
βββ user.prisma
βββ post.prisma
Generator Config:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
splitBySchema = true // Split by schema files
}Generated File Structure:
generated/types/
βββ user.ts // User, UserProfile (from user.prisma)
βββ post.ts // Post (from post.prisma)
βββ index.ts // Exports everything (from schema.prisma)
Generates index.ts barrel exports for easier imports (enabled by default).
Example:
With barrelExports = true (default):
// generated/types/index.ts
export * from "./User";
export * from "./Post";
export * from "./UserRole";Generates basic utility types (Partial, Required, Readonly, DeepPartial, DeepRequired) for every model (enabled by default).
Example:
model User {
id String @id
name String
email String?
createdAt DateTime
}Generated Types:
export interface User {
id: string;
name: string;
email: string | null;
createdAt: Date;
}
export namespace User {
// Always generated (unless basicUtilityTypes = false)
export type Partial = Partial<User>;
export type Required = Required<User>;
export type Readonly = Readonly<User>;
export type DeepPartial<T = User> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
export type DeepRequired<T = User> = {
[P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};
}Maps Prisma types to custom TypeScript types globally (e.g., DateTime β string).
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
typeMappings = "DateTime=string,Bytes=Uint8Array"
}
model User {
id String @id
createdAt DateTime // Will be generated as string
avatar Bytes // Will be generated as Uint8Array
}Generated TypeScript:
export interface User {
id: string;
createdAt: string; // Mapped from DateTime
avatar: Uint8Array; // Mapped from Bytes
}Enables PrismaType namespace for JSON types, allowing you to extend JSON field types. you can even provide the namespaceName PrismaJson or anything you would like to use, and it's cross compatible with prisma-json-types-generator.
namespaceName Sets a custom namespace name for JSON type mapping (default: PrismaType).
Example:
schema.prisma:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
jsonTypeMapping = true // Enable PrismaType namespace
}
model User {
id String @id
preferences Json // Will use PrismaType.Json
metadata Json
}prisma-type.ts (create this file in your project dir):
Make sure to include this file in the tsconfig, also you can specify the path to the generated files,
// Extend PrismaType namespace with your JSON types
declare namespace PrismaType {
interface Json {
// Define your JSON structure here
}
// Or use specific types
interface UserPreferences {
theme: "light" | "dark";
notifications: boolean;
}
interface UserMetadata {
lastLogin: string;
ipAddress: string;
}
}Generated TypeScript:
export interface User {
id: string;
preferences: PrismaType.Json | null;
metadata: PrismaType.Json | null;
}Usage with Field-Level Override:
model User {
/// @type Json=UserPreferences
preferences Json // Will use PrismaType.UserPreferences
}Generates JSDoc comments from Prisma schema comments in the generated TypeScript.
Example:
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
jsDocComments = true // Generate JSDoc comments
}
/// User model represents a user account in the system
model User {
/// Unique identifier for the user
id String @id @default(uuid())
/// User's full name
name String
/// User's email address (optional)
email String? @unique
/// Account creation timestamp
createdAt DateTime @default(now())
}Generated TypeScript:
/**
* User model represents a user account in the system
*/
export interface User {
/**
* Unique identifier for the user
*/
id: string;
/**
* User's full name
*/
name: string;
/**
* User's email address (optional)
*/
email: string | null;
/**
* Account creation timestamp
*/
createdAt: Date;
}Override the TypeScript type for specific fields using comments. Per-field customization, API compatibility, or when different fields need different type representations.
Example:
model User {
id String @id
/// @type DateTime=string
createdAt DateTime // This field will be string, not Date
/// @type Json=UserPreferences
preferences Json // This field will be UserPreferences, not Record<string, unknown>
}
// Define UserPreferences in namespaceGenerated TypeScript:
export interface User {
id: string;
createdAt: string; // Overridden to string
preferences: UserPreferences | null; // Overridden to UserPreferences
}Creates string fields with autocomplete suggestions while still allowing other values (flexible enums).
Example:
Strict Enum (only allowed values):
model User {
/// @type !["email", "google"]
authProvider String // Only "email" or "google" allowed
}Generated TypeScript:
export interface User {
authProvider: "email" | "google"; // Strict - only these values
}Loose Enum (autocomplete + flexibility):
model User {
/// @type ["email", "google"]
authProvider String // Autocomplete suggests these, but accepts any string
}Generated TypeScript:
export interface User {
// Autocomplete suggests "email" | "google", but accepts any string
authProvider: "email" | "google" | (string & {});
}Add directives to your Prisma models to generate additional utility types. These are opt-in features that give you powerful type transformations.
Generates CreateInput and UpdateInput types that automatically exclude auto-generated fields.
Example:
/// @input
model User {
id String @id @default(uuid())
name String
email String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Generated Types:
export namespace User {
/**
* Input type for creating User (omits id, createdAt, updatedAt)
*/
export type CreateInput = Omit<User, "id" | "createdAt" | "updatedAt">;
/**
* Input type for updating User (all fields optional, omits id)
*/
export type UpdateInput = Partial<Omit<User, "id">>;
}Generates a Select type for type-safe Prisma query select clauses.
Example:
/// @select
model User {
id String @id
name String
email String
createdAt DateTime
}Generated Types:
export namespace User {
/**
* Select type for Prisma queries
*/
export type Select = {
id?: boolean;
name?: boolean;
email?: boolean;
createdAt?: boolean;
};
}Usage:
// Type-safe Prisma select // like: Prisma.UserSelectInput
const selectClause: User.Select = {
id: true,
name: true,
// email and createdAt are optional
};
// Use with Prisma Client
const user = await prisma.user.findUnique({
where: { id: "123" },
select: selectClause, // Type-safe!
});Generates types that include related models (e.g., WithPosts, WithProfile). Type-safe relations, better autocomplete, and ensures included relations match your schema.
Example:
/// @with posts,profile
model User {
id String @id
name String
posts Post[]
profile Profile?
}
model Post {
id String @id
title String
authorId String
author User @relation(fields: [authorId], references: [id])
}
model Profile {
id String @id
bio String
userId String @unique
user User @relation(fields: [userId], references: [id])
}Generated Types:
export namespace User {
/**
* User with relations: posts, profile
*/
export type WithPostsAndProfile = User & {
posts: Post[];
profile: Profile;
};
}Groups related fields together into reusable types. Logical field grouping, reusable field sets, or when you want to organize related fields.
Example:
/// @group timestamps createdAt,updatedAt
/// @group auth password,email
model User {
id String @id
name String
email String
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Generated Types:
export namespace User {
/**
* timestamps fields: createdAt, updatedAt
*/
export type TimestampsFields = Pick<User, "createdAt" | "updatedAt">;
/**
* auth fields: password, email
*/
export type AuthFields = Pick<User, "password" | "email">;
}Usage:
// Access auth fields
const authData: User.AuthFields = {
email: "[email protected]",
password: "hashed_password",
};Generates a Validated type that marks data as validated with a __validated: true marker. Runtime validation, type guards, or when you need to distinguish validated from unvalidated data. Type-safe validation, compile-time safety, and clear distinction between validated and unvalidated data.
Example:
/// @validated
model User {
id String @id
name String
email String @unique
createdAt DateTime @default(now())
}Generated Types:
export namespace User {
/**
* Validated User type
*/
export type Validated = User & { __validated: true };
}Usage:
// Validation function
function validateUser(user: User): User.Validated | null {
if (!user.email || !user.name) {
return null;
}
return { ...user, __validated: true as const };
}
// Use validated type
function processUser(user: User.Validated) {
// TypeScript knows this user is validated
console.log(user.name, user.email);
}
// Usage
const user: User = {
id: "123",
name: "John",
email: "[email protected]",
createdAt: new Date(),
};
const validated = validateUser(user);
if (validated) {
processUser(validated); // β
Type-safe!
}Generates types that exclude specific fields from a model.
Example:
/// @omit createdAt,updatedAt WithoutTimestamps
model User {
id String @id
name String
email String
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Generated Types:
export namespace User {
/**
* User without createdAt, updatedAt
*/
export type WithoutTimestamps = Omit<User, "createdAt" | "updatedAt">;
}Custom Type Name:
/// @omit password UserPublic
model User {
// ...
}Generated:
export type UserPublic = Omit<User, "password">;Generates types that include only specific fields from a model. Type-safe field selection, minimal types, and clean public APIs with only necessary fields.
Example:
/// @pick id,name,email
model User {
id String @id
name String
email String
password String
createdAt DateTime @default(now())
}Generated Types:
export namespace User {
/**
* User with only id, name, email
*/
export type PickIdNameEmail = Pick<User, "id" | "name" | "email">;
}Usage:
// User with only basic fields
const basicUser: User.PickIdNameEmail = {
id: "123",
name: "John",
email: "[email protected]",
// password and createdAt are excluded
};Custom Type Name:
/// @pick id,name,email UserBasic
model User {
// ...
}Generated:
export type UserBasic = Pick<User, "id" | "name" | "email">;π See Complete Features Documentation β - Even more detailed examples and advanced usage patterns
| Option | Type | Default | Description |
|---|---|---|---|
output |
string | "../generated/types" |
Output directory for generated types |
global |
boolean | false |
Generate global types with T prefix |
clear |
boolean | false |
Clear output directory before generating |
enumOnly |
boolean | false |
Only generate enum types (skip models) |
include |
string | - | Include only these models (comma-separated) |
exclude |
string | - | Exclude these models (comma-separated) |
typeMappings |
string | - | Custom type mappings (e.g., "DateTime=string") |
jsonTypeMapping |
boolean | false |
Enable PrismaType namespace for JSON types |
namespaceName |
string | PrismaType |
namespace for the jsonTypeMapping |
jsDocComments |
boolean | false |
Generate JSDoc comments from Prisma schema comments |
splitFiles |
boolean | false |
Split output into separate files per model/enum |
splitBySchema |
boolean | false |
Split types by schema file names |
barrelExports |
boolean | true |
Generate barrel exports (index.ts) |
basicUtilityTypes |
boolean | true |
Generate basics utility types (default=true) |
basicUtilityTypes
generator client {
provider = "prisma-client-js"
}
generator types {
provider = "prisma-type-generator"
output = "../generated/types"
jsonTypeMapping = true
jsDocComments = true
}
/// @input
/// @with posts
model User {
id String @id @default(uuid())
name String
email String? @unique
/// @type DateTime=string
createdAt DateTime @default(now())
/// @type Json=UserPreferences
preferences Json
posts Post[]
}
model Post {
id String @id @default(uuid())
title String
authorId String
author User @relation(fields: [authorId], references: [id])
}
enum UserRole {
ADMIN
USER
}Generated Output:
// generated/types/prisma.d.ts
export type UserRole = "ADMIN" | "USER";
export interface User {
id: string;
name: string;
email: string | null;
createdAt: string; // Custom mapped
preferences: UserPreferences | null; // Custom type
}
export namespace User {
export type CreateInput = Omit<User, "id" | "createdAt">;
export type UpdateInput = Partial<Omit<User, "id">>;
export type WithPosts = User & { posts: Post[] };
export type Partial = Partial<User>;
export type Required = Required<User>;
// ... more utility types
}Contributions are welcome! Please follow our contribution guidelines.
If you like the project, please consider giving a βοΈ on GitHub.
If you find a bug, please file an issue on GitHub
MIT License - see LICENSE file for details.