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

adres-design-system

v0.1.0

Published

Adres design system monorepo — white-label, multi-brand, Vignelli-rooted.

Readme

Adres Design System

A white-label, multi-brand design system for Adres (proptech, part of Aldar). Built on Next.js 16 · React 19 · Tailwind CSS 4 · Radix · Motion · class-variance-authority · TypeScript strict.

The default brand is Adres (Airbnb-DLS-inspired palette + Switzer typography). New brands are added by dropping in a new CSS variable file — components never know which brand they're wearing.


First-time setup

This repo uses npm workspaces (npm 10+). The repository was scaffolded inside a Cowork sandbox whose filesystem couldn't complete the install, so clean any leftover artifacts and install fresh:

cd ~/repos/adres-design-system

# Remove any partial install state from the scaffold step
rm -rf node_modules package-lock.json pnpm-lock.yaml pnpm-workspace.yaml _tmp_*

# Install everything
npm install

Then:

npm run docs           # legacy docs  at  http://localhost:3000
npm run docs:v2        # Fumadocs     at  http://localhost:3003
npm run playground     # playground   at  http://localhost:3001  (brand switcher)
npm run storybook      # storybook    at  http://localhost:6006  (install docs + components)
npm run build-storybook  # rebuild packages/design-system/storybook-static for deployment
npm run storybook:static # serve prebuilt static only (no live reload)
npm run build          # turbo: build every package and app
npm run typecheck      # strict TypeScript across the workspace

Workspace deps use "@adres/design-system": "*" — npm 7+ resolves the * to the local workspace package automatically.


Consuming from npmjs (apps outside this monorepo)

Packages are published publicly to npmjs.com under the @adres scope. No special .npmrc is required for install.

npm install @adres/design-system @adres/brand-adres
# peers: react@19, react-dom@19, tailwindcss@4

Wire CSS (order matters):

@import "tailwindcss";
@import "@adres/brand-adres/theme.css";
@import "@adres/brand-adres/overrides.css";
@import "@adres/design-system/styles";

Activate the brand:

<html data-brand="adres">
import { Button } from "@adres/design-system"

Consumers need a bundler that can compile TypeScript from node_modules (Next.js, Vite, etc.). Package exports currently point at src/ (no separate dist build).

Publishing (maintainers)

  1. Own or create the @adres org on npmjs; enable 2FA.
  2. npm login
  3. npm run typecheck && npm run validate:brands && npm run sync:skills && npm run validate:skills
  4. Bump package versions before re-publishing (npm rejects duplicate versions).
  5. npm run publish:npm — publishes in order: brand-contract → design-system → brands.

Patch-releasing a single package

Most changes (e.g. a design-system component tweak) only touch one or two packages. Don't run the full npm run publish:npm script for these — npm rejects re-publishing a version that hasn't changed, so it will error on every other package that wasn't bumped.

Not sure which packages actually changed? Diff the local source against what's currently published — don't trust memory or a stale CHANGELOG:

npm pack @adres/brand-thinkprop@<published-version>
tar -xzf adres-brand-thinkprop-*.tgz
diff -rq package/src packages/brand-thinkprop/src
# 1. Confirm the working tree is clean and the change is committed
git status

# 2. Bump each affected workspace's version — updates its package.json,
#    and by default also commits + tags "<name>@<version>" (one bump
#    commit covering all `-w` targets when passed together)
npm version patch -w @adres/design-system -w @adres/brand-thinkprop

# 3. Push the commit and the tags
git push && git push --tags

# 4. Verify, then publish only the changed packages
npm run typecheck && npm run validate:brands
npm publish -w @adres/design-system --access public
npm publish -w @adres/brand-thinkprop --access public

# 5. Confirm they landed
npm view @adres/design-system version
npm view @adres/brand-thinkprop version

If the change touches @adres/brand-contract, publish that one first — every other package depends on it (see publish order above). Consumers then pick up the fix with a normal npm update @adres/design-system.

No changesets/lerna here — versions are hand-bumped per workspace. See .cursor/skills/adresx-release-deploy/SKILL.md for the target state (adopting Changesets) once manual bumps start drifting.

Dual registry later (Azure Artifacts)

npmjs is the primary registry for testing. When you are ready for a private Aldar feed, publish the same version again with a user/CI Azure .npmrc (never commit tokens):

npm publish -w @adres/design-system \
  --registry=https://pkgs.dev.azure.com/adres-dari-dev/Adres-Design/_packaging/adres-packages/npm/registry/

Repository layout

adres-design-system/
├── apps/
│   ├── docs/               # Next.js docs site (legacy hand-rolled)
│   ├── docs-v2/            # Fumadocs docs (same content, MDX + search)
│   ├── playground/         # Next.js live preview with brand switcher
│   └── playbook/           # Config-driven guidelines (playbook-kit)
├── packages/
│   ├── design-system/      # Components, hooks, utilities. Brand-agnostic.
│   ├── brand-adres/        # Adres default brand tokens (Rausch / Babu / Arches / Switzer)
│   └── brand-template/     # Skeleton brand for cloning when adding a new white-label theme
├── package.json            # workspaces + turbo scripts
├── turbo.json
├── tsconfig.base.json
└── README.md

Architecture in three sentences

  1. Brand is a layer, not a fork. Components reference semantic CSS variables (--primary, --background, …) — never brand colours.
  2. One source of truth per token. Spacing, radius, motion, type, colours all live as named tokens. No magic numbers in components.
  3. Vignelli, not maximalism. Typography first, grid is law, hierarchy through scale and weight, motion only when it communicates.

Three token layers

| Layer | Lives in | Example | |---|---|---| | 1 — Brand primitives | packages/brand-* | --rausch-600: 358 100% 68% | | 2 — Semantic tokens (the contract) | packages/brand-* | --primary: var(--rausch-600) | | 3 — Component tokens | packages/design-system | --button-padding-x (when introduced) |

Components consume layer 2 only, via Tailwind utilities (bg-primary). The mapping from semantic vars to utilities lives in packages/design-system/src/styles/base.css (@theme inline).


How a colour reaches a pixel

1. Brand defines the primitive:    --rausch-600: 358 100% 68%
2. Brand wires the semantic:       --primary: var(--rausch-600)
3. Design system maps it:          --color-primary: hsl(var(--primary))   /* @theme inline */
4. Component consumes it:          className="bg-primary"

Steps 1 + 2 are brand-specific. Steps 3 + 4 never change. To re-skin, only steps 1 + 2 change.


Adding a new brand

cp -R packages/brand-template packages/brand-acme

Then in packages/brand-acme:

  1. Update package.json name to @adres/brand-acme.
  2. In src/theme.css, change every :root[data-brand="template"] selector to :root[data-brand="acme"].
  3. Replace primitives (your brand's colour scales, fonts, radius).
  4. Wire every semantic token (--background, --primary, etc.) — keep the names identical.
  5. Provide a parallel .dark block.
  6. Update src/tokens.ts with the typed metadata mirror.

Wire it into the app's globals.css:

@import "tailwindcss";
@import "@adres/brand-adres/theme.css";
@import "@adres/brand-acme/theme.css";        /* new */
@import "@adres/brand-acme/overrides.css";     /* optional */
@import "@adres/design-system/styles";

Register in apps that ship a brand switcher (playground):

  1. "@adres/brand-acme": "*" in the app package.json
  2. @import the brand CSS files in globals.css (see above)
  3. { id: "acme", name: "Acme" } in apps/playground/app/themes.ts

Activate at runtime by setting <html data-brand="acme">. The playground ThemeProvider syncs data-brand on <html> — your app does the same.

Validate with npm run validate:brands (checks REQUIRED_SEMANTIC_CSS_VARS and playground wiring). After structural changes, also run npm run sync:skills && npm run validate:skills to keep agent docs in sync.


v1 component inventory

Web App — Button, Input + Field + Label, Card (CardHeader/Title/Description/Content/Footer), Dialog, Tabs, Badge, Alert, Toaster (sonner), Sidebar (collapsible), TopNav + Breadcrumbs.

Marketing — Hero, FeatureGrid, CTA.

All components:

  • Composable (CVA where variants apply)
  • Accessible (Radix where appropriate, semantic HTML, ARIA, keyboard, focus-visible)
  • Responsive (mobile-first, sensible breakpoints)
  • Motion-aware (uses useReducedMotion and the motion-reduce: Tailwind utilities)

Planned for v2 (not yet implemented)

  • Web App: Dropdown menu, Select, Combobox, Data table (sortable/filterable), Empty state, Loading skeletons, Tooltip, Popover, Switch, Checkbox, Radio group, Avatar, Separator
  • Marketing: Pricing, Testimonials, FAQ accordion, Footer, Logo cloud, Stats section, Long-form content section

The patterns are established; each component is ~30 minutes of work.


Default Adres brand (Airbnb DLS lineage)

| Token | Value | Note | |---|---|---| | Primary | Rausch #FF5A5F | actions, links, brand spark | | Secondary | Babu #00A699 | secondary actions, data contrast | | Accent | Arches #FC642D | emphasis highlights | | Foreground | Hof-warm #484848 | body text | | Neutral surface | warm gray (24° hue, 4% sat) | not cool blue | | Typeface | Switzer (Fontshare) | weights 300–700 | | Radius | 8 / 12 / 16 / pill | generous, not sharp | | Shadows | warm-tinted, soft | not heavy |

Apps load Switzer from Fontshare CDN by default. For production deployments, self-host the font files and adjust the @import in app/globals.css.


Accessibility

  • WCAG 2.1 AA target. Default Adres pairings (Rausch/white, white/Rausch, Hof/neutral-50) clear AA at 14px+.
  • Visible 2px focus ring in --ring on :focus-visible only.
  • Radix primitives handle keyboard and focus management for Dialog, Tabs, Dropdown.
  • All inputs and dialogs use proper ARIA. The Field primitive auto-wires aria-describedby for help/error text and aria-invalid on error.
  • Icon-only buttons require an aria-label (TS strict surfaces missing labels).
  • prefers-reduced-motion is respected globally (CSS) and in motion-driving components (via useReducedMotion).

Responsive

  • Mobile-first; everything degrades gracefully from large desktop down to 360px.
  • Sidebar collapses to icon-only via the collapsed prop.
  • TopNav has start/center/end slots that wrap.
  • Hero auto-stacks below md. FeatureGrid drops 3 → 2 → 1 columns.

Verification status (this scaffold)

| Check | Result | Notes | |---|---|---| | design-system source typechecks | ✅ pass | 2 type errors found and fixed during scaffold | | brand-adres typechecks | ✅ pass | no external deps | | brand-template typechecks | ✅ pass | no external deps | | App typechecks | ⚠ deferred | requires complete npm install; sandbox time-budget prevented finishing in-place | | next build | ⚠ deferred | same reason | | npm run lint | ⚠ deferred | ESLint configs are wired but not run |

Action item for first local install: run the cleanup + install commands at the top of this README, then npm run typecheck && npm run build to confirm everything compiles in your environment.


Recommended next steps

  1. Run npm install locally — confirm the workspace resolves and apps start.
  2. Self-host Switzer — replace the Fontshare CDN @import in app/globals.css with next/font/local or self-hosted @font-face declarations.
  3. Ship the v2 components in priority order: Dropdown, Select, Tooltip, Skeleton, Avatar — these unblock most app surfaces.
  4. Add a Data Table with sort/filter/pagination — Adres listing dashboards will need this immediately.
  5. Add Storybook or a route-per-component docs view so each component has live + code in one place.
  6. Set up a visual regression suite (Chromatic, Percy, or Playwright snapshots) — multi-brand systems are a perfect fit.
  7. Add a ColorPair contrast test in CI that ensures every brand's --primary / --primary-foreground, --background / --foreground, etc. clear WCAG AA.
  8. Wire up next/font in both apps so font loading is optimized rather than CDN-blocked.
  9. Token-doc generator — emit a JSON token reference from each brand's tokens.ts for use by Figma plugins or other tooling.
  10. Internationalisation + RTL — Adres operates in the UAE; an RTL switch and Arabic typography pairing belong on the v2 roadmap.

License

Proprietary — internal Adres / Aldar use.