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

tinseltown

v0.3.0

Published

Hollywood lighting for your website. One HTML tag.

Readme

Tinseltown: light through venetian blinds, cast behind a landing page

tinseltown

Hollywood lighting for your website. One HTML tag.

npm downloads License: MIT

Live demo

Film crews put a cut-out called a cookie in front of the lamp, and flat light gets life, pattern and texture. Tinseltown does that for a flat web page. A good background does not have to be hard to make.

What you get

  • A page that looks like a place. Most sites sit on the same gradient. Light through blinds, leaves or a window gives yours a room to stand in.
  • No stock overlays and no hero video. The whole thing is under 20 kB. A hero video is megabytes, and every visitor on mobile data pays for it.
  • A new mood without a designer. One attribute moves the sun, warms the light or fills the room with smoke. A campaign, a season or a dark theme is one line of HTML.
  • It fits the site you have. It works anywhere you can paste HTML. No framework, no build step, no dependencies.
  • Safe to ship. It holds still for visitors who ask for less motion, stays out of screen readers, tracks nobody and is MIT licensed.

Examples

Twelve renders: blinds, french doors, a photo used as a colour slide, a fence, halftone, an iris, clouds, leaves, palm fronds and a passing train

Eleven presets under different rigs, and one photo used as the cookie. Photo by Mikhail Nilov on Pexels.

Install

From here on, this page is for the person who adds it to the site.

Without installing anything:

<script type="module" src="https://cdn.jsdelivr.net/npm/tinseltown@latest/src/tinseltown.js"></script>

With a bundler:

npm install tinseltown@latest
import 'tinseltown'

The presets and the option schema are exported too, as tinseltown/cookies and tinseltown/options.

Usage

The element fills its nearest positioned parent and sits behind the content.

<section style="position: relative; isolation: isolate">
  <tinseltown-backdrop preset="blinds-horizontal"></tinseltown-backdrop>
  <h1>Your content</h1>
</section>

A full-page backdrop, late afternoon, with smoke in the room:

<tinseltown-backdrop preset="window" style="position: fixed"
  elevation="25" color-temp="2800" haze="0.4"></tinseltown-backdrop>

Leaves that move:

<tinseltown-backdrop preset="leaves" motion="sway breathe"></tinseltown-backdrop>

Presets: blinds-horizontal blinds-vertical window french-doors arched-window bars chain-link fence staircase bricks halftone breakup iris clouds leaves palm palm-tree ceiling-fan train

Every preset is generated in code. The repo ships no third-party artwork.

Your own cookie

A cookie is any image, video or canvas. Black blocks light. Transparent or white passes it. Grey passes part of it. Black on transparent and white on black both work as they are. Colour tints the light, the way a gel or a slide does, so a photo works as a cookie too. A photo repeats mirrored, which hides the seam.

<tinseltown-backdrop src="cookie.png"></tinseltown-backdrop>

A phone photo of a cut-out is noisy. Blur it, then cut it at a threshold:

<tinseltown-backdrop src="photo.jpg" cookie-blur="4" threshold="0.5"></tinseltown-backdrop>

A video or an animating canvas:

backdrop.setCookie(video)
backdrop.setCookie(canvas, { live: true })

The rig

Presets are composed for a frame of 3.2 by 2 units. The element shows the largest part of that frame with its own aspect, like background-size: cover, so a phone, a laptop and an ultrawide monitor all get a fully lit wall. Distances and sizes use the same unit.

| Attribute | Default | | | --- | --- | --- | | light-size | 0.15 | Radius of the source. Larger is softer. | | light-shape | disc | disc, square or ring. Gaps between leaves image the lamp, so the shape shows. | | light-distance | 6 | From the wall to the lamp. | | azimuth elevation | 140 42 | Where the lamp stands, in degrees. Low elevation rakes and stretches. | | spread | 32 | Half-angle of the spot cone. | | aim-x aim-y | 0 0 | The point on the wall the lamp aims at. | | cookie-distance | 1.5 | From the wall, along the beam. Closer is sharper. | | cookie-scale cookie-roll | 3 0 | Cookie height in units. Rotation in degrees. | | cookie-blur threshold | 0 0 | Blur from 0 to 8, then a luminance cut from 0 to 1. Zero is off. | | invert | | Boolean. Swaps what blocks and what passes. | | layers | 1 | Up to 3 copies of the cookie at increasing depth, for parallax. | | edge | repeat | Outside the cookie: repeat, block or pass. | | color-temp intensity ambient | 3200 2.2 0.1 | Kelvin, key level, fill level. Contrast is key against fill. | | light-color | | A gel. Any CSS colour. Replaces color-temp. | | wall | #3a3835 | Wall colour. Any CSS colour. | | haze | 0 | Smoke in the room, from 0 to 1. | | motion speed | | Any of sway drift spin breathe flicker, space separated. | | samples resolution | 48 1 | Paths per pixel and render scale. Quality against GPU time. |

A preset sets its own defaults. Any attribute overrides them. backdrop.options returns the resolved values.

Every value is validated. A number outside its range is clamped, and anything unreadable falls back to the default, so samples="100000" cannot stall the GPU and elevation="0" cannot divide by zero.

How it works

The page is the wall. For every pixel, one fragment shader walks samples paths to points spread across the lamp. Each path is intersected with the cookie planes and reads the cookie texture there. The average, weighted by inverse-square falloff, both cosines and the spot cone, is the colour of the pixel. Twelve probes go first. A pixel that sees all of the lamp or none of it stops there, so only the penumbra pays for every sample. Penumbra, keystone stretch and falloff come out of that integral. Nothing is blurred.

Haze marches the view ray through a drifting noise volume and asks the same question at each step.

A still rig keeps averaging new sample patterns for 24 frames, about a thousand paths per pixel, and then stops and costs nothing. Animated rigs stop when offscreen. Under prefers-reduced-motion every rig renders one still frame.

Limitations

  • WebGL2 only. Without it the element shows a flat dark background.
  • Tuned on Apple Silicon. A governor lowers the render scale when frames run long, and phones start a step down. On a draining battery below 30 percent the rig renders small and holds still. That needs the Battery Status API, which only Chromium browsers have. Lower samples and resolution yourself for a heavy page.
  • One cookie image per element. Layers reuse it at different depths.
  • Tested in Chrome. Safari and Firefox are untested.

Same rig, other gags

Each of these takes a grip truck on set. Here each is a change to one shader. None of them is built yet.

  • Fire: fabric strips in front of a wind machine, plus a flicker box. A displaced strip cookie, flicker, 1900 K.
  • Water caustics: a tray of water and mirror shards, shaken by hand. A refracting height field replaces the cookie.
  • Rain on the window: rivulets projected onto a face, as in In Cold Blood. An animated refracting cookie.
  • Ceiling fan noir: a rotating cookie layer over the blinds.
  • Passing train, passing car: lamps on a dolly run past the window. Animate azimuth.
  • Clouds over the sun: a flag waved slowly in front of the lamp. A large soft cookie layer far from the wall.
  • Lightning, TV glow, neon: intensity and colour envelopes on the lamp.
  • Eclipse crescents and bokeh dapples: gaps between leaves act as pinholes and image the light source. Give the lamp a shape texture and the same integral produces them.
  • Multiplane camera: Disney's layered glass panes are cookie layers at depth.
  • Shadow puppets and Lotte Reiniger silhouettes: articulated cookies, close to the wall.
  • Dust motes and god rays: particles in the haze volume.
  • Time of day: bind elevation, azimuth and colour temperature to scroll or to the visitor's clock.

Develop

npm install, npm run dev, npm test, npm run test:browser. See DEVELOPMENT.md and CONTRIBUTING.md.

The demo page uses the element as its own backdrop. Its design tokens live at the top of demo/demo.css.

Same name, other project

For hacker-movie page-load effects, see Tinseltown.js by Antrikshy. The two share a name and nothing else.

License

MIT