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

@mowogames/mdf

v1.0.2

Published

MDF (Mowo Data Format) — a typed, human-readable serialization format for game engines

Readme

@mowogames/mdf


A typed, human-readable data format designed for game engines. First-class support for vec3(), quat(), rgb(), hex(), uuid(), asset references, and bare enums.

This is the official JavaScript/TypeScript implementation of MDF.

Install

npm install @mowogames/mdf

Quick Start

Parse

import { parse } from "@mowogames/mdf";

const doc = parse(`
  Scene "Forest" {
    version: 2
    gravity: vec3(0, -9.81, 0)

    GameObject "Player" {
      active: true
      mesh: @"Assets/Models/Character.fbx"

      Transform {
        position: vec3(0, 1, 0)
        rotation: quat(0, 0.707, 0, 0.707)
      }

      RigidBody {
        type: Dynamic
        mass: 75.0
      }
    }
  }
`);

const root = doc.root();
console.log(root.type);  // "Scene"
console.log(root.name);  // "Forest"

const gravity = root.getVec3("gravity");
console.log(gravity);  // { x: 0, y: -9.81, z: 0 }

const player = root.findChild("GameObject", "Player");
console.log(player.getBool("active"));     // true
console.log(player.getString("mesh"));     // "Assets/Models/Character.fbx"

const pos = player.findChild("Transform").getVec3("position");
console.log(pos);  // { x: 0, y: 1, z: 0 }

Build & Serialize

import {
  MdfDocument, MdfInt, MdfBool, MdfString, MdfVec3Val,
  MdfEnum, MdfAssetRef, MdfUUID, stringify
} from "@mowogames/mdf";

const doc = new MdfDocument();
const scene = doc.createRoot("Scene", "MyLevel");
scene.set("version", MdfInt(1));
scene.set("gravity", MdfVec3Val(0, -9.81, 0));

const player = scene.addChild("GameObject", "Player");
player.set("active", MdfBool(true));
player.set("tag", MdfString("Player"));
player.set("id", MdfUUID("550e8400-e29b-41d4-a716-446655440000"));

const transform = player.addChild("Transform");
transform.set("position", MdfVec3Val(0, 1, 0));

const body = player.addChild("RigidBody");
body.set("type", MdfEnum("Dynamic"));

console.log(stringify(doc));

Output:

Scene "MyLevel" {
    version: 1
    gravity: vec3(0.0, -9.81, 0.0)

    GameObject "Player" {
        active: true
        tag: "Player"
        id: uuid("550e8400-e29b-41d4-a716-446655440000")

        Transform {
            position: vec3(0.0, 1.0, 0.0)
        }

        RigidBody {
            type: Dynamic
        }
    }
}

Value Types

| Type | MDF Syntax | Constructor | |------|-----------|-------------| | Null | null | MdfNull() | | Bool | true / false | MdfBool(true) | | Int | 42 | MdfInt(42) | | Float | 3.14 | MdfFloat(3.14) | | String | "hello" | MdfString("hello") | | Vec2 | vec2(1, 2) | MdfVec2Val(1, 2) | | Vec3 | vec3(1, 2, 3) | MdfVec3Val(1, 2, 3) | | Vec4 | vec4(1, 2, 3, 4) | MdfVec4Val(1, 2, 3, 4) | | Quat | quat(0, 0, 0, 1) | MdfQuatVal(0, 0, 0, 1) | | Color | rgb(0.5, 0.2, 0.1) | Parsed as Vec4 with alpha 1.0 | | Hex | hex(#FF6600) | Parsed as normalized Vec4 | | UUID | uuid("...") | MdfUUID("...") | | Asset Ref | @"path" | MdfAssetRef("path") | | Enum | Dynamic | MdfEnum("Dynamic") | | Array | [1, 2, 3] | MdfArray([...]) |

API

parse(source: string): MdfDocument

Parse MDF text. Throws on syntax errors.

stringify(doc: MdfDocument, indent?: number): string

Serialize a document to MDF text format.

MdfDocument

doc.createRoot(type, name?)  // Create root node
doc.root()                   // Get first root (throws if empty)
doc.roots                    // All root nodes

MdfNode

node.type                    // Node type identifier
node.name                    // Optional name
node.set(key, value)         // Set property (chainable)
node.get(key)                // Get raw MdfValue
node.has(key)                // Check if property exists
node.properties              // Map<string, MdfValue>

// Typed getters (throw on type mismatch)
node.getBool(key)            // boolean
node.getInt(key)             // number (truncated)
node.getFloat(key)           // number
node.getString(key)          // string (works for String, UUID, AssetRef, Enum)
node.getVec2(key)            // { x, y }
node.getVec3(key)            // { x, y, z }
node.getVec4(key)            // { x, y, z, w }
node.getArray(key)           // MdfValue[]

// Children
node.addChild(type, name?)   // Add child node
node.findChild(type, name?)  // Find first child by type
node.findChildren(type)      // Find all children by type
node.children                // All children

Format Features

  • // line comments and /* */ block comments
  • Trailing commas in arrays
  • Scientific notation (1e-6)
  • Escape sequences in strings (\n, \t, \\, \")
  • Multiple root nodes per document
  • Heterogeneous arrays

Compatibility

Fully compatible with the C++ MDF library. Files written by either implementation can be read by the other.

License

MIT