Max Heinritz > Posts Introducing prisma-lint

Introducing prisma-lint

A few months ago I released prisma-lint, an open source version of a tool we use internally at Loop. It’s a linter for Prisma schema files.

Example

A schema file looks like this:

// prisma.schema

model User {
  id String @id @default(uuid())
  firstName String
  lastName String
  emailAddress String
  createdAt DateTime
  tenantId String
  tenant Tenant @relation(fields: [tenantId], references: [qid])
}

model Tenant {
  id String @id @default(uuid())
  name String
  createdAt DateTime
}

The linter can enforce style preferences like singular model names (User not Users) as well as behaviors such as requiring all tables to have a createdAt field. Here’s an example configuration:

// .prismalintrc.json

{ 
  "model-name-grammatical-number": ["error", { "style": "singular" }],
  "require-field": ["error", { "require": [ "createdAt" ]}]
}

The schema file is used to generate database migrations and application-level types. The linter can enforce rules that impact this generated code, such as requiring snake case database table names and a prefix for generated types:

model DbUser {
  // ...
  @@map(name: "user")
}

model DbTenant {
  // ...
  @@map(name: "tenant")
}
{ 
  // ...
  "model-name-mapping-snake-case": ["error", { "trimPrefix": "Db" }],
  "model-name-prefix": ["error", { "prefix": "Db" }],
}

One of the more powerful rules is require-field-index, which can be configured to require all fields used in relations be indexed.

Kudos

I was inspired by ESLint (especially for the configuration file schema) as well as RuboCop, which first got me hooked on developing AST-based tooling. The fast iteration cycle and immediate impact is exhilarating.

Shout out to Jeremy Liberman for writing the schema parser used under the hood. We worked together to expose AST node location data for contextual output: PR #25, PR #26.

Shout outs also to Sean Nicolay, Shu Liu, and Evan Richards – co-workers at Loop who wrote the initial internal implementations of a few rules.

Livestream

The Prisma team asked me to speak about it on their livestream, which you can view here.

Follow up

Some of the more fun parts of this project include tooling to automate releases and support for Neovim diagnostics. I may write follow-up posts to go deeper on those.