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

social-masonry

v1.1.0

Published

Beautiful masonry layout for X (Twitter) and Instagram embeds with virtualization support

Readme

npm version bundle size license TypeScript


Features

  • Official Widgets - Uses Twitter's widgets.js and Instagram's embed.js for native embeds
  • Auto-sizing - Embeds automatically adjust to their content height
  • Responsive - Adaptive column layouts that look great on any screen size
  • Themeable - Light and dark theme support for Twitter embeds
  • TypeScript - Full type safety
  • React Ready - First-class React component with ref support
  • Lightweight - Minimal bundle size, widgets loaded on-demand

Installation

npm install social-masonry

Quick Start

React

import { SocialMasonry } from 'social-masonry/react';

function App() {
  const posts = [
    {
      id: '1',
      platform: 'twitter',
      url: 'https://twitter.com/username/status/1234567890',
    },
    {
      id: '2',
      platform: 'instagram',
      url: 'https://www.instagram.com/p/ABC123xyz/',
    },
  ];

  return (
    <SocialMasonry
      posts={posts}
      columns={[
        { columns: 4, minWidth: 1536 },
        { columns: 3, minWidth: 1024 },
        { columns: 2, minWidth: 640 },
        { columns: 1, minWidth: 0 },
      ]}
      gap={16}
      theme="light"
    />
  );
}

API

SocialMasonry Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | posts | SocialPost[] | [] | Array of posts to display | | columns | number \| ColumnConfig[] | 3 | Number of columns or responsive config | | gap | number | 16 | Gap between items in pixels | | theme | 'light' \| 'dark' | 'light' | Theme for Twitter embeds | | animate | boolean | true | Enable/disable layout animations | | animationDuration | number | 300 | Animation duration in milliseconds | | animationEasing | string | 'ease-out' | CSS easing function | | staggerDelay | number | 0 | Delay between each card animation (ms) | | className | string | - | Custom class for container | | style | CSSProperties | - | Custom styles for container | | onEmbedLoad | (post: SocialPost) => void | - | Called when an embed loads | | onEmbedError | (post: SocialPost, error: Error) => void | - | Called on embed error |

SocialPost Type

interface SocialPost {
  id?: string;                         // Optional unique identifier
  platform: 'twitter' | 'instagram';   // Social platform
  url: string;                         // Post URL
}

ColumnConfig Type

interface ColumnConfig {
  columns: number;   // Number of columns
  minWidth: number;  // Minimum container width for this config
}

Ref Methods

import { useRef } from 'react';
import { SocialMasonry, SocialMasonryRef } from 'social-masonry/react';

function App() {
  const masonryRef = useRef<SocialMasonryRef>(null);

  const handleAddPost = () => {
    masonryRef.current?.addPosts([newPost]);
  };

  return (
    <SocialMasonry
      ref={masonryRef}
      posts={posts}
    />
  );
}

Available ref methods:

| Method | Description | |--------|-------------| | addPosts(posts) | Add posts to the end | | setPosts(posts) | Replace all posts | | removePost(id) | Remove a post by ID | | refresh() | Re-process embeds |

Supported URL Formats

Twitter/X

  • https://twitter.com/username/status/1234567890
  • https://x.com/username/status/1234567890

Instagram

  • https://www.instagram.com/p/ABC123xyz/
  • https://www.instagram.com/reel/ABC123xyz/

Utilities

The library exports utility functions for URL parsing:

import {
  extractTweetId,
  extractInstagramId,
  detectPlatform,
} from 'social-masonry';

// Extract tweet ID from URL
extractTweetId('https://x.com/user/status/123456'); // '123456'

// Extract Instagram post ID
extractInstagramId('https://instagram.com/p/ABC123'); // 'ABC123'

// Detect platform from URL
detectPlatform('https://x.com/user/status/123'); // 'twitter'
detectPlatform('https://instagram.com/p/ABC'); // 'instagram'

Animation

Social Masonry uses FLIP (First, Last, Invert, Play) animation technique for smooth layout transitions when window resizes or column count changes.

Configuration

<SocialMasonry
  posts={posts}
  animate={true}           // Enable animations (default: true)
  animationDuration={300}  // Duration in ms (default: 300)
  animationEasing="ease-out"  // CSS easing (default: 'ease-out')
  staggerDelay={50}        // Delay between cards (default: 0)
/>

Accessibility

Animations automatically respect the user's prefers-reduced-motion system preference. When this setting is enabled, layout changes happen instantly without animation.

Disabling Animations

<SocialMasonry posts={posts} animate={false} />

How It Works

  1. Script Loading: Twitter's widgets.js and Instagram's embed.js are loaded on-demand when needed
  2. Widget Creation: Official APIs (twttr.widgets.createTweet and instgrm.Embeds.process) create native embeds
  3. Masonry Layout: Posts are distributed across columns using a simple round-robin algorithm
  4. Auto-sizing: Each embed automatically sizes to its content - no fixed heights
  5. FLIP Animation: Cards smoothly animate to new positions using GPU-accelerated CSS transforms

Browser Support

| Browser | Version | |---------|---------| | Chrome | 80+ | | Firefox | 75+ | | Safari | 14+ | | Edge | 80+ |

License

MIT