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

@oddcommon/bolt

v0.0.6

Published

Make your websites faster! ⚡️

Readme

⚡️🤖 Bolt

A light weight library ( 3k gzipped ) that gives you the speed and control of an SPA while keeping your site static through progressive enhancement and modern techniques.

Demo: https://bolt.oddcommon.dev

The primary goal of Bolt is to speed up page load times and give users the feel of an SPA while remaining static HTML. It's not quite a router and not quite a transition library, it's main objective is speed and progressive enhancement, it's up to you to decide how to implement.

You can use Bolt in a few different ways, out of the box it will improve load times with a few modifications to your code.

Heavily inspired by Quicklink, Turbo & Highway the goal of Bolt is to be an easy to integrate script that gives speed + flexibility to build around.

📦 Setup

To Install: npm i @oddcommon/bolt

Bolt is a long lived script and needs to run on each page and between renders. If you initialize Bolt from a script that script will be considered protected, that means it will never be disposed of.

ex: App.js

import Router from "@oddcommon/bolt";

class App {
  constructor(){
    this.BoltRouter = new Router();

    this.observe();
  }

  observe(){
    this.BoltRouter.on('navigate-before', () => { .... })
  }
}
new App();

Dev

  • npm run dev
  • http://localhost:8000/examples

Basics

Wrapper

In order for Bolt to know where updates need to be rendered you need to specify a dom element to use. This is done by adding data-bolt to any top level DOM element that will be changing from page to page. Typically this would be your main content.

Anything outside of data-bolt will be left intact between page renders. You can have multiple wrappers by specifying an ID

example:

<div data-bolt="some-id">...</div>

Link

To get Bolt running on your links just add data-bolt-link as an attribute to any links. Bolt will handle the rest.

You can optionally set data-bolt-link="static" and bolt will retain the current scroll position on the page between renders. This is helpful if you're paginating content and don't want to reset the user on every click. The default behavior is to scroll the user to the top of the page on every render.

Static

Adding data-bolt-static='static-id' to an element will freeze that element and Bolt will not touch it between renders. These elements will never be removed or changed, you can treat them as independent sandboxes for long lived content.

✨ Super charge Bolt

Bolt has a predefined lifecycle and emits events throughout this lifecycle. you can tap into any of them at any time.

🎟 Events

  • prefetch-before
  • prefetch-complete
  • navigate-before
    • params: {to: string, from: string}
  • navigate-complete
    • params: {to: string, from: string}
  • loading
  • load-event
    • params: {total: integer, complete: integer}
  • load-complete
  • render-before
  • render-complete
  • bolt-complete

Merge Elements

Bolt has a concept of merging static elements that are outside the main data-bolt wrapper. By adding data-bolt-merge to an element bolt will merge attributes of those elements. This is handy if you have different classes or require a specific layout between pages on elements that are static.

example:

<div data-bolt-merge="div-id">...</div>

Prefetch

If you want to really go after speed and have specific assets that you want to preload before a navigation event even happens you can use data-bolt-prefetch. This will add preload tags and the browser will begin preloading those assets in the background.

🚨 - This is very agressive and must be used with caution, but it can result in dramatically faster pages loads.

API

Bolt has a very simple API that allows you the ability to control lifecycle steps.

  • BoltRouter.pause() - Pauses execution before the next step in lifecycle
  • BoltRouter.resume() - Resumes execution
  • BoltRouter.initialize() - Refreshes bindings
  • BoltRouter.disable() - Disable Bolt

🚨 Danger Zone Be Very careful with these

  • BoltRouter.lock() - Override the lock that Bolt creates during routing ( similar to pause but blocks any new routing from happening )
  • BoltRouter.unlock() - Unlock the override

Transitions

When you initialize Bolt you can supply a transitions object where you can define transition functions and then specify them using data-bolt-transition="transitionName" Your transition function will be called on navigate-before - it us up to you to hook into the Bolt lifecycle. In the below example we are simply adding an await to delay, it's up to you to decide what happens and when to resume Bolt lifecycle. You can also hook into any step of the lifecycle for your transition.

Example:

import Router from '@oddcommon/bolt';

class App {
  constructor() {
    const exampleTransition = this.exampleTransition;

    this.BoltRouter = new Router({
      transitions: [
        {
          name: 'exampleTransition',
          transition: exampleTransition,
        },
      ],
    });
  }

  // Bolt provides the to and from in the callback
  async exampleTransition({ to, from }) {
    // Pause Bolt lifecycle
    this.BoltRouter.pause();

    // ... Fancy transition animation and logic
    await setTimeout(() => {
      new Promise(resolve => resolve());
    }, 500);

    // Resume Bolt Lifecycle
    this.BoltRouter.resume();
  }
}
new App();

Register Transitions

You can register new transitions at any time by calling BoltRouter.registerTransition({ ...transition-object });

Transition Object Options

If you want to specify specific transitions based on pages you can define to and from in your transition object, Bolt will call the transiton whenever it's navigating to and from those specific pages.

const transitionObject = {
  name: 'homeToAbout',
  to: '/about/',
  from: '/home/',
  transition: exampleTransition,
};

You can also use regex to apply transitions to groups of pages.

BoltRouter = new Router({
  transitions: [
    {
      name: 'exampleTransition',
      from: /features/,
      to: /link-example/,
      transition: exampleTransition,
    },
  ],
});

Examples

You can see a demo of Bolt in example. Just run npm run dev from the root of the Bolt project and the demo will start up.