{"id":11170,"library":"json-api-serializer","title":"Framework-agnostic JSON:API Serializer","description":"json-api-serializer is a versatile JavaScript library for Node.js and browsers, designed to serialize JavaScript objects into JSON:API 1.0 compliant documents and deserialize JSON:API documents back into standard JavaScript objects. The current stable version is 2.6.6. It maintains an active development cycle, frequently releasing minor updates and bug fixes. Key differentiators include its framework-agnostic nature, extensive configuration options for defining complex relationships, links, and metadata, and support for both serialization and deserialization processes. It allows for fine-grained control over attribute whitelisting/blacklisting, case conversion, and custom logic for handling relationships, making it adaptable to various JSON:API implementations.","status":"active","version":"2.6.6","language":"javascript","source_language":"en","source_url":"https://github.com/danivek/json-api-serializer","tags":["javascript","json","json-api","jsonapi","json api","serializer"],"install":[{"cmd":"npm install json-api-serializer","lang":"bash","label":"npm"},{"cmd":"yarn add json-api-serializer","lang":"bash","label":"yarn"},{"cmd":"pnpm add json-api-serializer","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"While the documentation often shows CommonJS `require`, ESM default import is the standard for modern Node.js and browser environments. The package exports the constructor directly as the default export.","wrong":"const JSONAPISerializer = require('json-api-serializer');","symbol":"JSONAPISerializer","correct":"import JSONAPISerializer from 'json-api-serializer';"},{"note":"The `Serializer` is an *instance* created from the `JSONAPISerializer` class, not a direct named export. Attempting to import `Serializer` directly will result in an undefined module member error.","wrong":"import { Serializer } from 'json-api-serializer';","symbol":"Serializer (instance)","correct":"import JSONAPISerializer from 'json-api-serializer';\nconst serializer = new JSONAPISerializer();"}],"quickstart":{"code":"import JSONAPISerializer from 'json-api-serializer';\n\n// 1. Initialize the serializer\nconst serializer = new JSONAPISerializer();\n\n// 2. Register a 'user' type\nserializer.register('user', {\n  id: 'uuid', // Use 'uuid' as the ID field instead of default 'id'\n  blacklist: ['passwordHash'],\n  relationships: {\n    posts: {\n      type: 'post', // The type of the related resource\n      links: {\n        self: (data, extraData) => `/users/${data.uuid}/relationships/posts`\n      }\n    },\n    comments: {\n      type: 'comment',\n      alternativeKey: 'commentIds' // Use 'commentIds' if 'comments' relationship key is missing\n    }\n  },\n  links: {\n    self: (data) => `/users/${data.uuid}`\n  }\n});\n\n// 3. Register a 'post' type\nserializer.register('post', {\n  attributes: ['title', 'content', 'createdAt'],\n  relationships: {\n    author: {\n      type: 'user',\n      deserialize: (data) => data.id // Custom deserialization for author\n    }\n  }\n});\n\n// Example Data\nconst userData = {\n  uuid: 'u123',\n  name: 'Alice',\n  email: 'alice@example.com',\n  passwordHash: 'hashedpassword',\n  posts: [{ id: 'p1', title: 'My First Post' }, { id: 'p2', title: 'Another Post' }],\n  commentIds: ['c1', 'c2']\n};\n\nconst postData = {\n  id: 'p1',\n  title: 'My First Post',\n  content: 'Hello World!',\n  createdAt: new Date().toISOString(),\n  author: { id: 'u123' }\n};\n\n// 4. Serialize data\nconst serializedUser = serializer.serialize('user', userData);\nconsole.log('Serialized User:', JSON.stringify(serializedUser, null, 2));\n\n// 5. Deserialize data (requires a full JSON:API document)\nconst jsonApiDoc = {\n  data: {\n    type: 'user',\n    id: 'u123',\n    attributes: {\n      name: 'Alice',\n      email: 'alice@example.com'\n    },\n    relationships: {\n      posts: {\n        data: [\n          { type: 'post', id: 'p1' },\n          { type: 'post', id: 'p2' }\n        ]\n      }\n    }\n  },\n  included: [\n    { type: 'post', id: 'p1', attributes: { title: 'First Post Title' } },\n    { type: 'post', id: 'p2', attributes: { title: 'Second Post Title' } }\n  ]\n};\n\nconst deserializedData = serializer.deserialize('user', jsonApiDoc);\nconsole.log('Deserialized Data:', JSON.stringify(deserializedData, null, 2));","lang":"javascript","description":"This quickstart demonstrates how to initialize `json-api-serializer`, register custom schemas for 'user' and 'post' types with relationships, and then perform both serialization of a JavaScript object into JSON:API format and deserialization of a JSON:API document back into a plain object. It highlights `id` customization, blacklisting attributes, and defining relationship logic."},"warnings":[{"fix":"Upgrade to `json-api-serializer` version 2.4.1 or higher. Ensure your data structures are not unintentionally circular, especially when defining `relationships` where an object might reference itself or an ancestor.","message":"Older versions (prior to 2.4.1) could enter an infinite loop when deserializing data with circular references, leading to a 'Maximum call stack size exceeded' error.","severity":"breaking","affected_versions":"<2.4.1"},{"fix":"Always ensure all related `type`s specified in `relationships` options are registered before performing serialization or deserialization operations. For example, if a 'user' has 'posts', both 'user' and 'post' types must be registered.","message":"Attempting to serialize or deserialize a relationship for a type that has not been explicitly registered with `serializer.register()` will lead to errors.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Upgrade to version `2.6.6` or higher to correctly handle cases where `id` might be missing in the input. Alternatively, implement defensive checks in your application code for `id` presence after deserialization.","message":"Deserialized data might have `undefined` `id` fields if the input JSON:API document lacks an `id` for a resource, which can cause issues if your application expects all resources to have an `id`.","severity":"gotcha","affected_versions":"<2.6.6"},{"fix":"This was a fix in `v2.6.4`. Be aware that if your application relied on the presence of an `included` array in older versions even when no relationships had attributes, you might need to adjust your expectations or post-processing logic when upgrading.","message":"The behavior regarding the `included` array in serialized output has been adjusted. Previously, the `included` array might have been present even if the input had no attributes. This is now fixed to be more compliant.","severity":"deprecated","affected_versions":"<2.6.4"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Refactor your data to break circular dependencies, or ensure you are using `json-api-serializer` version 2.4.1 or higher which includes fixes for preventing circular deserialization.","cause":"Circular references in the data being serialized or deserialized, leading to an infinite recursion.","error":"RangeError: Maximum call stack size exceeded"},{"fix":"Register all resource types involved in relationships using `serializer.register('type', options)` before performing any serialization or deserialization operations that involve those relationships.","cause":"Attempting to serialize or deserialize data that contains a relationship to a type ('...') which has not been registered with the `serializer.register()` method.","error":"Error: Relationship '...' is not registered."},{"fix":"Ensure all relationships are properly registered. Review the `deserialize` function for relationships in your `serializer.register()` options to handle cases where `data` might be `null` or `undefined`, especially for optional relationships. Upgrade to `v2.6.5` or higher which fixes errors when deserializing unregistered relationships.","cause":"This error can occur during deserialization when an unregistered relationship is encountered, or when a relationship's `deserialize` function attempts to access `data.id` on an `undefined` or malformed relationship object.","error":"TypeError: Cannot read properties of undefined (reading 'id')"}],"ecosystem":"npm"}