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

masonry-angular

v0.0.2

Published

Zero-dependency masonry layout for Angular. Signal-based, zoneless, SSR-safe.

Readme

masonry-angular

Cascading grid ("masonry") layout for Angular. Its own solver — no masonry-layout, no jQuery, no imagesLoaded, no runtime dependencies at all. 8.6 KB gzipped.

For photo galleries, and for dashboards of charts and KPI cards — anywhere a CSS Grid leaves empty space under the short items.

<masonry-grid columns="3" gutter="20">
  @for (photo of photos(); track photo.id) {
    <article masonryGridItem>…</article>
  }
</masonry-grid>

That is the whole setup. Add, remove and reorder items however you like — the grid watches sizes and the DOM and re-lays out on its own. There is no reloadItems() to remember.

  • Signal-based and zoneless, standalone directives, OnPush, layout loop outside change detection.
  • SSR-safe. The server renders a usable multi-column approximation; hydration swaps in real masonry with no layout shift.
  • Uses native CSS masonry where it exists. With native: true, browsers that ship display: grid-lanes lay the grid out themselves — no measuring, no observers, no JavaScript.
  • Fast. One shared ResizeObserver, one frame per burst of changes, transform-based positioning. The solver places 10,000 items in 0.16 ms.

Try it in StackBlitz — a running grid in your browser, no setup.

Install

npm install masonry-angular

Works on Angular 17.1 and every version since, including 22. Each of those majors is verified by building a real application against the published package — see Angular support.

Copy-paste starting point

A complete component that works on every supported version. If you only read one code block, read this one — the comments mark the three things people get wrong.

import { Component, signal } from '@angular/core';
import { NG_MASONRY_GRID } from 'masonry-angular';

@Component({
  selector: 'app-gallery',
  // Angular 17 and 18 only: add `standalone: true`. It is the default from 19 on.
  imports: [NG_MASONRY_GRID],
  template: `
    <!-- "as many ~260px columns as fit" — no breakpoints to maintain -->
    <masonry-grid columnWidth="260" gutter="16">
      @for (photo of photos(); track photo.id) {
        <!-- widen an item with masonryColSpan, never with CSS width -->
        <article masonryGridItem [masonryColSpan]="photo.featured ? 2 : 1">
          <!-- width/height let the browser reserve space, so the grid never jumps -->
          <img [src]="photo.url" [alt]="photo.title" [width]="photo.width" [height]="photo.height" />
        </article>
      }
    </masonry-grid>
  `,
  styles: `
    /* The grid sets item width itself — never set a width on an item. */
    article[masonryGridItem] img { width: 100%; display: block; }
  `,
})
export class Gallery {
  readonly photos = signal([
    { id: 1, url: '/a.jpg', title: 'A', width: 400, height: 300, featured: false },
  ]);
}

Add, remove or reorder photos and the grid follows. There is no reloadItems() and nothing to call after a change.

Configure it

Five inputs cover almost everything, and they work as plain attributes:

<masonry-grid columnWidth="260" gutter="20">                 <!-- as many 260px columns as fit -->
<masonry-grid columns="3" gutter="20">                       <!-- a fixed count -->
<masonry-grid [columns]="{ '0': 1, '768': 2, '1200': 4 }">   <!-- counts by breakpoint -->

columns, columnWidth, gutter, gutterX, gutterY. Everything else — animations, RTL, SSR, stamps, native — lives on [options], and the two layer:

<masonry-grid columns="4" [options]="{ native: true, entryAnimation: false }">…</masonry-grid>

Two rules worth knowing: do not set a width on your items (the grid owns it), and widen an item with [masonryColSpan]="2", not CSS.

The four directives

| | | | --- | --- | | <masonry-grid> | The container. | | [masonryGridItem] | An item. [masonryColSpan] widens it; [masonryIgnore] drops it out. | | [masonryGridStamp] | A region items flow around instead of overlapping. | | [masonryGridSizer] | An element whose CSS width becomes the column width. |

Angular support

| Angular | Status | | ------- | ------ | | 17.1 – 22 | Supported, and each major is verified by building a real app against the published package. | | Below 17.1 | Not supported. The library uses input() with a transform, which the Angular linker only understands from 17.1. |

There is nothing to configure — one build of the package serves every version. It ships in Angular's partial-compilation format, so your own build finishes compiling it, which is why a single artifact works across six majors.

On Angular 17 and 18, add standalone: true to any component that imports the directives. Standalone became the default in Angular 19; before that, imports: on its own is a compile error (TS-992010). Nothing else differs between versions.

Where to go next

| | | | --- | --- | | Getting started | A tutorial: from install to a responsive gallery with SSR. | | Full reference | Every option, spans, stamps, testing, and migrating from ngx-masonry. | | Changelog | What changed in each release. | | Architecture | How it works inside. | | Contributing | Setting up, and where each file lives. |

Help shape it

This is version 0.0.2 — early enough that your opinion still changes the API.

Something broke, or felt harder than it should? Open an issue. "I expected X and got Y" is a complete bug report — you do not have to diagnose it. This is the single most useful thing anyone can do for the project right now, and it is worth more to me than any other kind of support.

Does it work well for you? A star on GitHub is how other people find this. Search and recommendations both weigh it, so it genuinely decides whether the next person with the same layout problem ever sees it.

Also wanted, and none of it requires touching the library: Safari and Firefox reports, mobile and RTL testing, a screen-reader audit, translations of the getting-started guide, and demo examples covering what the current five do not.

New to open source? This is a reasonable place to start, and saying so is welcome. See CONTRIBUTING.md.

License

MIT