Skip to content

Emmanuel-Melon/jsonapi-nano

Repository files navigation

jsonapi-nano

A lightweight, ultra-fast, zero-dependency presentation layer engine for formatting data into strict, compliance-ready JSON:API spec configurations. 100% framework-agnostic design built for modern cloud-native architectures.

License: MIT NPM Version Bundle Size

📖 Complete Documentation

Our full installation guides, framework integration examples, type parameters, and error-handling utilities are live at: 👉 emmanuel-melon.github.io/jsonapi-nano


Installation

npm install @emelon/jsonapi-nano

Quick Start

import {
  createResource,
  serialize,
  belongsTo,
  fieldsFromQuery,
} from "@emelon/jsonapi-nano";

interface Article {
  id: string;
  title: string;
  body: string;
  authorId: string;
}

interface Author {
  id: string;
  name: string;
}

// 1. Define reusable presentation schemas matching your entities
const authorResource = createResource<Author>("authors", {
  attributes: (author) => ({ name: author.name }),
});

const articleResource = createResource<Article>("articles", {
  attributes: (article) => ({ title: article.title, body: article.body }),
  relationships: (article) => ({
    author: belongsTo("authors", article.authorId),
  }),
});

// 2. Format data into strict JSON:API specifications with side-loaded data
const mockArticles = [
  {
    id: "1",
    title: "The Will of Fire",
    body: "Believing in your dreams no matter what.",
    authorId: "7",
  },
];
const mockAuthors = [{ id: "7", name: "Naruto Uzumaki" }];

const output = serialize(mockArticles, articleResource, {
  include: {
    author: [mockAuthors, authorResource],
  },
  // Optional: Pass raw express/fastify query params for sparse fieldsets
  fields: fieldsFromQuery(req.query),
});

Output Target Shape:

{
  "data": [
    {
      "type": "articles",
      "id": "1",
      "attributes": {
        "title": "The Will of Fire",
        "body": "Believing in your dreams no matter what."
      },
      "relationships": {
        "author": {
          "data": { "type": "authors", "id": "7" }
        }
      }
    }
  ],
  "included": [
    {
      "type": "authors",
      "id": "7",
      "attributes": {
        "name": "Naruto Uzumaki"
      }
    }
  ],
  "meta": {
    "timestamp": "2026-06-13T18:20:33.243Z"
  }
}

Spec Compliance

jsonapi-nano is not a tutorial on JSON:API — see jsonapi.org for the full specification. Below is the current implementation status of serialize / createResource / serializeErrors against the spec.

Feature Status Notes
data (resource objects, type/id/attributes) ✅ Implemented Core createResource + serialize
meta (top-level and per-resource) ✅ Implemented Auto timestamp is opt-out via options.timestamp: false
links (top-level and per-resource) ✅ Implemented
relationships ✅ Implemented Semantic abstractions available via belongsTo helper
included (compound documents) ✅ Implemented Fully resolved and deduped by type+id via options.include
jsonapi top-level member ✅ Implemented Via serialize options
errors array ✅ Implemented serializeErrors, includes source.pointer/parameter/header
Sparse fieldsets (fields[type]) ✅ Implemented Fully supported via query utility filtering
Pagination links/meta helpers 🚧 Planned Not yet supported
Resource type validation 🚧 Planned No runtime validation of member-name format
Error object id / links.about 🚧 Planned Not yet on ErrorConfig

License

MIT © Emmanuel Gatwech

About

A lightweight, ultra-fast, zero-dependency presentation layer engine for formatting data into strict [JSON:API](https://jsonapi.org/) specification format.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors