# PalJS turns a Prisma schema into a GraphQL API and an admin UI

> PalJS is a Prisma 7 native generator that emits Nexus GraphQL types, TypeScript types, an admin schema and pages from your Prisma models, all during prisma generate. The trade is that the output is generated rather than authored, so what you exclude from the generator is what you do not get, and the whole admin surface depends on how well your models are shaped.

**AhmedElywa/prisma-tools** — Prisma tools to help you generate CRUD system for GraphQL servers

- Repository: https://github.com/AhmedElywa/prisma-tools
- Website: https://paljs.com
- Stars: 696 · Forks: 59
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/ahmedelywa-prisma-tools

## A Prisma generator, not a separate command

The problem PalJS addresses is the gap between a database schema and a usable API. You have Prisma models and a GraphQL server, and the two are connected by hand-written resolvers, plus a separate admin interface, plus type definitions that drift from the schema. PalJS is presented as a comprehensive toolkit for building modern GraphQL APIs with Prisma, and from v9 it integrates directly with Prisma 7 or newer as a native generator, so the code generation, admin interfaces and query optimization run automatically during prisma generate. The README is explicit that no separate CLI is needed. The intended user is a TypeScript team whose data model is already in Prisma and whose GraphQL layer is the repetitive part, and the homepage for the project is paljs.com rather than a repository page.

## The install is two npm commands and a generator block

Installation splits into a development dependency and a runtime dependency, which is the conventional split for a Prisma generator. The generator and Prisma itself go in as dev dependencies, and the plugins and the Nexus integration go in as runtime packages. The generator is then declared in your schema alongside the existing Prisma client generator, pointing at the provider name, an output directory and a config file, and the datasource block stays as it was. That last point matters because it means the tool sits next to your client generator rather than replacing it, and the two run in the same prisma generate pass:```bash
npm install -D @paljs/generator prisma

# Install runtime dependencies
npm install @paljs/plugins @paljs/nexus
``` The generator block itself is short:```prisma
generator paljs {
  provider = "paljs-generator"
  output   = "../generated/paljs"
  config   = "../paljs.config.ts"
```

## The config file decides what gets generated at all

Everything the tool does is governed by a config file using defineConfig from the generator package, and the basic shape is:```typescript
export default defineConfig({
  // Generate TypeScript types for PrismaSelect
  generateTypes: true,

  // Generate Nexus GraphQL types
``` and the switches are all booleans or path names. There is a switch for generating TypeScript types for PrismaSelect, one for generating the Nexus GraphQL types, and a nested generateAdmin object with an enabled flag, an output directory and a routerType that is app for the Next.js App Router or pages for the Pages Router. Then there are the exclusion lists: excludeFields for fields to keep out of everything, excludeInputFields for fields to keep out of GraphQL inputs, excludeQueriesAndMutations for operations to remove, and the disableQueries and disableMutations flags to switch a whole category off. Per-model configuration mirrors all of it, so a single model can opt out of a specific mutation while the rest of the schema keeps it. The pattern that comes out of this is that sensitive fields are declared once and stay out of the API, which is the mechanism that makes a generated surface safe to expose.

## One command produces the schema, the types, the Nexus layer and the admin

Running the generation step is a single command:```bash
npx prisma generate
``` and the output tree is described in the README as four directories under the generator output. The dmmf directory holds DMMF data for runtime use, the types directory holds the TypeScript types for PrismaSelect, the nexus directory holds the Nexus GraphQL types, queries and mutations, and the admin directory holds the admin UI schema and pages. The DMMF piece is the one that is easy to overlook, since it is the data model metadata the runtime plugins need in order to reason about your schema at request time, which is what makes the automatic field selection possible. Nothing here is a placeholder to be filled in later, it is the actual artefact your server imports.

## PrismaSelect rewrites the query, not the resolver

The part of the toolkit that goes beyond code generation is PrismaSelect, in the plugins package. The Nexus plugin handles Prisma integration with automatic field selection, and the plugin itself is a Nexus plugin for that integration. The usage pattern is a class instantiated inside a resolver with the resolver info and the DMMF data, and it takes a defaultFields map per model and an excludeFields map per model, so the same exclusion rules you wrote in the config file apply to the query Prisma actually runs. The resolver then calls findMany with select.value instead of a hand-written select object. The practical difference is that a client asking for a field the schema does not expose cannot get it, and a client asking for one it does expose does not pull the excluded columns along.

## The server side is three imports and a makeSchema call

Wiring the generated Nexus types into a server is deliberately small. The schema module imports makeSchema from nexus and the generated types, and passes the types plus an outputs block naming a typegen file and a schema.graphql file for the toolchain to write. The whole GraphQL surface is therefore whatever the generator emitted, and the server file itself is configuration rather than logic. The corresponding resolver pattern is the same: instantiate PrismaSelect with the info and the dmmf, pass it the select to the Prisma call, and let the framework handle the rest. For a project that has written these resolvers by hand, the pitch is that this file is a few lines instead of a few hundred.

## Four packages, and the admin UI is a separate one

The package table splits the toolkit into four publishable pieces, and the split tells you what the project is. The generator is the Prisma 7 native generator for GraphQL schemas, types and the admin UI, the plugins package holds PrismaSelect and the other GraphQL plugins for query optimization, the nexus package is the Nexus plugin for Prisma integration with automatic field selection, and the admin package holds React admin UI components built with Tailwind CSS. The v9 announcement also mentions a React 19 admin UI with Tailwind CSS 4, and a typed PrismaSelect, which tells you the admin side was rewritten rather than carried over. The repository is a bun workspace over packages and examples, with Biome for format and lint, changesets for versioning, and lefthook for the git hooks.

## The generated surface is only as good as your model

The limitation to hold in mind is that this is a generator, and a generator can only be as opinionated as its configuration. Your GraphQL schema is derived from your Prisma models, so a relation, a naming choice or a field type in the database will show up in the API whether or not you wanted it there, and the fix is always in the exclusion lists or in a per-model override rather than in the generated file. The same applies to the admin interface, which is why the generateAdmin object can be limited to specific models. The other limitation is the version floor, since v9 is a major rewrite with a native Prisma 7 generator, a React 19 admin and a typed PrismaSelect, and the README links a migration guide for people coming from earlier versions. The licence is MIT, and the recent releases are v9.0.0 dated 2026-02-04 after a v9.0.0 beta in January.

## Conclusion

PalJS suits a team with a Prisma data model who wants a GraphQL API and a working admin interface without writing CRUD resolvers and screens by hand, and who is prepared to shape their models so the generated surface is the surface they want. It does not suit a project that needs bespoke GraphQL semantics, because the resolver layer is generated and shaped by configuration rather than by code, and it does not suit a team on Prisma 6 or earlier, since the v9 rewrite targets Prisma 7 and up. Before adopting, read docs/MIGRATION-v9.md if you are moving from an earlier PalJS, and note that the last push to the repository was on 2026-06-11 with release v9.0.0 dated 2026-02-04.

## FAQ

### How do I install PalJS?

Two npm commands. Install the generator and Prisma as dev dependencies with `npm install -D @paljs/generator prisma`, and the runtime packages with `npm install @paljs/plugins @paljs/nexus`, then declare the paljs generator block in your Prisma schema pointing at the paljs-generator provider.

### What does PalJS generate from a Prisma schema?

Running prisma generate produces four output directories: the DMMF data for runtime use, TypeScript types for PrismaSelect, Nexus GraphQL types, queries and mutations, and the admin UI schema and pages. The generator runs as part of prisma generate, so no separate CLI is needed.

### How do I keep sensitive fields out of the generated GraphQL API?

The config file has an excludeFields list applied to all models, an excludeInputFields list for GraphQL inputs, and excludeQueriesAndMutations for operations, plus per-model configuration that can exclude individual mutations. The PrismaSelect resolver plugin applies the same exclusions to the queries that actually run.

### What is PrismaSelect and what does it do in a PalJS resolver?

PrismaSelect comes from the @paljs/plugins package and rewrites the Prisma query based on what the GraphQL client asked for. You instantiate it in a resolver with the resolver info and the DMMF data, set defaultFields and excludeFields per model, and pass its select.value to the Prisma call.

### Does PalJS work with Prisma 6 and earlier?

Not the current version. From v9 PalJS is a Prisma 7 native generator, with a React 19 admin UI using Tailwind CSS 4 and a typed PrismaSelect, and the README links a migration guide for people moving up from earlier releases. The licence is MIT and the newest tagged release is v9.0.0 from 2026-02-04.

## Sources

- [AhmedElywa/prisma-tools on GitHub](https://github.com/AhmedElywa/prisma-tools)
- [License: MIT](https://github.com/AhmedElywa/prisma-tools/blob/main/LICENSE)
- [Project website](https://paljs.com)
- [README](https://github.com/AhmedElywa/prisma-tools/blob/main/README.md)
- [Releases](https://github.com/AhmedElywa/prisma-tools/releases)

---

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