npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ananto-in/mf-categories

v0.1.0

Published

Open reference data for Indian mutual fund scheme categories: SEBI's categorization with stable IDs, characteristics, AMFI label aliases and change history.

Downloads

228

Readme

mf-categories

Open reference data for Indian mutual fund scheme categories: SEBI's categorization with stable IDs, characteristics, AMFI label aliases and change history. JSON, with PHP and JS packages.

Version 0.1.0. Reflects the SEBI circular of 26 February 2026. Maintained by Deepesh Shah Chheda, ananto.in.

Why

SEBI renames, splits and discontinues scheme categories from time to time (most recently by the circular dated 26 February 2026). Systems that store category names break when that happens. This project gives every category a stable ID, records what each category was called and when, and maps the labels AMFI publishes to those IDs.

What is in the dataset

| File | Contents | |---|---| | data/categories.json | Broad and specific categories, with SEBI's characteristics and validity dates | | data/aliases.json | AMFI scheme-data labels (old and new formats) mapped to category IDs | | data/history.json | Renames, splits, replacements, new and discontinued categories, with effective dates | | data/circulars.json | The SEBI circulars the data is derived from | | data/glide-paths.json | Life Cycle Fund asset allocation by years to maturity | | data/rules.json | Cross-category rules (portfolio overlap limits, per-fund-house limits, exit loads) | | data/meta.json | Dataset version and the latest circular it reflects | | data/schema/ | JSON Schema for each file |

Principles

  • IDs never change or get reused. A rename changes a label, not an ID.
  • Every fact cites a circular.
  • JSON is the source of truth. The PHP and JS packages only read it.

Install

composer require ananto-in/mf-categories   # PHP >= 8.1
npm install @ananto-in/mf-categories       # Node >= 20.10

Releases follow Semantic Versioning; see the changelog.

API

The PHP and JS packages expose the same operations. Category is a typed, immutable object with camelCase properties (id, parent, level, name, shortName, group, status, validFrom, validTo, circular, schemeTypeDescription, description, characteristics, formerNames, note). Rules, history, glide paths, circulars and meta are returned as the plain objects found in the JSON files.

| Operation | Returns | |---|---| | all() | every category, including superseded and discontinued | | find(id) | a category or null | | children(id) | direct children | | active(on?) | categories in force on a date (today by default); validFrom <= on < validTo | | resolveLabel(label) | the category an AMFI label maps to; null if unknown or ambiguous | | candidatesForLabel(label) | every category a label can mean (several for an ambiguous label) | | successors(id) | categories that continue a split, merged or replaced category (a rename keeps its id) | | history(id?) | lifecycle events for a category, or all events | | rulesFor(id) | rules on the category or any of its parents | | glidePath(id) | Life Cycle glide path, or null | | circular(id) / meta() | source circular / dataset version |

Label matching ignores case and repeated or surrounding whitespace.

PHP

use Ananto\MfCategories\Categories;

$categories = new Categories();
$categories->resolveLabel('Income/Debt Oriented Schemes - Short Term Fund')?->id; // "debt.short_term"
$categories->find('debt.short_term')?->formerNames;                              // ["Short Duration Fund"]
$categories->active('2026-02-25');                                               // categories before the 2026 circular

JavaScript

ES modules, no dependencies, TypeScript types included. Needs Node 20.10+ (JSON import attributes) or a bundler that supports them (Vite, webpack 5, esbuild, Rollup).

import categories, { resolveLabel, active } from '@ananto-in/mf-categories';

resolveLabel('Income/Debt Oriented Schemes - Short Term Fund')?.id; // "debt.short_term"
categories.find('debt.short_term')?.formerNames;                    // ["Short Duration Fund"]
active('2026-02-25');                                               // categories before the 2026 circular

Every operation is available as a named export and on the default export. Dates can be a Date (its local calendar day) or a YYYY-MM-DD string; anything else throws a RangeError (the PHP package throws InvalidArgumentException). createCategories(dataset) builds the same API over your own copy of the data.

The JS package parses all data files when imported and adds about 121 KB (14 KB gzipped) to a bundle. For a front end that needs only a label or two, fetch the JSON files you need from the package's data/ directory instead.

Both packages are tested against the same cases in tests/contract/api-contract.json, so they behave identically.

PHP: performance

Each data file is read on first use and cached for the rest of the process: the first label lookup costs about a millisecond, later lookups under a microsecond, and about 1.5 MB of memory. Create one Categories per process (or register it as a shared service); instances share the parsed data.

Development

npm install
npm run validate   # schema and integrity checks on data/
npm run lint:words # wording rules for README and data
npm test           # JS and dataset tests

composer install
composer test      # PHPUnit
composer cs        # PSR-12

Disclaimer

This is an unofficial community reference compiled from publicly available SEBI circulars and AMFI data. It is not an official SEBI or AMFI resource and is not investment advice. The data may contain errors or lag behind the latest circulars: always check the source circular before relying on it. Provided "as is", without warranty of any kind.

License

  • Code: MIT
  • Data (data/): CC0 1.0. Credit to ananto.in is appreciated but not required.