{"id":16587,"library":"xorma","title":"Xorma In-memory Reactive Database","description":"Xorma is a synchronous, reactive, in-memory database at an early stage of development (version 0.0.1). It is specifically designed for building complex frontend applications such as video editors, design tools, IDEs, and games, where maintaining complex object graphs with frequent write operations is common. Developed initially in 2022 for a 3D circuit simulator, Xorma leverages MobX for its core reactivity, allowing developers to define observable models (`Model.withType(DataType)`) and manage application state in a centralized `Store`. A key differentiator is its synchronous API for data manipulation, coupled with a guarantee that only one instance of a model will ever exist for a given ID within the store, ensuring data consistency and simplifying reactivity patterns. While actively developed, its 0.0.1 version indicates a rapidly evolving API and no established release cadence.","status":"active","version":"0.0.1","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","typescript"],"install":[{"cmd":"npm install xorma","lang":"bash","label":"npm"},{"cmd":"yarn add xorma","lang":"bash","label":"yarn"},{"cmd":"pnpm add xorma","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core reactivity engine for Xorma models and store operations.","package":"mobx","optional":false}],"imports":[{"note":"The central repository for all models and data. ESM-only due to modern frontend focus.","wrong":"const { Store } = require('xorma');","symbol":"Store","correct":"import { Store } from 'xorma';"},{"note":"Base class for defining data structures. Typically extended via `Model.withType(DataType)`.","wrong":"import Model from 'xorma/Model';","symbol":"Model","correct":"import { Model } from 'xorma';"},{"note":"Used with `Model.withType()` to provide type information for model instances.","wrong":"import { Data } from 'xorma';","symbol":"DataType","correct":"import { DataType } from 'xorma';"},{"note":"Essential MobX decorators/functions for making Xorma model properties reactive. Although from MobX, they are integral to defining Xorma models.","symbol":"observable, makeObservable","correct":"import { observable, makeObservable } from 'mobx';"}],"quickstart":{"code":"import { DataType, Model, Store } from 'xorma';\nimport { observable, makeObservable, autorun } from 'mobx';\n\ninterface TaskData {\n  id: string;\n  name: string;\n  done: boolean;\n}\n\n// 1. Define your base model\nclass BaseModel extends Model.withType(DataType<TaskData>()) {\n  static idSelector(data: TaskData) {\n    return data.id;\n  }\n}\n\n// 2. Define your specific data model extending BaseModel\nclass TaskModel extends BaseModel.withType(DataType<TaskData>()) {\n  name!: string;\n  done!: boolean;\n\n  constructor(data: TaskData) {\n    super(data);\n    makeObservable(this, {\n      name: observable,\n      done: observable\n    });\n    this.loadJSON(data);\n  }\n\n  // Method to update instance data from JSON\n  loadJSON(data: TaskData) {\n    this.name = data.name;\n    this.done = data.done;\n  }\n\n  toJSON(): TaskData {\n    return { id: this.id, name: this.name, done: this.done };\n  }\n}\n\n// 3. Create a store and register your models\nconst store = new Store({\n  schemaVersion: 1,\n  models: {\n    Task: TaskModel // Register TaskModel under the key 'Task'\n  }\n});\n\n// Access the collection for TaskModel\nconst taskCollection = store.getCollection(TaskModel);\n\n// 4. Add data to the store (synchronous)\nconsole.log('Adding tasks...');\nconst task1 = taskCollection.create({\n  id: 'task-1',\n  name: 'Learn Xorma',\n  done: false\n});\n\nconst task2 = taskCollection.create({\n  id: 'task-2',\n  name: 'Build something great',\n  done: false\n});\n\n// 5. Demonstrate reactivity with MobX autorun\nautorun(() => {\n  const allTasks = taskCollection.getAll();\n  console.log('\\n--- Reactive Task List ---');\n  allTasks.forEach(task => console.log(`[${task.id}] ${task.name} (Done: ${task.done})`));\n  console.log('--------------------------');\n});\n\n// 6. Update data and observe reactivity (synchronous)\nsetTimeout(() => {\n  console.log('\\nUpdating task-1...');\n  task1.name = 'Master Xorma';\n  task1.done = true;\n\n  // Trying to create a task with an existing ID will update it\n  taskCollection.create({\n    id: 'task-2',\n    name: 'Deploy something awesome', // Name is updated\n    done: true // Done status is updated\n  });\n\n  // Add a new task\n  taskCollection.create({\n    id: 'task-3',\n    name: 'Celebrate success',\n    done: false\n  });\n}, 1000);\n\n// Output after all operations (will be reactive, showing changes from setTimeout)\n","lang":"typescript","description":"This quickstart demonstrates defining models, creating a central store, performing synchronous CRUD operations, and observing reactive updates using MobX's `autorun`."},"warnings":[{"fix":"Monitor the official GitHub repository and documentation for updates. Pin exact versions in your `package.json` to prevent unexpected breaks.","message":"Xorma is currently at version 0.0.1. The API is in a very early stage of development and is subject to frequent and significant breaking changes without prior notice. Use in production at your own risk.","severity":"breaking","affected_versions":">=0.0.1"},{"fix":"Understand that `create` acts as an 'upsert' when an ID collision occurs. If you need distinct instances, ensure unique IDs or use other methods if provided by the API for deep cloning/copying.","message":"Xorma enforces a 'single instance per ID' guarantee. Attempting to `create` a model with an ID that already exists in the store will not create a new instance, but instead update the existing instance's data via its `loadJSON` method.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Exercise caution if handling sensitive data. For critical applications, consider performing a security audit or contributing to the project's security posture.","message":"The project repository indicates no security policy (`SECURITY.md`) has been defined. This means there's no formal process for reporting or addressing security vulnerabilities.","severity":"gotcha","affected_versions":">=0.0.1"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"In your custom `Model` class's constructor, ensure all properties intended to be reactive are listed in the `makeObservable(this, { ... })` call with `observable` or `computed`.","cause":"A property on a Xorma `Model` instance was accessed or modified in a reactive context but was not marked as observable using `makeObservable` in the constructor.","error":"Error: [mobx] Property 'fieldName' is not observable. Please ensure it is annotated with @observable, or added to an object passed to 'makeObservable'."},{"fix":"Ensure your functional React components are wrapped with `observer` from `mobx-react` (or `mobx-vue` for Vue) to subscribe them to observable changes from the Xorma store.","cause":"A React/Vue component that consumes data from the Xorma store is not properly wrapped as an observer.","error":"Component is not re-rendering after data changes."},{"fix":"This is expected behavior. If you need a truly new, separate instance, provide a unique ID. If you intend to update, this is the correct method. Otherwise, consider cloning an existing instance if the API provides such functionality.","cause":"You attempted to `create` a new model instance with an ID that already exists in the Xorma store. Xorma guarantees a single instance per ID.","error":"My `create` call is not returning a new instance, but modifying an existing one."}],"ecosystem":"npm"}