# Prisma Json Types Generator: real types for Json columns

> Prisma types every Json field as JsonValue and every String field as string, and prisma-json-types-generator replaces those with TypeScript types you declare, so the compiler checks the values you read and write. It changes only the generated types, so there is no runtime cost, and version 5 dropped support for anything older than Prisma 7 and TypeScript 6.

**arthurfiorette/prisma-json-types-generator** — ⚒️ Changes JsonValues to your custom typescript type.

- Repository: https://github.com/arthurfiorette/prisma-json-types-generator
- Website: https://arthur.run/prisma-json-types-generator/
- Stars: 571 · Forks: 46
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/arthurfiorette-prisma-json-types-generator

## Prisma's Json type is a promise of nothing

The problem this generator addresses is small and specific. Prisma types every Json field as JsonValue and every String field as string, so a column that always holds a user profile object is indistinguishable at the type level from a column that holds a string, a number, an array or null. The generator replaces those types in the generated @prisma/client with TypeScript types you define, so the compiler checks the values you read and write.

Two properties make this unusually clean to adopt. It works with every database Prisma supports, since the work happens at the type level and not in the query layer. And only the generated types change, so there is no runtime cost. Nothing is added to the client bundle, no validator runs on the way in and no behaviour changes.

That second point is what separates this from the runtime validation libraries that solve a similar problem. The README has a section on validating types at runtime, and the generator also has TypedSQL support, so the project covers both ends, but the type replacement itself costs nothing.

The feature list is short. Object shapes for Json fields, including Json[] lists. Literal unions for String, Int and Float fields, which gives you enums without native database enums. Types declared in a global namespace or written inline in the schema. And support for several @prisma/client generators at once, which the README says is useful while you are moving the client to a new output location.

The audience is a TypeScript team that stores structured data in Json columns and has given up on modelling it, and the last of those features suggests the other audience, which is a team mid-migration between client output locations.

## Installing the generator and the agent skill

The package is a normal npm development dependency:

```bash
npm install -D prisma-json-types-generator
```

There is a second installation route, and it is unusual enough to notice. An agent skill for this generator is also available, and it is installed with:

```bash
npx skills add arthurfiorette/prisma-json-types-generator
```

The README explains what it does: it teaches AI agents to set up the generator and to type Prisma Json, String, Int and Float fields with the /// [Type] and /// ![Type] syntax. So the project ships a skill alongside the package, aimed at assistants that are being asked to modify a Prisma schema, and the syntax it teaches is the same syntax the generator reads.

There is a version constraint to respect, and the README puts it in an IMPORTANT callout. prisma-json-types-generator@5+ only supports Prisma v7 and TypeScript v6. That is a real boundary rather than a soft warning, and it is the kind of thing that turns into an afternoon if you find out after upgrading the generator in a project that is still on an older Prisma.

The package metadata fills in the rest. The name is prisma-json-types-generator, the version 5.2.0, the type is commonjs with index.js as the main entry, and the same file is registered as a binary named prisma-json-types-generator, which is what makes the provider name prisma-json-types-generator work in a schema. The runtime dependencies are the Prisma generator helper, semver, try, tslib and TypeScript itself, aliased as npm:typescript@^6.0.3, which is how the generator gets the compiler version it expects.

## The generator block and the options that matter

Options go in the generator block of schema.prisma, and the minimal form is short:

```prisma
generator json {
  provider  = "prisma-json-types-generator"
  namespace = "PrismaJson"
  allowAny  = false
  // etc...
}
```

The options table is where the design shows. The namespace option is the global namespace that holds your custom types, and it defaults to PrismaJson. clientOutput is the path to the @prisma/client output directory, which is detected automatically, so the README says to set it only when detection fails, as in some monorepos.

allowAny is the safety switch. When it is true, untyped Json fields resolve to any instead of unknown, and the default is false, which means an untyped Json field stays unknown and you have to narrow it yourself. That default is the interesting one, because it means a field you forget to type does not silently become an anything-shaped hole in your type checking.

useType names a type in your namespace to use for every untyped Json field, and the generator adds an index signature [key: string]: any to it, which is a way to say that this fallback is deliberately permissive rather than merely forgotten. Its default is undefined.

The last two options relate to TypedSQL. typedSqlUrlEnv is the environment variable holding the PostgreSQL URL used to match TypedSQL columns to schema fields, defaulting to DATABASE_URL, and typedSqlPath is the directory of your TypedSQL .sql files relative to the schema, defaulting to sql, to be set only if you changed typedSql.path in prisma.config.ts.

## Declaring types and attaching them with comments

The quick start has three steps, and the third is the one that decides whether the whole thing works.

First, add the generator to your schema after the client generator. Second, declare your types in a file such as src/types.ts, make sure your tsconfig.json includes it, and declare them in the global PrismaJson namespace:

```ts
// declare global only works inside a module, hence the empty export.
export {};

declare global {
  namespace PrismaJson {
    type UserProfile = {
      theme: 'dark' | 'light';
      twitterHandle?: string;
    };
  }
}
```

The comment at the top of that block is the kind of detail that saves an hour. Declaring a global namespace only works inside a module, so the file needs the empty export to be treated as one, and without it the declaration either fails or lands in the wrong scope.

Third, link the types to your schema by adding an AST comment above the Json field:

```prisma
    model User {
      id    Int    @id @default(autoincrement())
      email String @unique

      /// [UserProfile]
      profile Json
    }
```

After that, run npx prisma generate and the field is typed as PrismaJson.UserProfile, so reading user.profile.theme is checked against the union you declared. The comment syntax is what the skill teaches agents too, with the bracket form for Json fields and the exclamation form for the string, int and float literal unions.

Because the attachment is a comment in the schema, a field that is not annotated is simply left as JsonValue. Nothing fails, nothing warns you, and the type system is only as complete as your annotations.

## Enums without database enums, and how the client is consumed

The literal union syntax turns a String column into something that behaves like an enum without using Prisma's native enum type, which keeps the allowed values in your schema rather than in a database migration:

```prisma
model Post {
  id    Int    @id @default(autoincrement())
  title String

  /// !['draft' | 'published' | 'archived']
  status String @default("draft")
}
```

The point of keeping them in the schema is that the value set travels with the schema file rather than living in a database type that every client has to be told about separately.

The generated client is then used exactly as before, with the difference that the types are now specific:

```ts
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();

async function updateUserProfile() {
  const user = await prisma.user.update({
    where: { id: 1 },
    data: {
      profile: {
        theme: 'dark'
        // twitterHandle is optional
      }
    }
  });

  // user.profile is PrismaJson.UserProfile
  console.log(user.profile.theme); // 'dark'
}
```

Nothing in the call site changes. The same update, the same client, the same runtime behaviour, and the comment in the sample points out the payoff, that user.profile is PrismaJson.UserProfile and the theme property is narrowed to the union.

That is the whole argument of the project in one example: a database column that stores structured data stops being a hole in your type checking, at no cost in the bundle and with no change to the query layer.

## The version wall, the licence and what the repository holds

The maintenance picture is good. The recent tags are v5.2.0 on 2026-10-13, v5.1.1 on 2026-07-09 and v5.1.0 on 2026-05-25, and the last push to the repository was on 2026-10-19. The project is not archived, and the homepage in the metadata points at the author's own site, arthur.run/prisma-json-types-generator.

The version numbering carries the compatibility statement, and it is a hard one. Version 5 of the generator supports only Prisma 7 and TypeScript 6, which is visible in the package dependencies as the Prisma generator packages at the 7.10 line and TypeScript aliased to the 6.0.3 range. A team on Prisma 5 or TypeScript 5 is looking at the 4.x line of this package.

The licence is MIT, and the package metadata says so explicitly. The author also asks for sponsorship, and the README carries a note that the repository and the project would benefit from stars and shares, which is a small signal that this is a one person project with a community around it rather than a company backed tool.

The repository layout is a modern TypeScript one. There is an index.js as the binary entry, a src directory, a test directory with a unit test run through tsx and an end to end script, a scripts directory holding the TypedSQL test script, a skills directory for the agent skill, an assets directory, a docker-compose.yml, a pnpm workspace with a lock file, biome.json for formatting and linting, a husky directory, and .nvmrc and .npmrc files pinning the toolchain.

The docker-compose file is a test fixture rather than a deployment artefact, and it says so. It runs a Postgres 17 alpine container for the TypedSQL tests, because TypedSQL needs a live database to introspect queries, with a healthcheck on pg_isready, and the port published on 5432.

## Conclusion

Adopt prisma-json-types-generator if your Prisma schema has Json columns that your application code treats as structured objects, because the change costs nothing at runtime and moves the shape of the data into the type system. Do not adopt it if your Json fields are genuinely schemaless, since typing them buys nothing there, and check your Prisma and TypeScript versions first, because version 5 of the generator supports only Prisma 7 and TypeScript 6. Verify first that your declared types live in the namespace the generator looks in, that the comments attaching a type to a field are in the syntax the generator reads, and that the allowAny setting is still false when you want untyped fields to stay unknown rather than become any.

## FAQ

### What does prisma-json-types-generator do?

It replaces the types Prisma generates for Json and scalar fields with TypeScript types you declare. Prisma types every Json field as JsonValue and every String field as string, and the generator substitutes your own types so the compiler checks the values you read and write.

### How do I install and configure prisma-json-types-generator?

Install it with npm install -D prisma-json-types-generator, then add a generator block to schema.prisma with provider set to prisma-json-types-generator, a namespace such as PrismaJson, and the allowAny option. Types are declared in a global namespace in a TypeScript file that your tsconfig includes, and attached to fields with a /// [TypeName] comment.

### Does prisma-json-types-generator add any runtime cost?

No. The README states that only the generated types change, so there is no runtime cost, and it works with every database Prisma supports. The generator is a build-time tool rather than a client-side library.

### Which Prisma and TypeScript versions does version 5 of the generator support?

Only Prisma v7 and TypeScript v6, according to the README, which marks it as an IMPORTANT note. The package dependencies match, with the Prisma generator packages at the 7.10 line and TypeScript aliased to the 6.0.3 range.

## Sources

- [arthurfiorette/prisma-json-types-generator on GitHub](https://github.com/arthurfiorette/prisma-json-types-generator)
- [License: MIT](https://github.com/arthurfiorette/prisma-json-types-generator/blob/main/LICENSE)
- [Project website](https://arthur.run/prisma-json-types-generator/)
- [README](https://github.com/arthurfiorette/prisma-json-types-generator/blob/main/README.md)
- [Releases](https://github.com/arthurfiorette/prisma-json-types-generator/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/arthurfiorette-prisma-json-types-generator
