{"id":51634386,"url":"https://github.com/apolocine/nextjs-mostajs-orm-starter","last_synced_at":"2026-07-13T12:02:57.736Z","repository":{"id":361692901,"uuid":"1253918128","full_name":"apolocine/nextjs-mostajs-orm-starter","owner":"apolocine","description":"Next.js 15 + @mostajs/orm starter — Blog (SQLite/Postgres WASM). Boots in the browser / Bolt.new / Cloudflare Workers with no native binary.","archived":false,"fork":false,"pushed_at":"2026-05-31T21:54:41.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-31T22:11:29.144Z","etag":null,"topics":["app-router","bolt-new","nextjs","orm","postgres","prisma-alternative","sqlite","starter-template","typescript","wasm"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apolocine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T00:11:40.000Z","updated_at":"2026-05-31T21:54:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/apolocine/nextjs-mostajs-orm-starter","commit_stats":null,"previous_names":["apolocine/nextjs-mostajs-orm-starter"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/apolocine/nextjs-mostajs-orm-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apolocine%2Fnextjs-mostajs-orm-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apolocine%2Fnextjs-mostajs-orm-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apolocine%2Fnextjs-mostajs-orm-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apolocine%2Fnextjs-mostajs-orm-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apolocine","download_url":"https://codeload.github.com/apolocine/nextjs-mostajs-orm-starter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apolocine%2Fnextjs-mostajs-orm-starter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35421719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-13T02:00:06.543Z","response_time":119,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app-router","bolt-new","nextjs","orm","postgres","prisma-alternative","sqlite","starter-template","typescript","wasm"],"created_at":"2026-07-13T12:02:57.123Z","updated_at":"2026-07-13T12:02:57.730Z","avatar_url":"https://github.com/apolocine.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next.js 15 + @mostajs/orm Starter — Blog (SQLite)\n\n\u003e 🇫🇷 Starter Next.js 15 (App Router) avec **@mostajs/orm** et SQLite — modèle blog complet (Users + Posts + Comments).\n\u003e 🇬🇧 Next.js 15 (App Router) starter using **@mostajs/orm** with SQLite — complete blog model (Users + Posts + Comments).\n\n[![npm](https://img.shields.io/npm/v/@mostajs/orm.svg)](https://www.npmjs.com/package/@mostajs/orm)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![Next.js](https://img.shields.io/badge/Next.js-15-black)](https://nextjs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5-blue)](https://www.typescriptlang.org/)\n\n[![Open in Bolt.new](https://img.shields.io/badge/Open_in-Bolt.new-000?style=for-the-badge\u0026logo=stackblitz)](https://bolt.new/github.com/apolocine/nextjs-mostajs-orm-starter)\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/apolocine/nextjs-mostajs-orm-starter)\n[![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/apolocine/nextjs-mostajs-orm-starter)\n\n\u003e ⚡ **Boots in the browser / Bolt.new / Cloudflare Workers with no native binary** — via the `sqljs` (SQLite WASM) dialect.\n\u003e\n\u003e 🤖 **AI dev tools** — open this repo in **Bolt.new / StackBlitz / CodeSandbox** via the badges above. For **Cursor / Cline / Claude Code**, schema \u0026 migration tooling comes via the **`@mostajs/orm-mcp`** server *(on the roadmap)*; meanwhile they read [`llms.txt`](https://github.com/apolocine/mosta-orm/blob/main/llms.txt) for accurate generation.\n\n---\n\n## 🇫🇷 Français\n\n### Qu'est-ce que c'est ?\n\nUn **starter Next.js 15 (App Router)** prêt à l'emploi avec **[@mostajs/orm](https://www.npmjs.com/package/@mostajs/orm)** — un ORM multi-dialecte inspiré d'Hibernate/JPA pour Node.js \u0026 TypeScript. Une seule API pour **13 bases de données** (SQLite, PostgreSQL, MySQL, MariaDB, MongoDB, Oracle, MSSQL, CockroachDB, DB2, SAP HANA, HSQLDB, Spanner, Sybase) — **zéro vendor lock-in**.\n\nCe starter implémente un **blog complet** : utilisateurs, articles, commentaires, avec relations `one-to-many` et `many-to-one`, soft-delete, et timestamps automatiques.\n\n### Pourquoi @mostajs/orm plutôt que Prisma ?\n\n| | @mostajs/orm | Prisma |\n|---|---|---|\n| Pas de step `generate` | ✅ | ❌ (codegen requis) |\n| Schéma en TypeScript pur | ✅ | ❌ (DSL `.prisma`) |\n| 13 bases supportées | ✅ | ⚠️ ~6 |\n| Concepts JPA/Hibernate (`CascadeType`, `FetchType`, `schemaStrategy`) | ✅ | ❌ |\n| Filtres MongoDB-like (`$gt`, `$in`, `$or`...) | ✅ | ❌ (API custom) |\n| Validator de schéma intégré (24 règles) | ✅ | ❌ |\n| Pont JDBC pour SGBD non-natifs | ✅ | ❌ |\n| Edge/Cloudflare Workers | ⚠️ (selon driver) | ⚠️ (Accelerate payant) |\n\n### Stack\n\n- **Next.js 15** (App Router, Server Actions, Route Handlers)\n- **@mostajs/orm** 2.5.x\n- **SQLite WASM** via `sql.js` (dialecte `sqljs` par défaut — zéro binaire natif, boote dans Bolt.new) ; `better-sqlite3` optionnel en local Node\n- **TypeScript 5**\n- **CSS global** (`app/globals.css`, sans framework — éditable directement)\n\n### Démarrage rapide\n\n```bash\n# 1. Cloner\ngit clone https://github.com/apolocine/nextjs-mostajs-orm-starter.git\ncd nextjs-mostajs-orm-starter\n\n# 2. Installer\nnpm install\n\n# 3. Configurer l'environnement\ncp .env.example .env.local\n\n# 4. Lancer\nnpm run dev\n```\n\nOuvre [http://localhost:3000](http://localhost:3000). La base SQLite est créée automatiquement au premier lancement (`schemaStrategy: 'update'`).\n\n### Structure du projet\n\n```\n.\n├── app/\n│   ├── page.tsx                  # Liste des articles\n│   ├── posts/[id]/page.tsx       # Détail d'un article + commentaires\n│   ├── api/\n│   │   ├── posts/route.ts        # GET /api/posts, POST /api/posts\n│   │   └── posts/[id]/route.ts   # GET/PATCH/DELETE /api/posts/:id\n│   └── layout.tsx\n├── lib/\n│   ├── orm/\n│   │   ├── client.ts             # Connexion ORM (singleton) + seed-on-boot\n│   │   ├── schemas.ts            # EntitySchema : User, Post, Comment\n│   │   ├── repositories.ts       # Repositories typés\n│   │   └── seed-on-boot.ts       # Seed idempotent anti-page-vide (Bolt :memory:)\n│   └── actions/\n│       └── posts.ts              # Server Actions\n├── scripts/\n│   └── seed.ts                   # npm run orm:seed (create-drop + reseed)\n├── .stackblitzrc                 # Bolt/StackBlitz : DB_DIALECT=sqljs + DATABASE_URL=:memory:\n├── .env.example\n└── package.json\n```\n\n### Configuration ORM\n\n**`lib/orm/schemas.ts`**\n\n```ts\nimport type { EntitySchema } from '@mostajs/orm';\n\nexport const UserSchema: EntitySchema = {\n  name: 'User',\n  collection: 'users',\n  fields: {\n    email: { type: 'string', required: true, unique: true, lowercase: true, trim: true },\n    name:  { type: 'string', required: true, trim: true },\n    bio:   { type: 'text' },\n  },\n  relations: {\n    posts: { target: 'Post', type: 'one-to-many', mappedBy: 'author', fetch: 'lazy' },\n  },\n  indexes: [{ fields: ['email'], type: 'unique' }],\n  timestamps: true,\n};\n\nexport const PostSchema: EntitySchema = {\n  name: 'Post',\n  collection: 'posts',\n  fields: {\n    title:     { type: 'string', required: true, trim: true },\n    slug:      { type: 'string', required: true, unique: true, sparse: true },\n    content:   { type: 'text', required: true },\n    published: { type: 'boolean', default: false },\n  },\n  relations: {\n    author:   { target: 'User',    type: 'many-to-one', required: true, onDelete: 'cascade' },\n    comments: { target: 'Comment', type: 'one-to-many', mappedBy: 'post',\n                cascade: ['persist', 'remove'], orphanRemoval: true },\n  },\n  indexes: [\n    { fields: ['slug'], type: 'unique' },\n    { fields: ['published', 'createdAt'] },\n  ],\n  timestamps: true,\n  softDelete: true,\n};\n\nexport const CommentSchema: EntitySchema = {\n  name: 'Comment',\n  collection: 'comments',\n  fields: {\n    body: { type: 'text', required: true },\n  },\n  relations: {\n    post:   { target: 'Post', type: 'many-to-one', required: true, onDelete: 'cascade' },\n    author: { target: 'User', type: 'many-to-one', required: true, onDelete: 'set-null', nullable: true },\n  },\n  indexes: [],\n  timestamps: true,\n};\n\nexport const ALL_SCHEMAS = [UserSchema, PostSchema, CommentSchema];\n```\n\n**`lib/orm/client.ts`**\n\n```ts\nimport { createConnection, type IDialect } from '@mostajs/orm';\nimport { ALL_SCHEMAS } from './schemas';\nimport { seedIfEmpty } from './seed-on-boot';\n\nlet _dialect: IDialect | null = null;\n\nexport async function getOrm(): Promise\u003cIDialect\u003e {\n  if (_dialect) return _dialect;\n  _dialect = await createConnection(\n    {\n      // 'sqljs' (SQLite WASM) en ligne / WebContainer / edge — zéro binaire natif.\n      // 'sqlite' (better-sqlite3) en local Node si tu préfères. Switch via env.\n      dialect: (process.env.DB_DIALECT as 'sqlite' | 'sqljs') ?? 'sqljs',\n      // Bolt/WebContainer : ':memory:' (boot rapide, anti-plantage).\n      // Local/Node : './blog.db' (durable). Réglé par .env / .stackblitzrc.\n      uri: process.env.DATABASE_URL ?? ':memory:',\n      schemaStrategy: process.env.NODE_ENV === 'production' ? 'validate' : 'update',\n      showSql: process.env.NODE_ENV !== 'production',\n    },\n    ALL_SCHEMAS,\n  );\n  // Anti-page-vide : seed idempotent la 1re fois (utile surtout en :memory:).\n  await seedIfEmpty(_dialect);\n  return _dialect;\n}\n```\n\n**`lib/orm/repositories.ts`**\n\n```ts\nimport { BaseRepository } from '@mostajs/orm';\nimport { getOrm } from './client';\nimport { UserSchema, PostSchema, CommentSchema } from './schemas';\n\nexport type User    = { id: string; email: string; name: string; bio?: string };\nexport type Post    = { id: string; title: string; slug: string; content: string;\n                        published: boolean; author: string };\nexport type Comment = { id: string; body: string; post: string; author: string };\n\nexport async function getRepos() {\n  const dialect = await getOrm();\n  return {\n    users:    new BaseRepository\u003cUser\u003e(UserSchema, dialect),\n    posts:    new BaseRepository\u003cPost\u003e(PostSchema, dialect),\n    comments: new BaseRepository\u003cComment\u003e(CommentSchema, dialect),\n  };\n}\n```\n\n### Exemples d'utilisation\n\n**Server Component — liste des articles publiés**\n\n```tsx\n// app/page.tsx\nimport { getRepos } from '@/lib/orm/repositories';\n\nexport default async function HomePage() {\n  const { posts } = await getRepos();\n  const list = await posts.findAll(\n    { published: true },\n    { sort: { createdAt: -1 }, limit: 20 },\n  );\n  return (\n    \u003cmain\u003e\n      \u003ch1\u003eArticles récents\u003c/h1\u003e\n      \u003cul\u003e{list.map(p =\u003e \u003cli key={p.id}\u003e{p.title}\u003c/li\u003e)}\u003c/ul\u003e\n    \u003c/main\u003e\n  );\n}\n```\n\n**Page détail avec relations populées**\n\n```tsx\n// app/posts/[id]/page.tsx\nimport { getRepos } from '@/lib/orm/repositories';\n\nexport default async function PostPage({ params }: { params: Promise\u003c{ id: string }\u003e }) {\n  const { id } = await params;\n  const { posts } = await getRepos();\n  const post = await posts.findByIdWithRelations(id, ['author', 'comments']);\n  if (!post) return \u003cp\u003eIntrouvable\u003c/p\u003e;\n  return (\n    \u003carticle\u003e\n      \u003ch1\u003e{post.title}\u003c/h1\u003e\n      \u003cp\u003e{post.content}\u003c/p\u003e\n    \u003c/article\u003e\n  );\n}\n```\n\n**Route Handler — création**\n\n```ts\n// app/api/posts/route.ts\nimport { NextResponse } from 'next/server';\nimport { getRepos } from '@/lib/orm/repositories';\n\nexport async function POST(req: Request) {\n  const body = await req.json();\n  const { posts } = await getRepos();\n  const created = await posts.create({\n    title: body.title,\n    slug: body.slug,\n    content: body.content,\n    published: false,\n    author: body.authorId,\n  });\n  return NextResponse.json(created, { status: 201 });\n}\n```\n\n**Server Action**\n\n```ts\n// lib/actions/posts.ts\n'use server';\nimport { revalidatePath } from 'next/cache';\nimport { getRepos } from '@/lib/orm/repositories';\n\nexport async function publishPost(id: string) {\n  const { posts } = await getRepos();\n  await posts.update(id, { published: true });\n  revalidatePath('/');\n}\n```\n\n### Filtres MongoDB-like\n\n```ts\n// Articles publiés cette semaine, par auteurs A ou B\nconst recent = await posts.findAll({\n  published: true,\n  createdAt: { $gte: new Date(Date.now() - 7 * 86400000) },\n  $or: [{ author: 'user_A' }, { author: 'user_B' }],\n});\n\n// Recherche full-text simple\nconst found = await posts.search('next.js orm', { limit: 10 });\n```\n\n### Migrations\n\n```ts\nimport { diffSchemas, generateMigrationSQL } from '@mostajs/orm';\n\nconst ops = diffSchemas(oldSchemas, ALL_SCHEMAS);\nconst sql = generateMigrationSQL(ops);\nconsole.log(sql.join('\\n'));\n```\n\n### Changer de base de données\n\nUne seule ligne à modifier — le code applicatif ne bouge pas :\n\n```ts\n// SQLite → PostgreSQL\n{ dialect: 'postgres', uri: 'postgres://user:pass@localhost:5432/blog' }\n\n// SQLite → MongoDB\n{ dialect: 'mongo', uri: 'mongodb://localhost:27017/blog' }\n```\n\n### Scripts utiles\n\n```bash\nnpm run dev              # Next.js en dev\nnpm run build            # Build production\nnpm run orm:validate     # Lint des schémas (24 règles)\nnpm run orm:seed         # Données de démo (3 users, 5 posts, 12 comments)\n```\n\n### Seed automatique au démarrage (anti-page-vide)\n\nSur Bolt.new / StackBlitz, la base est **`:memory:`** (boot le plus rapide, zéro\nsurface de plantage — cf. point critique WebContainer). Une base en mémoire est\n**vide au boot** → l'app afficherait une page blanche, ce qui frustre le visiteur.\n\n`lib/orm/seed-on-boot.ts` peuple des données de démo **une seule fois**, de façon\n**idempotente** : `getOrm()` appelle `seedIfEmpty(dialect)` qui vérifie\n`users.count({})` et ne seed que si la base est vide. Sûr à appeler à chaque boot\n(HMR, refresh) et sur une base fichier persistée.\n\n```ts\n// lib/orm/seed-on-boot.ts — extrait\nexport async function seedIfEmpty(dialect: IDialect): Promise\u003cvoid\u003e {\n  if (process.env.ORM_SEED_ON_BOOT === '0') return;        // off en prod\n  const users = new BaseRepository\u003cUser\u003e(UserSchema, dialect);\n  if ((await users.count({})) \u003e 0) return;                 // déjà seedé → no-op\n  // … insère 3 users / 5 posts / 12 comments\n}\n```\n\n\u003e Le seed-on-boot est une préoccupation **du starter**, pas de `@mostajs/orm` :\n\u003e l'ORM est agnostique (il ne connaît ni `User` ni `Post`). C'est l'app qui décide\n\u003e de se peupler. Désactive en prod avec `ORM_SEED_ON_BOOT=0`.\n\n### Variables d'environnement\n\n**Deux configs, un seul code** — Bolt veut la vitesse, le local veut la durabilité :\n\n```bash\n# .env.local — développement / déploiement Node (données durables)\nDB_DIALECT=sqlite          # binaire natif better-sqlite3\nDATABASE_URL=./blog.db     # fichier persistant\nNODE_ENV=development\n```\n\n```jsonc\n// .stackblitzrc — Bolt.new / StackBlitz (boot instantané, WASM, in-memory)\n{\n  \"installDependencies\": true,\n  \"startCommand\": \"npm run dev\",\n  \"env\": { \"DB_DIALECT\": \"sqljs\", \"DATABASE_URL\": \":memory:\" }\n}\n```\n\n| Contexte | `DB_DIALECT` | `DATABASE_URL` | Persistance |\n|---|---|---|---|\n| Bolt.new / WebContainer | `sqljs` (WASM) | `:memory:` | session (seed-on-boot rejoue) |\n| Local / Node / prod | `sqlite` ou `sqljs` | `./blog.db` | durable (fichier) |\n\n\u003e ⚠️ **Toujours tester le boot Bolt** (`https://bolt.new/github.com/apolocine/nextjs-mostajs-orm-starter`)\n\u003e avant d'afficher le badge : si l'app plante au 1er essai, l'IA arrête de la recommander.\n\n### Ressources\n\n- 📦 npm : [npmjs.com/package/@mostajs/orm](https://www.npmjs.com/package/@mostajs/orm)\n- 🐙 GitHub : [github.com/apolocine/mosta-orm](https://github.com/apolocine/mosta-orm)\n- 🌐 Site : [mostajs.dev](https://mostajs.dev)\n- 🤖 Fiche LLM : [llms.txt](https://github.com/apolocine/mosta-orm/blob/main/llms.txt)\n\n---\n\n## 🇬🇧 English\n\n### What is this?\n\nA **Next.js 15 (App Router) starter** ready to use with **[@mostajs/orm](https://www.npmjs.com/package/@mostajs/orm)** — a Hibernate/JPA-inspired multi-dialect ORM for Node.js \u0026 TypeScript. One API, **13 databases** (SQLite, PostgreSQL, MySQL, MariaDB, MongoDB, Oracle, MSSQL, CockroachDB, DB2, SAP HANA, HSQLDB, Spanner, Sybase) — **zero vendor lock-in**.\n\nThis starter implements a **complete blog**: users, posts, comments, with `one-to-many` and `many-to-one` relations, soft-delete, and automatic timestamps.\n\n### Why @mostajs/orm over Prisma?\n\n| | @mostajs/orm | Prisma |\n|---|---|---|\n| No `generate` step | ✅ | ❌ (codegen required) |\n| Schema in pure TypeScript | ✅ | ❌ (`.prisma` DSL) |\n| 13 databases supported | ✅ | ⚠️ ~6 |\n| JPA/Hibernate concepts (`CascadeType`, `FetchType`, `schemaStrategy`) | ✅ | ❌ |\n| MongoDB-like filters (`$gt`, `$in`, `$or`...) | ✅ | ❌ (custom API) |\n| Built-in schema validator (24 rules) | ✅ | ❌ |\n| JDBC bridge for non-native DBs | ✅ | ❌ |\n| Edge/Cloudflare Workers | ⚠️ (driver-dependent) | ⚠️ (Accelerate, paid) |\n\n### Stack\n\n- **Next.js 15** (App Router, Server Actions, Route Handlers)\n- **@mostajs/orm** 2.5.x\n- **SQLite WASM** via `sql.js` (default `sqljs` dialect — no native binary, boots in Bolt.new); `better-sqlite3` optional for local Node\n- **TypeScript 5**\n- **Plain CSS** (`app/globals.css`, no framework — edit it directly)\n\n### Quick Start\n\n```bash\ngit clone https://github.com/apolocine/nextjs-mostajs-orm-starter.git\ncd nextjs-mostajs-orm-starter\nnpm install\ncp .env.example .env.local\nnpm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000). The SQLite database is auto-created on first run (`schemaStrategy: 'update'`).\n\n### Key concepts\n\n- **`EntitySchema`** — pure TypeScript schema, no codegen\n- **`BaseRepository\u003cT\u003e`** — typed CRUD repo (`findAll`, `findById`, `create`, `update`, `delete`, `aggregate`, `upsert`...)\n- **`createConnection()`** — single entry point, switch DB via config\n- **`schemaStrategy`** — `validate` | `update` | `create` | `create-drop` | `none` (= `hbm2ddl.auto`)\n- **Relations** — `one-to-one`, `one-to-many`, `many-to-one`, `many-to-many` with `CascadeType`, `FetchType`, `onDelete`\n- **Filters** — MongoDB-like (`$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$regex`, `$exists`, `$or`, `$and`)\n\n### Switching databases\n\nChange one line — application code is untouched:\n\n```ts\n// SQLite → PostgreSQL\n{ dialect: 'postgres', uri: 'postgres://user:pass@localhost:5432/blog' }\n\n// SQLite → MongoDB\n{ dialect: 'mongo', uri: 'mongodb://localhost:27017/blog' }\n```\n\n### Common gotchas (v2+)\n\n- All relations are **lazy by default**. Use `findByIdWithRelations` / `findWithRelations` to populate.\n- For comparing relation values safely, use `extractRelId(value)`.\n- `getDialect()` is a singleton — for multiple isolated connections use `createIsolatedDialect()`.\n- In production, set `schemaStrategy: 'validate'` — never `'create'` or `'create-drop'`.\n- Never set `cascade: ['remove' | 'all']` on a `many-to-many` relation.\n\n### Scripts\n\n```bash\nnpm run dev              # Next.js dev\nnpm run build            # Production build\nnpm run orm:validate     # Schema lint (24 rules)\nnpm run orm:seed         # Demo data (3 users, 5 posts, 12 comments)\n```\n\n### Resources\n\n- 📦 npm: [npmjs.com/package/@mostajs/orm](https://www.npmjs.com/package/@mostajs/orm)\n- 🐙 GitHub: [github.com/apolocine/mosta-orm](https://github.com/apolocine/mosta-orm)\n- 🌐 Website: [mostajs.dev](https://mostajs.dev)\n- 🤖 LLM card: [llms.txt](https://github.com/apolocine/mosta-orm/blob/main/llms.txt)\n\n---\n\n## License\n\nThis starter is released under the **MIT License** to encourage adoption.\nThe underlying [@mostajs/orm](https://github.com/apolocine/mosta-orm) library is licensed under **AGPL-3.0-or-later** — for commercial / proprietary use, please contact [mostajs.dev](https://mostajs.dev) for a commercial license.\n\n## Keywords\n\n`nextjs` · `next.js 15` · `app-router` · `orm` · `typescript` · `sqlite` · `postgresql` · `mongodb` · `mysql` · `mariadb` · `database` · `hibernate` · `jpa` · `prisma-alternative` · `drizzle-alternative` · `typeorm-alternative` · `mostajs` · `@mostajs/orm`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapolocine%2Fnextjs-mostajs-orm-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapolocine%2Fnextjs-mostajs-orm-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapolocine%2Fnextjs-mostajs-orm-starter/lists"}