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

folie-grid

v0.2.2

Published

Lightweight column grid overlay for the browser. Same columns, gutter, and margin as your Figma layout grid. Toggle it while you build.

Readme

folie

Folie

Live demo →

Lightweight column grid overlay for the browser. Same columns, gutter, and margin as your Figma layout grid. Toggle it while you build.

How it works

Figma's Layout Grid panel defines a grid with columns, gutter, and margin — folie uses those exact values. It mounts a fixed, semi-transparent CSS Grid overlay on top of your page, updated on resize for each breakpoint. Toggle it with Ctrl+G or an optional button.

Install

npm install folie-grid
# or
yarn add folie-grid

Usage

Minimal — built-in defaults

import Folie from "folie-grid";

new Folie().mount();

Top-level shorthand

Pass columns, gutter, and margin directly — applies at all viewport widths.

// mirror the Figma layout grid
new Folie({
  columns: 12,
  gutter: "10px",
  margin: "20px",
}).mount();

Per-breakpoint config

Use numeric min-width keys. Top-level columns/gutter/margin becomes the base (0px+) config and can be combined with breakpoints. All fields are optional — unspecified fields inherit from the base.

new Folie({
  columns: 6, gutter: "10px", margin: "20px", // base: 0px+
  breakpoints: {
    768:  {columns: 8}, // gutter/margin inherited
    1024: {columns: 12, gutter: "20px", margin: "20px"},
  },
}).mount();

If breakpoints is provided without shorthand, DEFAULTS (columns: 12, gutter: 20px, margin: 20px) are used as the base config.

Row overlay

Add a horizontal row overlay alongside the column grid:

new Folie({
  columns: 12, gutter: "20px", margin: "20px",
  rows: 8, rowsGutter: "20px", rowsMargin: "20px",
  rowsColor: "#0000ff", rowsOpacity: 0.05,
}).mount();

Row count can also be overridden per breakpoint:

new Folie({
  columns: 6, gutter: "20px", margin: "20px",
  rows: 6, rowsGutter: "20px", rowsMargin: "20px",
  breakpoints: {
    1024: {columns: 12, rows: 10},
  },
}).mount();

Options

| Option | Type | Default | Description | | -------------- | --------- | ------------ | --------------------------------------------------------------------------------- | | columns | number | 12 | Column count at 0px+ (base). Acts as the catch-all when no breakpoints are set. | | gutter | Spacer | 20px | Gutter at 0px+ (base). | | margin | Spacer | 20px | Margin at 0px+ (base). | | breakpoints | object | — | Per-breakpoint config keyed by numeric min-width (px). Can be combined with shorthand. | | showOnStart | boolean | true | Whether the grid is visible immediately on mount() | | toggleButton | boolean | false | When true, mounts a 40×40 button fixed to the bottom-left that toggles the grid | | rows | number | — | Number of rows. If omitted, no row overlay is rendered. | | rowsGutter | Spacer | — | Vertical gap between rows. | | rowsMargin | Spacer | — | Top/bottom padding of the row overlay. | | rowsColor | Color | #ff0000 | Row background color (global, not per-breakpoint) | | rowsOpacity | number | 0.1 | Row opacity (global, not per-breakpoint) | | color | Color | #ff0000 | Column background color | | opacity | number | 0.1 | Column opacity | | zIndex | number | 2147483647 | z-index of the overlay | | shortcut | string | ctrl+g | Keyboard shortcut to toggle visibility | | mode | 'fill' \| 'outline' | 'fill' | 'outline' renders columns as inset box-shadow borders instead of filled rectangles. When mode is 'outline' and opacity is not set, opacity defaults to 0.5 |

Spacer

Any CSS length value, a CSS custom property, or a var() reference:

20px · 1.5rem · 2vw · clamp(10px, 2vw, 24px) · var(--my-gutter) · --my-token

Color

Any CSS color value accepted by background / box-shadow:

#ff0000 · rgb(255,0,0) · rgba(255,0,0,0.5) · hsl(0,100%,50%) · transparent · currentColor · var(--brand)

Breakpoint config

Keys are numeric min-widths in px. Ranges are inferred from adjacent keys. columns, gutter, and margin match the Layout Grid fields in Figma's design panel.

| Key | Type | Required | Description | | ------------- | -------- | -------- | ----------------------------------------------------------------------- | | columns | number | no | Number of columns — inherits from base if omitted | | gutter | Spacer | no | Gap between columns — inherits from base if omitted | | margin | Spacer | no | Left/right padding — inherits from base if omitted | | rows | number | no | Number of rows — inherits from base if omitted | | rowsGutter | Spacer | no | Vertical gap between rows — inherits from base if omitted | | rowsMargin | Spacer | no | Top/bottom padding of the row overlay — inherits from base if omitted |

Default base config

When no shorthand is provided, the following is used as the base (0px+):

| columns | gutter | margin | | ------- | ------ | ------ | | 12 | 20px | 20px |

CSS custom properties

The overlay is driven by CSS custom properties set on .fl-wrapper. You can override them in your own CSS if needed.

| Property | Description | | ------------------- | ------------------------ | | --fl-columns | Number of columns | | --fl-gutter | Gap between columns | | --fl-margin | Left/right padding | | --fl-color | Column color | | --fl-opacity | Column opacity | | --fl-rows | Number of rows | | --fl-rows-gutter | Vertical gap between rows | | --fl-rows-margin | Top/bottom padding | | --fl-rows-color | Row color | | --fl-rows-opacity | Row opacity |

API

| Method | Description | | ------------------- | ------------------------------------------------------ | | mount(container?) | Attach overlay to container (default: document.body) | | destroy() | Remove overlay, toggle button, and all listeners |

Keyboard shortcut

Default: Ctrl+G. Toggle visibility. Customise via the shortcut option:

new Folie({shortcut: "ctrl+shift+g"});

TypeScript

The package ships type declarations — no @types/ package needed.

The import works exactly like JavaScript:

import Folie from "folie-grid";

const grid = new Folie({
  columns: 12,
  gutter: "20px",
  margin: "clamp(16px, 5vw, 80px)",
}).mount();

If you want to define the config object separately, you can import the FolieOptions type:

import Folie, { type FolieOptions } from "folie-grid";

const config: FolieOptions = {
  columns: 12,
  gutter: "20px",
  margin: "20px",
  breakpoints: {
    768:  { columns: 8 },
    1280: { columns: 12, gutter: "30px" },
  },
};

new Folie(config).mount();

HMR teardown (Vite / Nuxt / SvelteKit)

Call destroy() on hot reload to prevent the overlay from duplicating:

const grid = new Folie({ columns: 12 }).mount();

if (import.meta.hot) {
  import.meta.hot.dispose(() => grid.destroy());
}

License

MIT