Understand PrismaPrisma & Traditional ORMs

Prisma & TypeORM

Learn how Prisma compares to TypeORM

Overview

This page compares Prisma with TypeORM. Here is a high-level overview:

PrismaTypeORM
Auto-generated DB client
Type-safe
Declarative data modelling & migrations
Connection pooling
Supported DB typesDocument & RelationalDocument & Relational
Supported ORM patternsDataMapperDataMapper & ActiveRecord
Fluent API for relations
Relation filters
Raw database access
Transactional nested writes
Manual transactions

In the following, you find a detailled comparison of the TypeORM and Prisma APIs.

Fetching single objects

Prisma

const user = await prisma.user({ id })

TypeORM

const userRepository = getRepository(User)
const user = await userRepository.findOne(id)

Fetching selected scalars of single objects

Prisma

const userFragment = await prisma.user({ id }).$fragment(`
  fragment NameAndEmail on User { id email }`
`)

TypeORM

const userRepository = getRepository(User) 
const user = await userRepository.findOne(id, {
  select: ["id", "email"]
})

Fetching relations

Prisma

Fluent API
Using fragments
Native GraphQL
const postsByUser = await prisma
  .user({ id })
  .posts()

While the $fragment and the $graphql APIs each return a user object that includes a posts array, the fluent API returns just the posts array and no data about the user.

See the following GitHub issues to learn more about planned iterations of the Prisma client relations API:

TypeORM

Using `relations`
Using JOIN
Eager relations
const userRepository = getRepository(User)
const user = await userRepository.findOne(id, {
  relations: ["posts"]
})

Filtering for concrete values

Prisma

const users = await prisma.users({
  where: {
    name: "Alice"
  }
})

TypeORM

const userRepository = getRepository(User)
const users = await userRepository.find({
  where: {
    name: "Alice"
  }
})

Other filter criteria

Prisma

Prisma generates many additional filters that are commonly used in modern application development:

  • <field>_ends_with & <field>_starts_with
  • <field>_not_ends_with & <field>_not_starts_with
  • <field>_gt & <field>_gte
  • <field>_lt & <field>_lte
  • <field>_contains & <field>_not_contains
  • <field>_in & <field>_not_in

TypeORM

TypeORM doesn't expose other filter critera. But you can use the QueryBuilder API to send queries using LIKE and other SQL operators.

Relation filters

Prisma

Prisma lets you filter a list based on a criteria that applies not only to the models of the list being retrieved, but to a relation of that model.

For example, you want to fetch only those users that wrote a post with the title "Hello World":

query {
  user(where: {
    posts_some: {
      title: "Hello World"
    }
  }) {
    id
  }
}

TypeORM

TypeORM doesn't offer a dedicated API for relation filters. You can get similar functionality by using the QueryBuilder or writing the queries by hand.

Creating objects

Prisma

const user = await prisma.createUser({
  name: "Alice",
  email: "alice@prisma.io"
})

TypeORM

Using `save`
Using `create`
Using `insert`
const user = new User()
user.name = "Alice"
user.email = "alice@prisma.io"
await user.save()

Updating objects

Prisma

const updatedUser = await prisma.updateUser({
  where: { id },
  data: {
    name: "James",
    email: "james@prisma.io"
  }
})

TypeORM

const userRepository = getRepository(User)
const updatedUser = await userRepository.update(id, {
  name: "James",
  email: "james@prisma.io"
})

Deleting objects

Prisma

const deletedUser = await prisma.deleteUser({ id })

TypeORM

Using `delete`
Using `remove`
const userRepository = getRepository(User)
await userRepository.delete(id)

Batch updates

Prisma

const updatedUsers = await prisma
  .updateManyUsers({
    data: {
      role: "ADMIN"
    },
    where: {
      email_ends_with: "@prisma.io"
    }
  })

TypeORM

TypeORM doesn't offer a dedicated API for batch updates, but you can use save on an array of entities which leads to similar functionality.

Batch deletes

Prisma

await prisma.deleteManyUsers({
  id_in: [id1, id2, id3]
})

TypeORM

Using `delete`
Using `remove`
const userRepository = getRepository(User)
await userRepository.delete([id1, id2, id3])

Transactions

Prisma

const newUser = await prisma.createUser({
  name: "Bob",
  email: "bob@prisma.io",
  posts: {
    create: [
      { title: "Join us for GraphQL Conf in 2019" },
      { title: "Subscribe to GraphQL Weekly for GraphQL news" }
    ]
  }
})

TypeORM

await getConnection().transaction(async transactionalEntityManager => {
    const user = getRepository(User).create({
      name: "Bob",
      email: "bob@prisma.io"
    })
    const post1 = getRepository(Post).create({
      title: "Join us for GraphQL Conf in 2019",
    })
    const post2 = getRepository(Post).create({
      title: "Subscribe to GraphQL Weekly for GraphQL news",
    })
    user.posts = [post1, post2]
    await transactionalEntityManager.save(post1)
    await transactionalEntityManager.save(post2)
    await transactionalEntityManager.save(user)
  })