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

@lukewarmraven/figma-scale

v0.2.0

Published

Figma px → responsive CSS calc utility. Maps design canvas dimensions to live viewport scale via CSS custom properties.

Readme

@lukewarmraven/figma-scale

Converts Figma design canvas px values into responsive CSS calc() strings that scale with the live viewport — so your designs stay proportional at any screen size without media query breakpoints.

Works in any JS/TS project: Next.js, React, Vue, Vite, vanilla JS, etc.


Recommended: fluid, zoom-friendly sizing with clamp()

For text and spacing that scale across screen sizes and respect browser zoom, pair rem() with CSS clamp(). rem() returns your Figma px value as a rem string, and you compose it inside clamp(min, preferred, max):

import { rem } from '@lukewarmraven/figma-scale'

// Flows between 16px and 32px, centered on the Figma value (24px).
// The rem terms keep it zoom-friendly; 0.5vw adds viewport responsiveness.
<h1 style={{ fontSize: `clamp(${rem(16)}, ${rem(24)} + 0.5vw, ${rem(32)})` }}>
  Hello
</h1>

Why rem + clamp instead of vw/vh? vw/vh lock to the viewport, so browser zoom won't rescale them (elements stay the same proportion of the screen). rem is relative to the root font-size, so zoom works — and clamp() gives smooth fluid scaling between bounds.


Examples: fonts, elements & spacing

Everything you pull from Figma is a px number. The three things you'll convert most are text, box sizes, and gaps — below each is shown in both rem (+ clamp) and vw/vh forms.

| When you need… | Use | |---|---| | Sizing that respects browser zoom & stays fluid | rem() + clamp() | | Proportions locked to the viewport (like the Figma canvas) | vw() / vh() |

Fonts

import { rem, vw } from '@lukewarmraven/figma-scale'

// rem + clamp — fluid between 16px and 32px, zoom-friendly
<h1 style={{ fontSize: `clamp(${rem(16)}, ${rem(24)} + 0.5vw, ${rem(32)})` }}>Title</h1>

// vw — locks to viewport width, keeps Figma proportions at any size
<p style={{ fontSize: vw(24) }}>Body</p>

Elements (width / height)

import { rem, vw, vh } from '@lukewarmraven/figma-scale'

// rem — stable, zoom-friendly box
<div style={{ width: rem(320), height: rem(200) }} />

// vw / vh — scales with the viewport, matching the Figma canvas
<div style={{ width: vw(320), height: vh(200) }} />

Spacing (padding / margin / gap)

import { rem, vw } from '@lukewarmraven/figma-scale'

// rem + clamp — fluid spacing that respects zoom
<section style={{ padding: `clamp(${rem(16)}, ${rem(32)} + 1vw, ${rem(64)})` }} />

// vw — viewport-locked spacing
<section style={{ padding: vw(32), gap: vw(24) }} />

Install

npm install @lukewarmraven/figma-scale

How it works

Call initFigmaScale() once at your app's entry point. It sets two CSS custom properties on :root:

  • --figma-scale-w = window.innerWidth / canvasW (updates on resize)
  • --figma-scale-h = window.innerHeight / canvasH (updates on resize)

Then vw(px) and vh(px) return calc() strings that multiply your Figma px value by those variables:

vw(200)  →  calc(200px * var(--figma-scale-w) * 0.6)

The element's rendered size scales proportionally with the viewport — matching your Figma design at the exact canvas dimensions, and shrinking/growing smoothly at any other size.

Zoom-friendly alternative: rem(px) converts a Figma px value to a rem string (relative to root font-size) instead of the viewport. It respects browser zoom — pair it with a clamp() in your project for fluid sizing that still responds to zoom.


Usage

Vanilla JS / any framework

Call initFigmaScale in your entry file, then use vw / vh anywhere:

// main.ts / index.ts
import { initFigmaScale } from '@lukewarmraven/figma-scale'

initFigmaScale({
  canvasW: 1728,   // your Figma canvas width
  canvasH: 1117,   // your Figma canvas height
  scale: 0.6,      // global multiplier — tune if elements look too big/small
})
// any component / module
import { vw, vh } from '@lukewarmraven/figma-scale'

element.style.width  = vw(200)   // "calc(200px * var(--figma-scale-w) * 0.6)"
element.style.height = vh(100)   // "calc(100px * var(--figma-scale-h) * 0.6)"
element.style.fontSize = vw(24)

React / Vite

// src/main.tsx
import { initFigmaScale } from '@lukewarmraven/figma-scale'

initFigmaScale({ canvasW: 1440, canvasH: 900, scale: 0.55 })
// src/components/Hero.tsx
import { vw, vh } from '@lukewarmraven/figma-scale'

export function Hero() {
  return (
    <div style={{ width: vw(800), height: vh(400) }}>
      <h1 style={{ fontSize: vw(64) }}>Hello</h1>
    </div>
  )
}

Next.js (App Router)

Next.js renders on the server, so the init script must run as an inline <script> before first paint. Use getScriptString() for this — it returns a self-contained IIFE with your config baked in.

// app/layout.tsx
import { getScriptString } from '@lukewarmraven/figma-scale'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <script
          dangerouslySetInnerHTML={{
            __html: getScriptString({ canvasW: 1728, canvasH: 1117, scale: 0.6 }),
          }}
        />
      </head>
      <body>{children}</body>
    </html>
  )
}
// anywhere in your components (client or server)
import { vw, vh } from '@lukewarmraven/figma-scale'

export function Card() {
  return (
    <div style={{ width: vw(320), height: vh(200), fontSize: vw(16) }}>
      ...
    </div>
  )
}

Note: initFigmaScale() is not needed in Next.js when you use getScriptString() in the layout — the inline script handles the runtime setup. Import vw / vh directly in your components.


Next.js (Pages Router)

// pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
import { getScriptString } from '@lukewarmraven/figma-scale'

export default function Document() {
  return (
    <Html>
      <Head>
        <script dangerouslySetInnerHTML={{ __html: getScriptString() }} />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Config options

All fields are optional. Defaults are shown.

| Option | Type | Default | Description | |---|---|---|---| | canvasW | number | 1728 | Width of your Figma design canvas in px | | canvasH | number | 1117 | Height of your Figma design canvas in px | | scale | number | 0.6 | Global multiplier on top of the viewport scale. Decrease if elements look too big, increase if too small | | fallbackW | number | 1280 / canvasW | Value for --figma-scale-w before the script runs (SSR / first paint). Auto-computed if not set | | fallbackH | number | 800 / canvasH | Value for --figma-scale-h before the script runs (SSR / first paint). Auto-computed if not set |


API

// Sets up CSS vars + resize listener. Call once at app entry.
// Not needed in Next.js if you use getScriptString() in the layout.
initFigmaScale(config?: FigmaScaleConfig): void

// Convert a Figma px value using the horizontal scale.
vw(px: number): string

// Convert a Figma px value using the vertical scale.
vh(px: number): string

// Convert a Figma px value to a rem string. Zoom-friendly alternative to vw/vh.
// base = root font-size in px (default 16; use 10 for the 62.5% trick).
rem(px: number, base?: number): string

// Returns a self-contained inline script string for SSR frameworks.
// Config values are baked in as literals — no runtime imports needed.
getScriptString(config?: FigmaScaleConfig): string

CSS fallback (optional)

If you want fallback values in CSS instead of relying on the script, add this to your global stylesheet. Replace the values with 1280 / yourCanvasW and 800 / yourCanvasH:

:root {
  --figma-scale-w: 0.7407;   /* 1280 / 1728 */
  --figma-scale-h: 0.7162;   /* 800  / 1117 */
}

This is handled automatically by initFigmaScale and getScriptString, so you only need this if you're managing CSS variables yourself.


License

MIT © Raven Luke Quinto