Many-to-Many Relation in Drizzle ORM

From the Drizzle ORM cheat sheet · Relations · verified Jul 2026

Many-to-Many Relation

Define a many-to-many relationship using a junction table.

typescript
import { relations } from 'drizzle-orm';
import { pgTable, serial, text,
  integer, primaryKey } from 'drizzle-orm/pg-core';

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: text('title').notNull(),
});

export const tags = pgTable('tags', {
  id: serial('id').primaryKey(),
  name: text('name').unique().notNull(),
});

export const postsToTags = pgTable('posts_to_tags', {
  postId: integer('post_id').notNull()
    .references(() => posts.id),
  tagId: integer('tag_id').notNull()
    .references(() => tags.id),
}, (t) => ([
  primaryKey({ columns: [t.postId, t.tagId] }),
]));

export const postsRelations = relations(posts, ({ many }) => ({
  postsToTags: many(postsToTags),
}));

export const tagsRelations = relations(tags, ({ many }) => ({
  postsToTags: many(postsToTags),
}));

export const postsToTagsRelations = relations(postsToTags, ({ one }) => ({
  post: one(posts, {
    fields: [postsToTags.postId],
    references: [posts.id],
  }),
  tag: one(tags, {
    fields: [postsToTags.tagId],
    references: [tags.id],
  }),
}));
💡 Define relations() on the junction table too
⚡ Query nests through the junction (postsToTags)
📌 many() on each entity points at the junction
🟢 Junction needs FK references + its own relations
relationsmany-to-manyjunction

More Drizzle ORM tasks

Back to the full Drizzle ORM cheat sheet