This example demonstrates how to enforce action-only mutations with TanStack DB.
- Feature/UI code (
src/features/**) can import collections for read/query use. - Feature/UI code cannot call collection mutation methods directly (
insert,update,delete,upsert). - Writes are performed through
src/db/actions/*only.
This is enforced by a custom ESLint rule in eslint-rules/no-direct-collection-mutations.js, wired in eslint.config.mjs.
The rule uses collectionImportPatterns (list of regex strings) to match collection import paths.
An alternative strict import-ban approach using no-restricted-imports is included as commented config in eslint.config.mjs.
pnpm install
pnpm devsrc/db/collections/todoCollection.ts: collection wiringsrc/db/actions/todoActions.ts:createOptimisticActionmutationssrc/features/todos/TodoApp.tsx: reads directly withuseLiveQueryand includes an intentional invalid direct mutation exampleeslint-rules/no-direct-collection-mutations.js: custom lint rule
// src/features/todos/TodoApp.tsx
import { todoCollection } from '@/db/collections/todoCollection'
todoCollection.insert({
id: crypto.randomUUID(),
text: 'bad write',
completed: false,
createdAt: new Date(),
})Running pnpm lint will reject this mutation call.
If you want a clean lint pass, remove the intentional direct mutation call in src/features/todos/TodoApp.tsx.