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

dynaloader

v1.1.0

Published

Generic asset loader for dynamically loading assets based on site-assets.json configuration

Readme

dynaloader

Generic asset loader for dynamically loading assets based on site-assets.json configuration. Provides dynamic content loading for static sites with CLI tools for asset management.

Installation

npm install dynaloader

Usage

As a Module

For projects using build tools (Vite, Webpack, Rollup, etc.), import directly:

import { loadSiteAssets, getContentData } from 'dynaloader';

// Load all assets and execute handlers
await loadSiteAssets('site-assets.json', () => {
  console.log('All assets loaded and handlers executed');
});

// Or get content data after loading
const { siteAssets, contentData } = await loadSiteAssets();
console.log(contentData);

CLI Tools

After installation, you can use the CLI tools:

Initialize

For static sites without build tools, initialize dynaloader in your project:

# If installed locally
npm run init

# Or directly with npx (requires package name to avoid npm init conflict)
npx -p dynaloader init

This command will:

  • Copy asset-loader.js to your current directory
  • Create a site-assets.json file if it doesn't exist

After initialization, import directly from the local file:

import { loadSiteAssets } from './asset-loader.js';

Add Asset

# Add existing file
npx add-asset path/to/file.json

# Create new file (will prompt for details)
npx add-asset content/new-section.json

The tool will:

  • Add entry to site-assets.json with validation rules
  • Create a dedicated handler file in handlers/ directory
  • Create starter content file if it doesn't exist

Generate Schema

# Generate schema from JSON file
npx generate-schema content/property.json

# Generate schema from directory (uses sample JSON file)
npx generate-schema gallery

API Reference

loadSiteAssets(assetsPathOrCallback, onComplete)

Loads site assets configuration, all content files, and executes handlers.

Parameters:

  • assetsPathOrCallback (string|Function): Path to site-assets.json file (default: 'site-assets.json') or callback function
  • onComplete (Function): Optional callback function called after all handlers have executed

Returns: Promise<Object> - Object containing siteAssets and contentData

Example:

// With path and callback
await loadSiteAssets('site-assets.json', () => {
  console.log('Done!');
});

// With callback only (uses default path)
await loadSiteAssets(() => {
  console.log('Done!');
});

// Get return value
const { siteAssets, contentData } = await loadSiteAssets();

loadHandlers(onComplete)

Load and execute handlers for assets. Usually called automatically by loadSiteAssets.

Parameters:

  • onComplete (Function): Optional callback function called after all handlers have executed

getContentData()

Get the loaded content data object.

Returns: Object - The contentData object mapping asset paths to their loaded content

Example:

await loadSiteAssets();
const contentData = getContentData();
console.log(contentData['content/property.json']);

Handler Structure

Each asset in site-assets.json can have a handler property pointing to a JavaScript file. The handler file should export a handle function:

export function handle(data, assetPath) {
  if (!data) return;
  
  // DOM manipulation logic here
  const element = document.querySelector('.my-section');
  if (element) {
    element.textContent = data.title;
  }
}

Site Assets Configuration

Create a site-assets.json file to define your assets:

{
  "version": "1.0",
  "description": "Configuration file defining manageable assets",
  "assets": [
    {
      "path": "content/property.json",
      "type": "json",
      "label": "Property Information",
      "description": "Property details",
      "handler": "handlers/property.js",
      "maxSize": 5120,
      "allowedExtensions": [".json"],
      "schema": {
        "type": "object",
        "properties": {
          "title": { "type": "string" }
        }
      }
    }
  ]
}

Asset Types

  • json: JSON files loaded and parsed
  • text: Text files (typically Markdown) loaded as strings
  • image: Image files (path stored, not loaded)
  • directory: Directory containing multiple assets

Combo Assets

Combo assets group multiple files with the same base name but different extensions:

{
  "type": "directory",
  "path": "gallery",
  "contains": {
    "type": "combo",
    "parts": [
      { 
        "assetType": "image", 
        "allowedExtensions": [".webp", ".jpg"],
        "maxSize": 2097152
      },
      { 
        "assetType": "json", 
        "allowedExtensions": [".json"],
        "maxSize": 5120
      }
    ]
  },
  "handler": "handlers/gallery.js"
}

Handler receives grouped data:

export function handle(comboData) {
  Object.keys(comboData).forEach(baseName => {
    const combo = comboData[baseName];
    const imagePath = combo['.webp'] || combo['.jpg'];
    const metadata = combo['.json'];
    // Use imagePath and metadata together
  });
}

License

MIT