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

rubik-main

v2.3.2

Published

Main Rubik for your app

Downloads

78

Readme

Rubik

Rubik is a powerful library, for build extensible applications from small kubiks.

Main concept

Rubik was born to create large applications that can be used not only independently, but also as a NodeJS module, in other applications. At the same time without hard work in development, extension and support.

Application in Rubik is a hub of Kubiks. Kubik is a small box with a small responsibility. You can unite and combime kubiks, for the fast bootstraping, without parts that you don't need.

Example of Kubiks:

  • Congfiguration
  • Logging
  • Mailing
  • Storaging
  • Transporting (HTTP, Websockets, etc)
  • ...name it yourself

Install

Using Yarn:

yarn add rubik-main

Using NPM:

npm install rubik-main

Create and use App

const Rubik = require('rubik-main');

const app = new Rubik.App();
app.add(new Rubik.Kubiks.Config());
app.add(new Rubik.Kubiks.Log());
// app.add(your kubiks) ...

Another way, add kubiks as an array:

app.add([
  new Rubik.Kubiks.Config(),
  new Rubik.Kubiks.Log()
]);

or as constructor's arguments:

const app = new Rubik.App([
  new Rubik.Kubiks.Config(),
  new Rubik.Kubiks.Log()
]);

Create your own Kubik

A new Kubik should be inherited from the Kubik class.

There is only one additional requirement for Kubik. It should implement up method.

const { Kubik } = require('rubik-main');

class MyKubik extends Kubik {
  async up() {
    // bootstrap your kubik
  }
}

We can add dependencies list to Kubik, and Rubik will check they existing.

class MyKubik extends Kubik {
  constructor() {
    super();
    this.dependencies = ['config', 'log'];
  }

  up({ config, log }) {
    // do something with config and log
  }
}

// Or you can use prototype, for creating list once.
// MyKubik.prototype.dependencies = Object.freeze(['config', 'log']);

Hooks

All Kubiks have a hook system. You can use it, if you want.

Method after

You can add async method after to your kubik, and after application will up all kubiks, it will call after methods if they exists.

Name of Kubik

Every Kubik's instance should contain name field. When you add your kubik to application, it get name, and use it. If your kubik doesn't contain name, kubik.constructor.name.toLowerCase() will be used.

Attach and extract an application from different objects

If you need an application attached to some object in your kubik, you can use the method app.attach(object) or static equivalent App.attach(app, object).

You can extract application from any object (if application was attached) by the static method App.extract(object).

For example simplest HTTP Kubik with express:

// Some middleware
const { App } = require('rubik-main');

const check = async (req, res, next) => {
  const app = App.extract(req);

  const { Users } = app.storage.models;

  try {
    const user = await Users.auth(req.body.login, req.body.password);
  } catch (err) {
    return next(err);
  }

  return next();
}

// ...
// ... preparing Kubik class
class HTTP extends Kubik {
  constructor() {
    this.expressApp = express();
  }

  up() {
    // Attach this.app to an req of express
    this.expressApp.use((req, res, next) => this.app.attach(req));
    // Another way this.expressApp.use((req, res, next) => App.attach(this.app, req));

    // add middleware which uses Rubik's application inside
    this.expressApp.use(check);

    this.expressApp.listen(80);
  }
}


// ...
// ... add Kubik's instance into the application
const app = new App();

app.add(new SomeStorageKubik());
app.add(new HTTP());

Bootstrap third-party modules

You could bootstrap thrird-party modules throught lifecicle hooks. The general method is .hook:

app.hook(hookName, hookCallback);

There are few hooks, which an app provides to you. All hooks are asyncronious. In this case, you could use async callbacks for it.

atStart

Runs in the top of app.up(). In this hook you could add new kubiks, because none of them has been processed.

app.hook('atStart', async () => {
  // your code here
});

before

Runs in the top of app.up(), but after the application calculated all the dependencies and prepared their kubiks for the up.

In this hook you shouldn't add new kubiks, because all of them has been prepared.

You could add some custom logic in this hook before the application upped.

app.hook('before', async () => {
  // your code here
});

after

This hook runs after all kubiks was upped, but before the application runs their after methods.

app.hook('after', async () => {
  // your code here
});

atEnd

This hook runs in the end of app.up().

You could bootstrap in this hook.

app.hook('atEnd', async () => {
  // your code here
});

beforeDown

This hook runs in the top of app.down()

You could run cleanup jobs here.

app.hook('beforeDown', async () => {
  // your code here
});

afterDown

This hook runs in the top of app.down()

You could run cleanup jobs here.

app.hook('afterDown', async () => {
  // your code here
});