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

nodext

v0.2.0

Published

Plugin-driven Node.js applications

Downloads

83

Readme

NodeXT - Plugin-driven Node.js applications

NodeXT is a way to organize your Node.js web application so that it is driven by a collection of extensions. This makes the application easier to manage, as distinct collections of functionality can be isolated in their own extensions that can be enabled and disabled as needed.

Each extension runs within a URL prefix provided by configuration.

Structure of an extension

At minimum, an extension provides a main file that exports method extension. This method returns a constructor function to the extension object.

The NodeXT extension loader calls this method for each enabled extension, and then instantiates the extension objects through the constructor functions.

These constructor functions get a configuration object that may contain extension-specific configurations.

The extension might look like the following (in CoffeeScript):

# Get the extension base class
nodext = require 'nodext'

class MyExtension extends nodext.Extension
  name: "MyExtension":
  config: {}

exports.extension = MyExtension

There are several methods that the extensions may implement to provide actual behavior:

  • configure(server): run in the configuration phase of Express. An extension could add its own middlewares to server configuration here, for example to provide static servers or authentication
  • getModels(schema, otherModels): run whenever JugglingDB is used. Here the extension can provide its own JugglingDB models if necessary
  • registerRoutes(server) run after server has been configured. Here the extension can register its own Express routes

The extension configuration contains a key urlPrefix that tells the URL prefix the extension should run under. A well-behaved component should only register middleware or routes to work under the prefix to ensure it doesn't step on the toes of other loaded extensions.

For example:

class MyExtension extends nodext.Extension
  name: "MyExtension":
  config: {}

  configure: (server) ->
    # Function to check authentication against the username
    # and password provided in extension configuration
    checkAuth = (username, password) ->
      if username is @config.username and password is @config.password
        return true
      false

    # Use HTTP Basic authentication under the URL space handled
    # by this extension
    server.use @config.urlPrefix, express.BasicAuth checkAuth

  registerRoutes: (server) ->
    # Register a route under the URL space handled by this
    # extension
    server.get "#{@config.urlPrefix}hello/:user", (req, res) ->
      res.send "Hello #{req.params.user}"

Such extension, stored in extension/my/main.coffee could be enabled by:

{
  "server: {
    "hostname": "127.0.0.1",
    "port": 8001
  },
  "extensions: {
    "/foo/": {
      "name": "my"
      "configuration": {
        "username": "user",
        "password: "pass"
      }
    }
  }
}

Now, run this with NodeXT:

$ nodext my_config_file.json

...and the extension's route should answer in http://127.0.0.1/foo/hello/World. Use user / pass to log in.