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

@kendawson-online/vantl

v2.1.0

Published

A vanilla JavaScript library with zero dependencies that generates responsive timelines for both horizontal and vertical layouts

Readme

Vantl - Vanilla Timeline

Vantl is a lightweight, responsive timeline library created with vanilla Javascript for creating beautiful horizontal and vertical timelines with zero dependencies. Inspired by timeline originally created by squarechip in 2018. You can load your timeline data via a variety of methods and, you can include multiple timelines on a single page.

Features

  • Zero dependencies - Pure vanilla JavaScript (jQuery optional)
  • 📱 Fully responsive - Auto-switches between horizontal/vertical layouts
  • 🎨 Customizable colors - Theme nodes, lines, and navigation
  • 🖼️ Rich content - Support for images, HTML, and modal popups
  • 🔗 Deep linking - Link directly to specific timeline nodes via URL
  • 📦 Multiple layouts - Vertical scroll or horizontal carousel modes
  • 💾 Smart caching - LocalStorage caching for JSON data
  • 🚀 Auto-init - Just add a data attribute to load from JSON
  • 📏 Small footprint - Minified and tree-shakeable

Getting Started:

Load stylesheet and Javascript functions to your document via CDN links:

<!DOCTYPE html>
<html>
<head>
  <!-- load stylesheet -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.css">
</head>
<body>
   
  <!-- your timeline will go here --> 
  
  <!-- load functions -->
  <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.js"></script>
</body>
</html>

1️⃣ CREATE A TIMELINE USING BASIC HTML

Add some timeline node data in HTML. If you want your timeline to be oriented horizontally, set data-mode="horizontal" on the parent element (see code below). If you omit this setting, the timeline will be oriented vertically by default.

<!-- your timeline --> 
<div class="timeline" data-mode="horizontal">
  <div class="timeline__wrap">
    <div class="timeline__items">
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Jan. 1, 2000</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum.</p>
            </div>
        </div>
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Dec. 31, 2000</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum.</p>
            </div>
        </div>
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Jan. 1, 2001</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum.</p>
            </div>
        </div>
    </div>
  </div>
</div>

Add one line of code at the bottom to initialize your timeline. It goes after the CDN link but before the closing </body> tag and looks like this:

  <!-- load functions -->
  <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.js"></script>

  <!-- initialize the timeline -->
  <script>
    timeline(document.querySelectorAll('.timeline'));
  </script>

</body>
</html>

View A Basic HTML Example (With Source Code) 👀

Note: if you're using jQuery in your document, you can initialize your timeline like this:

    <!-- load functions -->
    <script src="https://cdn.jsdelivr.net/npm/@kendawson-online/vantl@latest/dist/timeline.min.js"></script>

    <!-- initialize timeline with jQuery -->
    <script>
        jQuery(function () {
            $('.timeline').timeline({
              mode: 'horizontal'
            });
        });
    </script>

  </body>
</html>

For more info check the Advanced Usage section below


2️⃣ USE DATA ATTRIBUTES TO CUSTOMIZE YOUR TIMELINE

You can add data attributes to the timeline element to control how it looks and/or functions. For example, this is how you would set the orientation of the timeline to be horizontal instead of vertical (default):

<div class="timeline" data-mode="horizontal">
  ...
</div>  

If you don't pass an attribute, the app will simply use the default values.

Here are the available data attributes:

| Option | Type | Default | Description | |--------|------|---------|-------------| | data-mode | string | 'vertical' | Layout mode: 'vertical' or 'horizontal' | | data-min-width | number | 600 | Minimum viewport width (px) to maintain horizontal mode | | data-max-width | number | 600 | Maximum viewport width (px) to maintain vertical mode | | data-move-items | number | 1 | Items to scroll per navigation click (horizontal) | | data-start-index | number | 0 | Initial item index (horizontal mode) | | data-horizontal-start-position | string | 'top' | First item alignment in horizontal layout: 'top' or 'bottom' | | data-vertical-start-position | string | 'left' | First item alignment in vertical layout: 'left' or 'right' | | data-same-side-nodes | string|boolean | false | If set, forces all nodes to the same side. Accepts 'top'/'bottom' (horizontal) or 'left'/'right' (vertical). Use data-same-side-nodes="true" to follow the orientation-specific start position (data-horizontal-start-position / data-vertical-start-position). | | data-vertical-trigger | string | '15%' | Scroll trigger distance: percentage or px (e.g., '20%' or '150px') | | data-rtl-mode | boolean | false | Right to left mode: true or false (only works in horizontal mode and overrides startIndex setting) | | data-node-color | string | — | Node circle color (hex/rgb/hsl) | | data-line-color | string | — | Timeline line color (hex/rgb/hsl) | | data-nav-color | string | — | Navigation button color (hex/rgb/hsl) | | data-json-config | string | — | path to a JSON data file (e.g., /path/to/valid/file.json)|

See the API Documentation for a more detailed description of all options.


3️⃣ USING A JSON FILE TO LOAD TIMELINE DATA

A great way to use vanilla timeline is to store and load your data from an external JSON file. JSON stands for: "JavaScript Object Notation".

It's a lightweight text format stored in a file with a .json extension. It's easy for humans to read and write and for machines to parse and use in apps. JSON is based on a web standard so you have to follow the rules to produce "well-formed JSON" that is formatted a specific way. A simple JSON file might look something like this:

{
  "timelineName": "Timeline Title",
  "layoutMode": "horizontal",
  "minWidth": 700,
  "maxWidth": "",
  "nodeColor": "",
  "lineColor": "",
  "navColor": ""  
}

To use JSON, you add a data attribute called data-json-config to your HTML to tell the app which JSON file you want to load:

<div class="timeline" data-json-config="/path/to/timeline.json"></div>

⚠️ Important: if you set a data-json-config value, the app will prioritize JSON file settings and ignore any other data attribute values being passed inlne via HTML.

If you load your timeline data using the JSON method, you don't have to add the extra line of code at the bottom of the page (used to initialize the timeline). When a JSON file is loaded, the app is initialized automatically.

Here are some examples of JSON files you can use as templates to build your own timelines:

🗓️ A NOTE ABOUT DATES IN JSON 🗓️

Dates stored in JSON data files (e.g. the lastupdated field) are stored in a special format called ISO 8601. The vanilla timeline app expects dates to be in this specific format.

There is a demo page which displays dates in this format for you. The page also teaches you how to generate ISO 8601 timestamps in the developer console of your own web browser. Open the demo/time.html file in a browser to see a current ISO 8601 timestamp. You can copy/paste this date string directly to your JSON timelines.


Deep Linking

Link to a specific timeline node using URL parameters:

https://example.com/page.html?timeline=myTimelineId&id=3


https://[domain name]/[page name]?timeline=[timeline ID]&id=[node id]
  1. Add an id attribute and value to your timeline container:
    <div id="myTimeline" class="timeline">
       ...
    </div>  
  1. Add a data-node-id to each node you want to link to
    <div class="timeline__items">
        <!-- node 1 -->
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Jan. 1, 2015</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore.</p>
            </div>
        </div>
        <!-- node 2 -->
        <div class="timeline__item">
            <div class="timeline__content">
                <h5>Dec. 31, 2016</h5>
                <p>Lorem ipsum dolor sit amet, qui minim labore.</p>
            </div>
        </div>
    </div>    

Deep linking works automatically with JSON-loaded timelines

Advanced Usage:

Installing with npm

npm install @kendawson-online/vantl

Importing timeline functions into your Javscript app:

import { timeline } from '@kendawson-online/vantl';
import '@kendawson-online/vantl/dist/timeline.min.css';

timeline(document.querySelectorAll('.timeline'), {
  mode: 'vertical',
  nodeColor: '#2d6cdf'
});

Setting options

// vanilla Javascript
timeline(document.querySelectorAll('.timeline'), {
  mode: 'horizontal'
});


// jQuery
$('.timeline').timeline({
  mode: 'vertical',
  verticalTrigger: '20%'
});

Available API Options

All options can be set via JavaScript API, data attributes, or with JSON config.

| Option | Type | Default | Description | |--------|------|---------|-------------| | mode | string | 'vertical' | Layout mode: 'vertical' or 'horizontal' | | minWidth | number | 600 | Min viewport width (px) to maintain horizontal mode | | maxWidth | number | 600 | Max viewport width (px) to maintain vertical mode | | moveItems | number | 1 | Items to scroll per navigation click (horizontal) | | startIndex | number | 0 | Initial item index (horizontal mode) | | horizontalStartPosition | string | 'top' | First item alignment: 'top' or 'bottom' | | verticalStartPosition | string | 'left' | First item alignment: 'left' or 'right' | | sameSideNodes | string|boolean | false | Force all nodes to the same side. Accepted literal values: 'top', 'bottom', 'left', 'right'. Use true to follow the orientation-specific start position (horizontalStartPosition / verticalStartPosition). | | verticalTrigger | string | '15%' | Scroll trigger distance: percentage or px (e.g., '20%' or '150px') | | rtlMode | boolean | false | Right-to-left mode (horizontal) | | nodeColor | string | — | Node circle color (hex/rgb/hsl) | | lineColor | string | — | Center line color (hex/rgb/hsl) | | navColor | string | — | Navigation button color (hex/rgb/hsl) |

Custom Image Path

Override the auto-detected image path:

<script>
  window.TimelineConfig = {
    basePath: '/custom/path/to/images'
  };
</script>
<script src="dist/timeline.min.js"></script>

Programmatic control

// Load from JSON programmatically
loadDataFromJson('/data/timeline.json', '#myTimeline');

// Clear cache
clearTimelineCache();                         // Clear all cached JSON timelines
clearTimelineCache('/data/my-timeline.json'); // Clear cache for specific JSON URL

// Navigate to node (horizontal mode)
navigateTimelineToNodeIndex(containerElement, 5);

// Open modal
openTimelineModal(itemElement);

// Close modal
closeTimelineModal();

More Information

Optional SwiperJS add-on (not bundled or supported)

  • SwiperJS is a third-party library; Vantl only ships an adapter. You must bring Swiper yourself and consult the Swiper docs for setup and features.
  • Resolution order when useSwiper is enabled: options.swiperCdn (ESM URL) → installed swiper package (dynamic import) → window.Swiper from a UMD CDN. If none are found, Vanilla Timeline falls back to its built-in carousel controls.
  • Enable with data-use-swiper="true" (or boolean true) in HTML or useSwiper: 'true' | 'auto' | true in JS. Pass Swiper options via swiperOptions.
  • Build warning about unresolved swiper is expected when you have not installed it; either ignore, mark it external (e.g., external: ['swiper']), or install Swiper to silence the warning.

UMD CDN example (provides window.Swiper):

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/swiper-bundle.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/swiper-bundle.min.js"></script>
<script src="dist/timeline.min.js"></script>
<script>
  timeline(document.querySelectorAll('.timeline'), { useSwiper: 'auto' });
  // Swiper-specific options: { swiperOptions: { loop: true } }
</script>

Browser Support

  • Chrome/Edge (2018+)
  • Firefox (2018+)
  • Safari (2018+)
  • Requires: ES6, IntersectionObserver, CSS Custom Properties

Contributing

See Development.md for build instructions and an architectural overview.

See API Documentation for details about how the API works.

You can report issues and open pull requests on GitHub:

  • https://github.com/kendawson-online/vantl/issues

  • https://github.com/kendawson-online/vantl/pulls

Links

NPM Package: @kendawson-online/vantl

Repository: github.com/kendawson-online/vantl

CDN: cdn.jsdelivr.net/npm/@kendawson-online/vantl

License

MIT License


Note (optional Swiper integration):

You may see a Rollup warning during npm run build similar to:

(!) Unresolved dependencies
swiper (imported by "src/adapters/swiper-adapter.js")

This is expected when Swiper is optional (not installed) because the adapter attempts to load Swiper at runtime via an ESM CDN, dynamic import, or window.Swiper (UMD). The build still completes; if you want Rollup to stop warning, add external: ['swiper'] to rollup.config.js, or install swiper locally to include it in the bundle.

Credits

Originally inspired by timeline by Mike Collins (2018).

Refactored and maintained by Ken Dawson (2026).