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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@latinfor/raise

v0.0.2

Published

An unopinionated static site generator. Work in progress.

Downloads

3

Readme

Raise is in active development. Expect bugs, and expect the API to change. Avoid using in production settings right now unless you're willing to do debugging/patching.

Raise

Raise is an unopinionated static site generator and directory transformer.

Raise is optimized for flexibility, extensibility, and quick deployment. It has few dependencies and a small API, making it lightweight and easy to understand.

It also ships without many features that are commonly included in other site generators, including command-line access, automatic markdown/pandoc/whatever compilation, template support, or minification.

We consider this conservative approach to functionality to be a feature, for a couple of reasons:

  • Many if not all of these features are simple enough that an API around them wouldn't be any shorter or easier to use.
  • In our experience the requirements behind these features change from site to site, and there is no one-size-fits-all set of defaults.
  • Including a lot of features that are unnecessary for the majority of users overcomplicates codebases and makes them harder to understand.

So if Raise doesn't compile Markdown, then what does it do?

Raise takes a source directory (either on disk or as a "virtual" JSON filesystem), passes that directory through a set of transform functions that make it easy to read and recursively manipulate its contents, and then writes the result to an output directory.

The below example shows how you could compile a large quantity of blog posts written in Markdown into a Handlebars template.

let template = Handlebars.compile(siteTemplate);

await Raise({
  input: './source',
  output: './public',
  transform: {
    '**/*.md': async (file) => ({
      [`${file.name}.html`]: template({
        post: marked(await file.contents())
      })
    })
  }
});

You may have noticed above that Raise accepts globs. It tries as much as possible to use the same API as minimatch, so there should be minimal new APIs for you to learn.

Passing in a file that doesn't exist will allow you to create it. Raise uses the same minimatch API mentioned above to tell whether or not you're using a glob, and to allow you to create files when you're referring to a specific path.

await Raise({
  input: {}, /* here, no input is passed in. */
  output: './public',
  transform: {
    'new_file.txt': 'Arbitrary text contents'
  }
});

Raise's API is fully recursive, and allows you to return not just files, but also directories, Promises, other functions, and arrays of transformations to perform in series. This can take a little getting used to, but is extraordinarily powerful once you become comfortable.

In the below example, we aggregate data sources from multiple different websites at compile time. The data sources are fetched from several remote servers, and then the results are written into a "data" folder.

var dataSources = ['https://data-url', 'https://data-url-2']

await Raise({
  input: {},
  output: './public',
  transform: {
    'instructions.txt': 'See JSON files in the data directory'
    
    data: dataSources.map(
      source => (axios.get(source)
        .then(data => ({ 
          [`${source}.json`]: JSON.stringify(data)
        })
      )));
    }
  }
})

You may notice that the output of the above example doesn't really look like a website. Although Raise is optimized for static site generation, a generic and extensible API means it can be used for a lot of different purposes beyond just web development.

Of course, Raise handles some other common use-cases, such as:

  • Working with raw buffers or different encoding types
await Raise({
  input: './source',
  output: './public',
  transform: { 

      /* `null`: raw buffer */
      'binary.exe': async (file) => manipulate(await file.contents(null)),
    
      /* or a custom encoding type */
      'data.file': async (file) => manipulate(await file.contents('base64')),
    }
});
  • Outputing to a virtual FS instead of the file directory
var output = await Raise({
  input: './source',
  output: {},
  transform: { foo: { bar: 'car' } }
});

/* { foo: { bar: 'car' } } */
console.log(output);

And more!