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

tacklet

v0.3.0

Published

The official SDK for building custom Tacklets for the [Tackpad](https://tackpad.xyz) free-form canvas. The SDK allows developers to create Tacklets that seamlessly integrate with Tackpad.

Downloads

111

Readme

Tacklet SDK

The official SDK for building custom Tacklets for the Tackpad free-form canvas. The SDK allows developers to create Tacklets that seamlessly integrate with Tackpad.

📦 Installation

npm install tacklet

Or with Yarn:

yarn add tacklet

⚡ Quick Start

Your Tacklet will be loaded in an iframe by the Tackpad application. The SDK handles communication between your Tacklet and the parent Tackpad canvas.

Here's a simple example:

import tacklet from 'tacklet';

// Connect to the Tackpad platform
async function initialize() {
  try {
    await tacklet.connect();
    console.log('Connected to Tackpad!');
    document.getElementById('tacklet-status').textContent = 'Connected';

    // Apply theme
    const theme = tacklet.getTheme();
    document.body.classList.add(`theme-${theme}`);

    // Listen for selection events
    tacklet.on('selected', () => {
      console.log('Tacklet selected!');
      document.body.classList.add('tacklet-selected');
    });

    tacklet.on('deselected', () => {
      console.log('Tacklet deselected!');
      document.body.classList.remove('tacklet-selected');
    });
  } catch (err) {
    console.error('Failed to connect to Tackpad:', err);
  }
}

initialize();

🔄 Tacklet Lifecycle

  1. Tacklet is loaded in an iframe by Tackpad.
  2. Call tacklet.connect() to initialize communication.
  3. Use the SDK's methods to interact with Tackpad.
  4. Save Tacklet state using setData() and retrieve it with getData().
  5. Call destroy() when your Tacklet is unmounted.

📊 Data Persistence

The SDK provides methods to save and retrieve Tacklet-specific data:

// Save Tacklet data
async function saveCounter() {
  const currentCount = parseInt(document.getElementById('counter').textContent, 10);
  await tacklet.setData({ count: currentCount });
  console.log('Counter saved!');
}

// Load Tacklet data
async function loadCounter() {
  try {
    const data = await tacklet.getData();
    if (data?.count !== undefined) {
      document.getElementById('counter').textContent = data.count;
    }
  } catch (err) {
    console.error('Failed to load counter:', err);
  }
}

🎨 Theming

Ensure theme consistency with the Tackpad environment:

async function applyTheme() {
  await tacklet.connect();
  const theme = tacklet.getTheme(); // 'light' or 'dark'
  document.body.classList.add(`theme-${theme}`);
}

applyTheme();

📏 Dimensions and Layout

Get Tacklet dimensions and listen for size changes:

const { width, height } = tacklet.getDimensions();
console.log(`Tacklet dimensions: ${width}x${height}`);

tacklet.on('resized', ({ width, height }) => {
  console.log(`Tacklet resized to: ${width}x${height}`);
  updateLayout(width, height);
});

📖 API Reference

The Tacklet SDK is a singleton and should not be instantiated manually.

Methods

| Method | Description | |--------|-------------| | connect() | Connects to the Tackpad platform. Must be called before using other methods. | | setData(data) | Saves widget data. | | getData() | Retrieves widget data. | | on(eventType, handler) | Registers an event listener. | | off(eventType, handler) | Removes an event listener. | | getNodeId() | Returns the Tacklet's unique node ID. | | getTheme() | Returns the current theme (light or dark). | | getDimensions() | Returns the Tacklet's dimensions. | | getIsSelected() | Returns whether the Tacklet is currently selected. | | destroy() | Cleans up the SDK connection. Call when Tacklet is unmounted. | | setDebug(state) | Enables debug logging. Example: tacklet.setDebug(true); |

Events

| Event | Description | |-------|-------------| | ready | Fired when the SDK is connected and ready. | | selected | Fired when the Tacklet is selected. | | deselected | Fired when the Tacklet is deselected. | | resized | Fired when the Tacklet is resized. | | moved | Fired when the Tacklet is moved. | | data | Fired when Tacklet data is saved. |

📱 Framework Integration Examples

The SDK can be used in different frameworks:

React Integration

import React, { useState, useEffect } from 'react';
import tacklet from 'tacklet';

function CounterWidget() {
  const [count, setCount] = useState(0);
  const [isSelected, setIsSelected] = useState(false);
  const [theme, setTheme] = useState('light');

  useEffect(() => {
    async function initialize() {
      try {
        await tacklet.connect();
        console.log('Connected to Tackpad!');
        setTheme(tacklet.getTheme());

        // Load saved data
        const data = await tacklet.getData();
        if (data?.count !== undefined) setCount(data.count);

        // Event listeners
        const handleSelected = () => setIsSelected(true);
        const handleDeselected = () => setIsSelected(false);

        tacklet.on('selected', handleSelected);
        tacklet.on('deselected', handleDeselected);

        return () => {
          tacklet.off('selected', handleSelected);
          tacklet.off('deselected', handleDeselected);
          tacklet.destroy();
        };
      } catch (err) {
        console.error('Failed to connect to Tackpad:', err);
      }
    }

    initialize();
  }, []);

  useEffect(() => {
    tacklet.setData({ count }).catch(err => console.error('Failed to save data:', err));
  }, [count]);

  return (
    <div className={`widget ${theme} ${isSelected ? 'selected' : ''}`}>
      <div>{count}</div>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  );
}

export default CounterWidget;

🧩 Development

To build your own Tacklet:

  1. Create your Tacklet using any framework or vanilla JavaScript.
  2. Use the Tacklet SDK to communicate with Tackpad.
  3. Host your Tacklet on a web server.
  4. Register your Tacklet with Tackpad to make it available to users.

For detailed development instructions, see the Developer Guide.

📄 License

This SDK is licensed under the MIT License - see the LICENSE file for details.