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

@northwestu/nuxt-nu-design-kit

v0.1.0

Published

Northwest University marketing design system as a Nuxt 4 layer — tokens, CSS components, and Vue wrappers.

Readme

@northwestu/nuxt-nu-design-kit

Northwest University marketing design system as a Nuxt 4 layer.

Packages the official stylesheet from northwestu.edu (assets/stylesheets/style-2026.css) with thin, auto-imported Vue wrappers (NButton, NCard, NSection, …) for ergonomic use in Nuxt apps. Component demos in the playground mirror the design-system examples.

Features

  • Design tokens — brand colors, space, type, radii, shadows, breakpoints (--nu-* CSS custom properties)
  • Official 2026 CSS — linked externally from www.northwestu.edu/assets/stylesheets/style-2026.css at runtime, so consumers always get the current upstream styles; a pinned vendored copy (nu-design-system.css) ships for offline/self-hosted use
  • Compatibility layer — nu-compat.css restores legacy classes the 2026 sheet no longer ships (stack/layout primitives, section-* tones, prose, card sub-parts, …) by aliasing them onto the 2026 --nu-* tokens
  • 40 Vue wrappers — auto-imported N* components over the design-system classes
  • Interactions — fade-in on scroll (plugin + composable), reel/carousel controls
  • Typekit fonts — Proxima Nova + Zenon via the NU kit stylesheet (optional)
  • Tested — Vitest unit + a11y contracts, Playwright e2e + axe scans

Requirements

  • Nuxt ^3.13.0 || ^4.0.0
  • Vue ^3.5.0

Installation

The package is published to npm as @northwestu/nuxt-nu-design-kit. No authentication needed.

1. Install the layer

npm install @northwestu/nuxt-nu-design-kit
# or
pnpm add @northwestu/nuxt-nu-design-kit

2. Extend Nuxt

// nuxt.config.ts
export default defineNuxtConfig({
  extends: ['@northwestu/nuxt-nu-design-kit'],
})

Extending the layer gives you:

  • The full design-system stylesheet (external 2026 sheet via runtime <link> + bundled app/assets/css/main.css → nu-compat.css)
  • All N* components, auto-imported
  • useNFadeIn / useNReel composables and the nClasses util, auto-imported
  • A client plugin that activates .fade-in / .fade-in-children scroll reveals on every page and after each route change
  • html[lang="en"] and runtime-controlled <head> links for the official stylesheet and Adobe Fonts (Typekit) — toggleable via runtimeConfig

Configuration

The layer's head resources are injected at runtime by a plugin, so consumers can toggle them per environment — in nuxt.config or via NUXT_PUBLIC_* env vars at deploy time.

Stylesheet

By default the official 2026 stylesheet is linked externally (https://www.northwestu.edu/assets/stylesheets/style-2026.css). To self-host instead (CSP, offline builds):

// nuxt.config.ts (consumer)
export default defineNuxtConfig({
  extends: ['@northwestu/nuxt-nu-design-kit'],
  runtimeConfig: {
    public: {
      nDesignKit: { stylesheet: 'none' },
    },
  },
})

Then load the pinned vendored copy yourself:

css: ['@northwestu/nuxt-nu-design-kit/css/nu-design-system.css'],

Or set NUXT_PUBLIC_N_DESIGN_KIT_STYLESHEET=none at runtime.

Typekit / fonts

The layer injects the NU Typekit stylesheet (https://use.typekit.net/lqz8krm.css) into <head>. If you self-host fonts:

runtimeConfig: {
  public: {
    nDesignKit: { typekit: false },
  },
},
// or NUXT_PUBLIC_N_DESIGN_KIT_TYPEKIT=false

App config

The layer exposes typed app config for debugging/introspection:

// app.config.ts (consumer)
export default defineAppConfig({
  nDesignKit: {
    name: '@northwestu/nuxt-nu-design-kit',
    version: '0.1.0',
  },
})

Usage

<template>
  <NSection tone="midnight">
    <NContainer>
      <h1>Welcome to Northwest University</h1>
      <NHStack>
        <NButton variant="primary" to="/apply">Apply</NButton>
        <NButton variant="secondary" href="/visit">Visit</NButton>
      </NHStack>
    </NContainer>
  </NSection>
</template>

CSS-only

You can also use design-system class names directly:

<a class="button primary" href="/apply">Apply</a>
<div class="card">…</div>

Or import the stylesheet without extending the full layer:

// nuxt.config.ts
export default defineNuxtConfig({
  css: ['@northwestu/nuxt-nu-design-kit/css'],
})

Package exports:

| Export | Resolves to | |--------|-------------| | @northwestu/nuxt-nu-design-kit | ./nuxt.config.ts (layer entry) | | @northwestu/nuxt-nu-design-kit/css | ./app/assets/css/main.css | | @northwestu/nuxt-nu-design-kit/css/* | ./app/assets/css/* |

Design tokens

Tokens are CSS custom properties on :root:

.hero {
  background: var(--nu-navy);
  color: var(--nu-color-white);
  padding: var(--nu-space-8);
  border-radius: var(--nu-border-radius-6);
}

| Token | Value | Role | |-------|-------|------| | --nu-blue | #0068bb | Primary brand | | --nu-navy | #034C87 | Deep brand | | --nu-alt | #148dcd | Alt blue | | --nu-amber | #ffbc2d | Secondary CTA | | --nu-evergreen | #04505c | Supporting green | | --nu-powder | #eaf4fb | Soft surface |

See the token block at the top of app/assets/css/nu-design-system.css for the full list (spacing scale --nu-space-*, radii --nu-border-radius-*, size scale --nu-size-*, typography, breakpoints).

The stylesheet also ships utility classes used across the demos, e.g. spacing utilities (mb-8, p-10) and the .inset full-cover link pattern; sizing (size-1…size-10) and aspect-ratio-* utilities are provided by the compat layer.

Compatibility layer

app/assets/css/nu-compat.css (imported after the official sheet) restores the legacy classes the 2026 stylesheet no longer ships — hstack/vstack/zstack/cover/cluster, section-* tones, prose, avatar, card-header/card-content/card-footer, blog, contact, cta, directory, feature, code-example, calendar-container/calendar-header, divider, size-*, aspect-ratio-*, scroll-reveal, and related modifiers. Its rules were carried over from the previous design-system stylesheet and resolve through aliases onto the 2026 --nu-* tokens, so tone/value changes upstream still flow through. Unlike the vendored file, nu-compat.css is maintained in this repo.

Component reference

All components are auto-imported. Every component accepts a class?: string prop that is merged onto its root element, and attributes fall through to the root. Wrappers emit the markup/classes expected by the 2026 stylesheet (plus compat-layer classes where noted above).

Actions & navigation

| Component | Root / classes | Props | Slots | |-----------|----------------|-------|-------| | NButton | .button (+ primary / secondary / contrast) on NuxtLink, <a>, or <button> | variant, to, href, external (adds target="_blank" rel="noopener noreferrer"), type ('button'), disabled | default | | NBreadcrumbs | .breadcrumbs > nav[aria-label="Breadcrumb"] | items: { label, to?, href? }[] (required) — first item renders the home icon, the current item renders <span aria-current="page"> | — | | NSubnav | nav.subnav > .container > .department-nav > ul (2026 markup; compat keeps the list visible on mobile) | items: { label, to?, href?, current?, external? }[] | default (custom items) |

Content & marketing blocks

| Component | Root / classes | Props | Slots | |-----------|----------------|-------|-------| | NBanner | .banner > .container | title | title, default, action | | NBlog | .blog on NuxtLink / <a> / <article>; inner .hstack > img + .vstack.gap-0 | to, href, title, meta, image, imageAlt | title, meta, default | | NCard | article.card | aspectRatio?: 2 \| 4 | default | | NCardHeader | img.card-header (with src) or .card-header element | as, src, alt | default | | NCardContent | .card-content | — | default | | NCardFooter | footer.card-footer | — | default | | NContact | .contact | name, title, email, phone, avatar, avatarAlt — email/phone render as mailto:/tel: links | name, title, email, phone, default | | NCta | .cta > .prose | title, description | title, description, default | | NDirectory | .directory, columns in .hstack.top | title | title, default | | NFeature | .feature — full-width h2, hr.divider, .layout > .main + .aside | title, tag | title, tag, aside, default | | NListing | ul.listing, items get a full-cover .inset link labelled by the item title | items: { title, href?, to?, description? }[] | item-${i} (scoped { item }), default | | NQuote | figure.quote > blockquote + figcaption | cite, author, scrollReveal | default, caption | | NStats | .stats (+ accent-1…accent-4) | accent, title (convenience; official markup nests NStat inside a heading via the default slot) | title, default | | NStat | span.stat | value?: string \| number | default |

Layout primitives

| Component | Root / classes | Props | Slots | |-----------|----------------|-------|-------| | NSection | <section> (+ section-<tone>) | tone: default, blue, alt, sky, skylight, powder, navy, midnight, evergreen, leaf, gold, sun, cloud, wisp, white; as (default 'section') | default | | NContainer | .container or .container-1….container-10 | size?: 0–10 \| 'default', as | default | | NHStack | .hstack | reverse, top, between, stretch, noWrap (bool modifiers), as | default | | NVStack | .vstack | as | default | | NZStack | .zstack | as | default | | NCenter | .center | as | default | | NCover | .cover | as | default | | NCluster | .cluster | as | default | | NSticky | .sticky | as | default | | NDivider | hr.divider | — | — | | NSpacer | .spacer (aria-hidden) | — | — |

UI & data

| Component | Root / classes | Props | Slots | |-----------|----------------|-------|-------| | NAccordion | .accordion, native <details>/<summary> | items: { title, content?, open? }[] | item-${i} (scoped { item }), default | | NAccordionItem | <details> (inside NAccordion default slot) | title (required), open | default | | NAvatar | img.avatar (+ size-1…size-5; no class = default 72px) | src (required), alt, size?: 1–5 | — | | NBadge | span.badge (+ variant) | variant: default, info, danger, warning, success, highlight | default | | NCalendar | .calendar-container + .calendar-header (compat) wrapping a table.cal month grid (2026) | title, subtitle | header, default, table | | NCode | .code-example | padded (default true; false adds p-0) | default | | NTable | .table > table | caption | caption, default | | NTooltip | data-tooltip attributes, pure CSS | text (required), position?: 'top' \| 'bottom', as | default (trigger) | | NTypography | .prose | as | default |

Motion & carousel

| Component | Root / classes | Props | Slots | |-----------|----------------|-------|-------| | NFadeIn | .fade-in or .fade-in-children | children?: boolean, as | default | | NReel | .reel[role="region" tabindex="0"] > .reel-container > ul.reel-list, controls in .reel-navigation | showControls (default true) | default (reel items) | | NReelItem | li.reel-item + reel-content-light / reel-content-dark | image, imageAlt, contentTone?: 'light' \| 'dark' | default |

NFadeIn runs its own IntersectionObserver (threshold 0.1, root margin 0px 0px -100px 0px) and adds .visible once when scrolled into view. The layer's client plugin does the same for plain .fade-in / .fade-in-children markup on every page and after each route navigation.

Composables

// Scoped fade-in observer (e.g. for dynamically rendered content)
const { observe } = useNFadeIn(rootElement?) // observe() re-scans

// Reel scroll state + controls (used internally by NReel)
const { canPrev, canNext, prev, next, update } = useNReel(scrollerElement)

prev() / next() smooth-scroll by one .reel-item width + gap; canPrev / canNext track scroll position and drive the disabled state of the controls.

Class-merge util

nClasses('button', variant && variant, { 'no-wrap': true }, props.class)
// clsx-style: strings passthrough, object keys when truthy, falsy skipped

Known differences from the official docs

  • NSubnav renders a flat item list; the official <details>/<summary> dropdown submenus and mobile .department-nav-button toggle are not implemented (compat CSS keeps the list visible below 960px instead).
  • NCalendar is a shell: it renders the 2026 table.cal grid container, but event/day interactions (.day-link, .event-link) are markup you supply via the table slot.
  • NAvatar renders <img> only; the official svg.avatar icon variant is not implemented.
  • NStats's title prop is a convenience not present in the official markup — prefer the default slot with the official nested-heading pattern (<h4><NStat>…</NStat> label</h4>).

Development

npm install --legacy-peer-deps
npx playwright install chromium   # first time only (e2e / a11y)
npm run dev          # docs-style playground at http://localhost:3000
npm run build        # build playground
npm run generate     # static-generate playground
npm run lint

The layer lives at the repo root. .playground/ extends .. so you can iterate on components against a real Nuxt app; every component has a demo page at /components/<slug> that mirrors the official docs page and links to it.

| Script | What it does | |--------|--------------| | dev | nuxi dev .playground — playground with hot reload | | build / generate / preview | Build / static-generate / preview the playground | | lint | ESLint over the repo | | test / test:watch / test:coverage | Vitest unit + a11y contracts | | test:e2e / test:e2e:ui | Playwright smoke + axe scans | | test:a11y | axe-core suite only | | test:all | unit + e2e/a11y |

Testing

| Suite | Tooling | What it covers | |-------|---------|----------------| | Unit | Vitest, @nuxt/test-utils, happy-dom | Key N* components, composables, a11y contracts | | E2E | Playwright | Playground load, all 31 component anchors, smoke interactions | | A11y | Playwright + @axe-core/playwright | WCAG 2.1 A/AA serious/critical violations, landmarks, alt text, focus |

E2E uses port 3333 by default so it does not attach to an unrelated app on :3000. Override with E2E_PORT=…. Set E2E_REUSE=1 only if you intentionally want to reuse a running server.

Sync upstream CSS

By default the layer links https://www.northwestu.edu/assets/stylesheets/style-2026.css externally at runtime (see Configuration → Stylesheet). A pinned copy is also vendored at app/assets/css/nu-design-system.css for reference and for consumers who must self-host (CSP, offline builds). To refresh the pinned copy:

scripts/sync-css.sh
# or a specific URL:
scripts/sync-css.sh "https://www.northwestu.edu/assets/stylesheets/style-2027.css"

The script re-downloads the stylesheet and re-adds the attribution header. Do not hand-edit the vendored file without re-syncing upstream — kit-specific fixes belong in app/assets/css/nu-compat.css.

Publishing (npm)

The package publishes to the public npm registry as @northwestu/nuxt-nu-design-kit. prepublishOnly runs nuxt prepare .playground as a final sanity check.

Publishing is automated: pushing a GitHub Release runs .github/workflows/publish.yml, which installs, runs unit tests, and publishes with provenance. One-time setup: create a granular access token at npmjs.com with read/write access to the northwestu org's packages, and save it as the repo secret NPM_TOKEN.

Release checklist

# 1. Verify the gate
npm run test:all && npm run lint

# 2. Bump the version in package.json (and the app.config.ts debug version)

# 3. Verify the tarball contents
npm pack --dry-run

# 4. Commit, tag, push
git add -A
git commit -m "Release <version>: …"
git tag v<version>
git push origin main --tags

# 5. Publish — either create a GitHub Release (runs CI publish),
#    or publish by hand (requires `npm login` as a northwestu org member):
npm publish --access public

After publishing, the package appears at https://www.npmjs.com/package/@northwestu/nuxt-nu-design-kit. Consumers install with no auth:

npm install @northwestu/nuxt-nu-design-kit

Package layout

@northwestu/nuxt-nu-design-kit
├── nuxt.config.ts          # layer entry (main) — css, fonts, runtime config
├── app.config.ts           # typed nDesignKit app config
├── app/
│   ├── assets/css/         # main.css (compat layer), pinned nu-design-system.css
│   ├── components/         # 40 N* Vue wrappers (auto-imported)
│   ├── composables/        # useNFadeIn, useNReel
│   ├── plugins/            # n-design-kit-head.ts (runtime head links), n-interactions.client.ts (fade-in observer)
│   └── utils/              # nClasses
├── scripts/sync-css.sh     # re-vendor upstream CSS
├── tests/
│   ├── unit/               # Vitest component + a11y contracts
│   └── e2e/                # Playwright smoke + axe scans
├── vitest.config.ts
├── playwright.config.ts
└── .playground/            # local demo app (not published)

Accessibility notes

  • Layer sets html[lang="en"] by default.
  • NListing overlay links get aria-label from the item title.
  • NReel is a keyboard-focusable region (tabindex="0", role="region") with labelled prev/next controls.
  • NBreadcrumbs uses nav[aria-label="Breadcrumb"] and aria-current="page"; decorative icons are aria-hidden.
  • Axe color-contrast findings from vendored design-system tokens are reported but not CI-gated until palette work lands upstream.

License

Apache-2.0 — see LICENSE. Source stylesheet: www.northwestu.edu/assets/stylesheets/style-2026.css.