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

astro-styletrace

v0.1.0-beta.4

Published

Astro integration that shows where a style came from and how far apart elements are, without opening DevTools

Downloads

72

Readme

astro-styletrace

npm version beta tag license

First public beta. The API and UI are usable for local Astro development, but may still change before 1.0.

An Astro integration that shows where a style came from and how far apart two elements are, without opening DevTools.

Hold Alt to measure. Alt + Click an element to open a panel that tells you, for every declared property, what the CSS says, what the browser computed, and what the layout actually produced — plus the file it came from, one click away from your editor.

When an element is selected, styletrace writes local handoff files that workspace-aware agents can read.

Dev only. The integration bails out unless command === 'dev', so nothing reaches a production build.

Install

npm install -D astro-styletrace
# pnpm add -D astro-styletrace
# yarn add -D astro-styletrace

Supports Astro 5, 6, and 7 (Vite 6, 7, and 8 respectively).

// astro.config.mjs
import { defineConfig } from 'astro/config';
import styletrace from 'astro-styletrace';

export default defineConfig({
  integrations: [styletrace()],
  // The Dev Toolbar can stay off. styletrace does not depend on it.
  devToolbar: { enabled: false },
});

Start the dev server and press Ctrl + Shift + C.

Keys

| Key | Action | | --- | --- | | Ctrl + Shift + C | Toggle styletrace on / off (default; configurable) | | Alt (held) | Show the measurement overlay (the panel stays closed) | | Alt + Click | Select an element and open the panel (click it again to close) | | Enter | Open the first source link for the selected element | | Esc / click outside | Clear the selection and close the panel | | Alt + ↑ / ↓ | Move the hovered element to its parent / child |

An indicator sits in the bottom-left corner while styletrace is on.

Searching and reading are separate

While Alt is held you get the overlay only — no panel. Alt + Click the element you want to read and the panel opens; from then on hovering no longer changes its contents. The selection doubles as the reference point for measurement, so you can keep measuring the distance between the element you chose and anything else on the page. While you measure (Alt held) the panel fades back to stay out of the way. Clicking outside closes the panel and the click still reaches the page.

Options

styletrace({ shortcut: 'Alt+Shift+D' })

| Option | Type | Default | Description | | --- | --- | --- | --- | | shortcut | string | 'Ctrl+Shift+C' | Toggle shortcut. Ctrl / Cmd / Shift / Alt plus one key. |

Change it if the default collides with a handler on your page. Matching is done on event.code, so keyboard layout and modifier-mangled event.key values do not matter.

Reading the panel

One property per block. Only properties that are actually declared appear.

margin-top                        .row[data-astro-cid-j7pv25f6]  +2
  declared   var(--space-l)  via margin-block
  computed   64px
  measured   64px
src/pages/index.astro ↗
  • declared is the strongest candidate by specificity, not a verdict on which rule won. If other declarations feed the same longhand, a +N badge appears. A row without +N has exactly one candidate and can be trusted as-is.
  • computed is the only ground truth.
  • measured is the difference between getBoundingClientRect() values. Rows where it disagrees with computed are highlighted. Margin collapsing, flex distribution, and gap losing to justify-content all show up here.
  • If font-size / line-height are not declared on the element, styletrace walks up the ancestors and labels the source, e.g. ← body.
  • width / height get a row only when explicitly declared. The actual size is always shown in the header.

Click the source file name, or press Enter, to open it in your editor at the exact line when one can be resolved. The link briefly reports whether the editor jump opened or failed.

After HMR, styletrace keeps the selected element when the same node survives, and tries to resolve it again by a stable DOM locator when Astro replaces the node. Rows that changed since the previous panel update get a changed marker and a compact before row for the values that moved.

When the selected element name has a pulsing context dot, the selected element, viewport, declared candidates, computed and measured values, selectors, competing-candidate counts, and file:line sources are available in .astro-styletrace/current-observation.json. The observation labels declarations as candidates because styletrace does not claim to reproduce the complete cascade. Handoff is local; nothing is sent to an external service.

What measured means

| Property | Measured value | | --- | --- | | width / height | The content box, derived from getBoundingClientRect() minus border and padding. getComputedStyle() resolves these to the used value, which is the content box whatever box-sizing says, so both rows describe the same box. The header keeps showing the full border box. | | margin-* | The real gap to the adjacent sibling, or to the parent's content box. Only shown when the element has a margin of its own — with a computed margin of 0 the space beside it belongs to the parent's gap or to the sibling's margin, not to this element. Margin collapsing and gap conflicts surface here. | | row-gap / column-gap | The smallest actual gap between children | | padding-*, font-size, line-height | None — computed only |

For example, a paragraph with margin-block: 1rem inside a flex container with gap: 12px reports a computed value of 16px and a measured value of 44px.

Features

  • Hit testing, hover highlighting, margin / padding boxes
  • Distance measurement in all three configurations (separated / contained / overlapping) with guide lines and collision-avoiding labels
  • Source resolution through data-vite-dev-id, including nested CSS &, conditional groups (@layer / @media / @supports), and declarations directly inside nested at-rules (CSSNestedDeclarations)
  • Specificity calculation with :is() / :where() / :has() support, used to rank candidates
  • Cross-origin sheets are kept in the index as unreadable rather than silently dropped
  • +N for competing declarations, expandable in place
  • Editor jump with a PostCSS-built selector → line map
  • Agent-ready diagnostic copy with source lines and measured layout values

Non-goals

styletrace deliberately does not show: the resolved value behind var(), the expansion of clamp(), px → rem / vw conversions, the full list of matched rules, specificity and @layer values, or a text export of the panel. The two questions worth answering are "what does the CSS say" and "what did it actually become" — not the derivation in between.

Editor jump

The dev server runs launch-editor behind /__styletrace/open-in-editor. Editor selection is left to the LAUNCH_EDITOR / EDITOR environment variables, or inferred from a running editor.

Line numbers come from a Vite transform hook where PostCSS collects selector → line and serves it at /__styletrace/css-map. The map is fetched once at startup and read synchronously afterwards (fetching per hover cannot hold 60fps).

  • For .astro <style> blocks the original file is re-read rather than the compiled code, which collapses newlines and puts every rule on the same line
  • Selectors are matched through a normalization key (drop [data-astro-cid-*], '", *::before::before). The normalizer lives in one place, src/core/css-map.ts, and the dev server imports the same function
  • Rules whose line cannot be resolved (cross-origin, inline, key mismatch) fall back to the top of the file

Agent handoff

Selecting an element writes two local files under the Astro project root:

  • .astro-styletrace/current-observation.json
  • .astro-styletrace/handoff.md

The pulsing context dot beside the selected element name means those files are prepared. From there you can ask any workspace-aware coding agent to read .astro-styletrace/handoff.md and fix the selected styling issue. The JSON uses the same vendor-neutral observation model that drives the panel, without DOM instances, browser storage, or editor open targets.

CLI and MCP access are still available for agents or scripts that prefer pull-based reads:

npx astro-styletrace observation --url http://localhost:4321
npx astro-styletrace source src/pages/index.astro --line 24 --url http://localhost:4321

The observation endpoint is updated only while a styletrace selection is active. source reads are restricted to files inside the Astro project root.

For tools that speak MCP over stdio:

npx astro-styletrace mcp --url http://localhost:4321

The adapter exposes styletrace_observation and styletrace_source.

Optional agent skill

Agents that support the open agent skills ecosystem can install the companion skill from the shared .agents/skills/astro-styletrace project skill:

npx skills add roukara/astro-styletrace --skill astro-styletrace

During local development of this repository:

npx skills add ./ --skill astro-styletrace

The skill teaches agents to read .astro-styletrace/handoff.md first, inspect current-observation.json, and make the smallest relevant CSS change.

Architecture

Everything except src/index.ts (the integration) and src/app.ts (the client shell) is free of Astro dependencies. This is machine-checked:

pnpm check

app.ts creates the host element and its ShadowRoot, listens for the shortcut, and calls createInspector(shadowRoot). The host is attached directly under document.documentElement — under body it would break pages that rely on body > *:last-child.

Styles live in src/ui/styles.ts as a string rather than a .css file: Vite would otherwise inject the CSS into the whole page through the dev server, defeating the ShadowRoot.

Development

pnpm install
pnpm build
pnpm --filter playground dev

| Script | Purpose | | --- | --- | | pnpm build | Compile to dist/ | | pnpm watch | Compile in watch mode | | pnpm typecheck | Types only | | pnpm check | typecheck + the Astro-dependency boundary check | | pnpm check:compat | Pack and smoke-test the integration against Astro 5, 6, and 7 |

The design document is spec.md (Japanese).

License

MIT