# ORM (/academy/orm)



SQL is the language of the filing cabinet. TypeScript is the language of your app. They do not get along at parties.

An **ORM** — Object Relational Mapper — is the translator in the middle. You say "get me all todos for this user" in TypeScript. The ORM says it again in SQL. The [database](/academy/database) answers. The ORM hands you objects your code already understands.

Without one, you write raw SQL strings and hope a typo isn't a production incident. With one, a missing column is a red squiggle *before* you run the app.

**Drizzle, Prisma, Mongoose**

Same job. Different accents.

* **Drizzle** — feels like SQL you can type-check. You see the query. You stay close to the cabinet.
* **Prisma** — feels like a generated client. You describe the shape, it writes the talking.
* **Mongoose** — the translator for Mongo, where the cabinet is documents, not rows.

`none` means you will write SQL (or Mongo queries) yourself. That's brave. It's also a Saturday you may not have.

**Migrations are the paper trail**

When you add a column, the cabinet has to change. A *migration* is the signed note: "as of this commit, todos have a `done` field." Run it on your laptop, run it in production, the cabinets match.

Skip migrations and you get the classic hackathon bug: it works locally because your file already has the column, and it dies on the judge's laptop because theirs doesn't.

**What this unlocks**

The ORM is not the database. It's how your [backend](/academy/frontend-backend) is allowed to be wrong in TypeScript instead of wrong in production.

Pick one. Let it complain early. Spend the complaint budget on the product.
