Prisma generator that creates Effect Schema types from Prisma schema compatible with Kysely
npm install prisma-effect-kyselyA Prisma generator that creates Effect Schema types from Prisma schema definitions with exact type safety and intelligent UUID detection.
- ✅ Type-Safe Generation: Zero type coercion, complete type safety
- ✅ Intelligent UUID Detection: Via @db.Uuid, nativeType, or field name patterns
- ✅ Enum Support: Effect Schema enums with @map annotation support
- ✅ Deterministic Output: Alphabetically sorted for consistent results
- ✅ Complete Type Mappings: All Prisma types mapped to Effect Schema equivalents
``bash`
bun add prisma-effect-kyselyor
npm install prisma-effect-kysely
`prisma`
generator effect_schemas {
provider = "prisma-effect-kysely"
output = "./generated/effect"
}
`bash`
npx prisma generate
Generates three files in the configured output directory:
Effect Schema enums from Prisma enums with exact literal types:
`typescript`
export const UserRoleSchema = Schema.Literal('admin', 'user', 'guest');
Effect Schema structs from Prisma models with Kysely integration (v5.0 direct exports):
`typescript
import { Schema } from "effect";
import { columnType, generated, Selectable } from "prisma-effect-kysely";
// EXPORTED - Branded ID schema
export const UserId = Schema.UUID.pipe(Schema.brand("UserId"));
export type UserId = typeof UserId.Type;
// EXPORTED - Model schema (direct export)
export const User = Schema.Struct({
id: columnType(Schema.UUID, Schema.Never, Schema.Never),
email: Schema.String,
createdAt: generated(Schema.DateFromSelf),
});
export type User = typeof User;
// EXPORTED - Kysely DB interface with Selectable
export interface DB {
User: Selectable
}
`
Re-exports all generated types for easy importing
Branded ID types are exported directly. Use type utilities from prisma-effect-kysely for other types:
`typescript
import { Selectable, Insertable, Updateable } from "prisma-effect-kysely";
import { User, UserId, DB } from "./generated";
// Branded ID type - direct import (no utility needed)
function getUser(id: UserId): Promise
// Extract types using utilities (Kysely-native pattern)
type UserSelect = Selectable
type UserInsert = Insertable
type UserUpdate = Updateable
// Use with Kysely
import { Kysely } from 'kysely';
const db = new Kysely
// Type-safe queries
const user = await db.selectFrom('User').selectAll().executeTakeFirst();
`
Naming Convention: All exported schemas use PascalCase, regardless of the Prisma model naming convention:
- Model User → export const Usersession_preference
- Model → export const SessionPreference
| Prisma Type | Effect Schema Type | Notes |
| ----------- | ------------------- | -------------------------------- |
| String | Schema.String | Schema.UUID for id fields |Schema.Number
| Int / Float | | With Schema.int() for integers |Schema.BigInt
| BigInt | | Exact bigint type |Schema.String
| Decimal | | String for precision |Schema.Boolean
| Boolean | | - |Schema.DateFromSelf
| DateTime | | Native Date for Kysely |Schema.Unknown
| Json | | Safe unknown type |Schema.Uint8Array
| Bytes | | - |Schema.Literal
| Enum | Enum Schema | With values |
The generator intelligently detects UUID fields through multiple strategies (in order):
1. Native Type: @db.Uuid attribute (most reliable)@db.Uuid
2. Documentation: in field commentsdbgenerated("gen_random_uuid()")
3. Default Value: or similarid
4. Field Name Patterns: , _id, _uuid, uuid
Example:
`prisma`
model User {
id String @id @db.Uuid @default(dbgenerated("gen_random_uuid()"))
userId String @db.Uuid // Detected via native type
productId String // Detected via field name pattern
}
This project uses Bun as the sole package manager.
`bashInstall dependencies
bun install
Release Process
This project uses Changesets for automated versioning and publishing:
$3
1. Add a changeset for your changes:
`bash
bun changeset
` Follow the prompts to describe your changes (patch/minor/major).
2. Commit the changeset:
`bash
git add .changeset/
git commit -m "docs: add changeset for [feature/fix]"
git push
`3. Automated Release PR: The CI will automatically:
- Create or update a "Version Packages" PR
- Update
package.json version
- Update CHANGELOG.md4. Publish: When you merge the "Version Packages" PR:
- CI automatically publishes to npm using Bun
- Creates a git tag (e.g.,
v1.15.0)
- Creates a GitHub release with auto-generated notes$3
`bash
Build and run all checks
bun run prepublishOnlyPublish
bun publish --access public
`Releasing (CI/CD)
This repo uses Changesets to automate versioning, changelog updates, npm publishing, git tags, and GitHub Releases.
$3
Add a changeset for any user-facing change:
`bash
bun changeset
`Commit the generated file in
.changeset/.$3
- When changesets land on
main, CI opens/updates a Version Packages PR.
- When the Version Packages PR is merged, CI:
- updates package.json + CHANGELOG.md
- publishes to npm (with provenance)
- creates/pushes vX.Y.Z tag
- creates a GitHub Release$3
-
NPM_TOKEN: npm access token with permission to publish prisma-effect-kyselyArchitecture
$3
This generator uses EXACT DMMF types from Prisma and implements zero type coercion:
- Uses
FieldDefault type matching Prisma's exact structure
- Type-safe validation with structural typing
- No as assertions or unsafe casts
- Complete TypeScript strict mode compliance$3
- Alphabetically sorted fields and models for consistency
- Branded types for UUIDs via
Schema.UUID
- Exact type inference - no widening to any or unknown
- Auto-generated headers with timestamps and edit warningsCustom Type Overrides
Use
@customType annotations to override Effect Schema types for Prisma-supported fields:`prisma
model User {
/// @customType(Schema.String.pipe(Schema.email()))
email String @unique /// @customType(Schema.Number.pipe(Schema.positive()))
age Int
/// @customType(Schema.String.pipe(Schema.brand('UserId')))
userId String
}
`Supported for: All Prisma scalar types (String, Int, Float, Boolean, DateTime, BigInt, Decimal, Json, Bytes)
Use cases:
- Email/URL validation
- Number constraints (positive, range, etc.)
- Custom branded types
- Refined string patterns
Examples:
`typescript
// Generated from Prisma schema with @customType annotations
export const _User = Schema.Struct({
email: Schema.String.pipe(Schema.email()),
age: Schema.Number.pipe(Schema.positive()),
userId: Schema.String.pipe(Schema.brand('UserId')),
});
`Troubleshooting
$3
If you're developing the generator locally, make sure to build it first:
`bash
npm run build
`Then reference it in your schema.prisma:
`prisma
generator effect_schemas {
provider = "node ./path/to/dist/generator.js"
output = "./generated/effect"
}
`$3
Check the generator output in console:
`
[Effect Generator] Starting generation...
[Effect Generator] Processing 15 models, 3 enums
[Effect Generator] ✓ Generated to ../../libs/types/storage/src/lib/effect
`$3
Add explicit
@db.Uuid attribute:`prisma
userId String @db.Uuid
``MIT