← Back to archive

Repo of the Day

codedredd/pinia-orm

Published: Feb 23, 2024

Open repository ↗

The Pinia plugin to enable Object-Relational Mapping access to the Pinia Store. I used to use Vuex-ORM in vue 2, do this looks like a similar thing for Vue3

Summary

pinia-orm is a TypeScript plugin for Pinia, Vue's state manager, that adds ORM-style modeling and relational queries to Pinia stores. It lets engineers describe entities with decorators, normalize nested data, and run Laravel-style queries against the store. The project is published under the MIT license and ships with first-class Nuxt and axios integrations.

What it is useful for

This plugin helps Vue and Pinia developers manage relational client-side data without hand-maintaining normalization. It is useful for:

  • Modeling entities such as users, posts, and comments with typed fields and relations, including hasOne, hasMany, belongsTo, belongsToMany, hasManyThrough, and polymorphic relations like morphOne, morphTo, morphMany, morphToMany, and morphedByMany.
  • Querying those entities with chainable methods such as where, whereLike, whereHas, orderBy (with Intl.Collator support), groupBy, aggregates, and helpers like updateOrCreate and firstOrCreate.
  • Sharing normalized state across components while keeping types through ECMAScript decorators, single-table inheritance with nested discriminators, lifecycle hooks, mutators, casts, hidden fields, and query caching.
  • Building apps on Nuxt 3 or Nuxt 4 using the documented Nuxt module, or pulling records from an API via the axios plugin.

How engineers can use it

Install it alongside Pinia:

npm install pinia pinia-orm

Wire the plugin into Pinia in your app entry, then define models with decorators and query them through useRepo:

import { createPinia } from 'pinia'
import { createORM } from 'pinia-orm'

const pinia = createPinia().use(createORM())
import { Model, useRepo } from 'pinia-orm'
import { Attr, HasMany, Str, Uid } from 'pinia-orm/decorators'

class Todo extends Model {
  static entity = 'todos'
  @Uid() id!: string
  @Str('') text!: string
  @Attr(null) userId!: string | null
}

class User extends Model {
  static entity = 'users'
  @Uid() id!: string
  @Str('') name!: string
  @HasMany(() => Todo, 'userId') todos!: Todo[]
}

const userRepo = useRepo(User)
userRepo.save({ id: '1', name: 'John', todos: [{ text: 'Read the docs' }] })
const usersWithTodos = userRepo.with('todos').get()

The README documents strict version requirements: pinia-orm 2.x needs pinia >= 3, Node >= 22.12, and TypeScript >= 5.2, while the 1.x line targets pinia 2.x, Node >= 14, and TypeScript >= 4.x. Because decorators are central to the documented API, your TypeScript configuration must enable them; toolchain-specific setup details are not included in the quick start, and the README points readers to the full guide for the missing steps. To contribute, the README documents cloning the repo, running corepack enable, then pnpm install, pnpm build:stub && pnpm build:ci, and pnpm test.