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

@fadymondy/nasaq

v1.4.0

Published

Nasaq (نسق): one product language for every surface. React + Base UI + Tailwind v4 components, the same components for Vue 3 and for HTML/Alpine.js (Laravel Blade, Livewire, FilamentPHP via fadymondy/nasaq-php), design tokens, brand marks, a React Native

Readme

@fadymondy/nasaq

Nasaq (نسق) is one product language for every surface: React 19 components built on Base UI and Tailwind CSS v4, design tokens, brand marks, a React Native kit and Electron window chrome. Arabic and RTL are first-class, not an afterthought.

  • Hundreds of components: buttons, forms, data tables, charts, commerce, auth, AI, workflow, and full page blocks.
  • Tokens as CSS variables (--nq-*), themeable per brand (data-brand), light and dark, three densities.
  • Logical properties everywhere: the same component is correct in English and Arabic.
  • Also on the shadcn registry, if you prefer to own the source (see below).

Docs and live component lab: https://docs.nasaqui.com · Landing: https://nasaqui.com

Install

npm install @fadymondy/nasaq react react-dom
npm install tailwindcss @tailwindcss/postcss   # Tailwind v4 (or @tailwindcss/vite)

Requires React 19+ and Tailwind CSS 4. react-native, react-native-svg, expo-haptics and electron are optional peers, needed only for /native and /electron.

The Vue and Alpine adapters' libraries are optional peers too, so a React app installs no Vue or Alpine code. Add them only for the entry point you use:

npm install vue reka-ui lucide-vue-next vue-sonner                     # @fadymondy/nasaq/vue
npm install alpinejs @alpinejs/anchor @alpinejs/collapse @alpinejs/focus  # @fadymondy/nasaq/alpine

The script-tag build (cdn/nasaq-alpine.js) bundles the Alpine plugins and needs neither.

There is no root import. Use the subpaths listed below.

CSS setup (required)

The components use Tailwind utility classes and --nq-* tokens. Tailwind does not scan node_modules, so tell it where the package lives. In your Tailwind entry CSS (for Next App Router, app/globals.css):

@import "tailwindcss";
@import "@fadymondy/nasaq/tokens.css";
@import "@fadymondy/nasaq/theme.css";
@import "@fadymondy/nasaq/web/styles.css";
@source "../node_modules/@fadymondy/nasaq/dist/web";

The @source path is relative to the CSS file: adjust the ../ so it reaches your node_modules (in a monorepo, the hoisted node_modules). Without the @source line the components render unstyled, because their classes are never generated.

  1. tokens.css: the --nq-* variables (colour, type, spacing, density, expression, brand).
  2. theme.css: maps the tokens into Tailwind's @theme (so bg-card, text-muted-foreground, rounded-card, h-control work) and the dark: variant.
  3. web/styles.css: base styles (fonts, scrollbars, focus).

Provider and no-flash theme

// app/layout.tsx (Server Component)
import { NasaqProvider, nasaqThemeScript } from "@fadymondy/nasaq/web";
import "./globals.css";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <script dangerouslySetInnerHTML={{ __html: nasaqThemeScript() }} />
      </head>
      <body>
        <NasaqProvider brand="nasaq">{children}</NasaqProvider>
      </body>
    </html>
  );
}

Under a strict Content Security Policy an inline script needs a nonce or a hash. Two options:

// 1. A nonce: spread the props and pass the per-request nonce (it must be in script-src).
import { nasaqThemeScriptProps } from "@fadymondy/nasaq/web";
<script {...nasaqThemeScriptProps("system", { nonce })} />

// 2. A static file, allowed by script-src 'self': no nonce, no inline code.
<script src="/nasaq-theme.js" data-default-theme="system" />

The static file ships as @fadymondy/nasaq/theme-script.js. Copy it to your public folder (or serve it from node_modules/@fadymondy/nasaq/dist/theme-script.js). It reads the default theme from data-default-theme and must be a classic, synchronous script in <head> (no async or defer) so it runs before first paint.

NasaqProvider sets data-brand, data-theme, data-density, data-expression, dir and lang on <html> and persists the theme.

Fonts

The package ships no font files. The stacks are Inter, Alexandria and JetBrains Mono (all SIL OFL, so you can load them with next/font or @fontsource/*) and Lusail, which is proprietary and is not bundled: load your own licensed copy or leave it out and Inter takes over. Without any of them, the system fonts are used.

A first component

import { Button, Card, CardContent, CardHeader, CardTitle, Price } from "@fadymondy/nasaq/web";

export default function Page() {
  return (
    <Card>
      <CardHeader><CardTitle>Nasaq mug</CardTitle></CardHeader>
      <CardContent className="flex items-center gap-3">
        <Button>Add to cart</Button>
        <Price amount={49} currency="SAR" />
      </CardContent>
    </Card>
  );
}

Components that hold state or use hooks are marked "use client" in the built files, so you can render them straight from a Server Component. Props that are functions can only be passed from a Client Component (normal React rule). Hook-based APIs such as useDataTable need a "use client" file of your own:

"use client";
import { DataTable, useDataTable, type DataTableColumn } from "@fadymondy/nasaq/web";

const columns: DataTableColumn<Row>[] = [
  { id: "name", header: "Name", cell: (r) => r.name, sortValue: (r) => r.name },
];

export function Customers({ rows }: { rows: Row[] }) {
  const table = useDataTable({ data: rows, columns, getRowId: (r) => r.id });
  return <DataTable table={table} label="Customers" />;
}

Every component has a manual with props, anatomy and examples in the lab and in the MCP (below).

RTL and Arabic

Pass a locale and everything flips: direction, logical spacing, mirrored directional icons, Arabic type metrics.

<NasaqProvider locale="ar">{children}</NasaqProvider>   // dir="rtl" lang="ar" on <html>

Built-in strings ship in English and Arabic; components take a labels prop to override. Keep code, IDs, URLs and numbers-with-units left-to-right with dir="ltr" or <bdi>.

Theming by brand

<NasaqProvider brand="mahaam" density="comfortable" expression="native" defaultTheme="dark">

Brands: nasaq, fadymondy, mahaam, zekra, moharrik, seatfor, health-debug, circlexo, hosbah, orchestra, togo, and the CircleXO apps matjar, sanduq, mizan, qaima, makhzan, mawared. A brand changes identity and action colour only; status colours keep their meaning. Every pair is contrast-tested. Read the manifests and draw marks from @fadymondy/nasaq/brands.

Not one of them? Theme Nasaq with your own colours, no registration: <NasaqProvider brandColors={{ brand: "#C8283A", accent: "#C9A227" }}> (each role is "#RRGGBB" or { light, dark }; dark steps and on-colours are derived for contrast; data-brand="custom"). Pass your own logo to SidebarBrand, AuthLayout or ProductMark src. The native NasaqProvider takes the same brandColors. See Theming in the lab docs.

Subpaths

| Import | What | | --- | --- | | @fadymondy/nasaq/web | React DOM components, NasaqProvider, nasaqThemeScript, nasaqThemeScriptProps, cn, commerce helpers | | @fadymondy/nasaq/theme-script.js | The no-flash theme script as a static file, for strict CSPs | | @fadymondy/nasaq/tokens | Typed token values (colour, space, type, density, contrast helpers) | | @fadymondy/nasaq/brands | Brand manifests, mark specs, markSvg() | | @fadymondy/nasaq/native | React Native kit (StyleSheet, no styling runtime): provider, Text, Button, Screen, ProductMark | | @fadymondy/nasaq/electron | Renderer title bar, drag regions, useWindowChrome() | | @fadymondy/nasaq/electron/main | Main process: windowChrome() window options, updateTitleBarOverlay() | | @fadymondy/nasaq/electron/preload | Preload: exposeChrome() | | @fadymondy/nasaq/tokens.css | Token CSS variables | | @fadymondy/nasaq/theme.css | Tailwind v4 @theme mapping | | @fadymondy/nasaq/web/styles.css | Web base styles | | @fadymondy/nasaq/electron/chrome.css | Electron drag-region CSS | | @fadymondy/nasaq/vue | Vue 3 components (NqButton, NqDialog, …) on Reka UI, NasaqProvider, the Nasaq plugin | | @fadymondy/nasaq/alpine | Alpine.js plugin that drives the HTML the Blade components render (nqDialog, nqTabs, …, $nq, x-nq-money) | | @fadymondy/nasaq/html | formatMoney and the locale helpers for plain JS | | @fadymondy/nasaq/nasaq.css | Precompiled stylesheet: tokens, theme and every component class. For apps without Tailwind | | @fadymondy/nasaq/nasaq.unlayered.css | The same without preflight or cascade layers, for Filament and Tailwind v3 hosts | | @fadymondy/nasaq/cdn/nasaq-alpine.js | Script-tag build of the Alpine plugin; registers itself on alpine:init |

ESM only, with TypeScript declarations. Heavy libraries (recharts, shiki, tiptap, xyflow, dnd-kit) are regular dependencies and are loaded only when the components that use them are imported; use a bundler that tree-shakes ESM (Next, Vite, esbuild, Rspack).

Not on React? Vue, Inertia, Laravel, Filament and plain HTML

Every stack renders the same markup with the same Tailwind classes, so a screen looks the same in all of them.

// Vue 3 / Nuxt (and Inertia + Vue)
import { Nasaq } from "@fadymondy/nasaq/vue";
createApp(App).use(Nasaq).mount("#app");   // <NqButton>, <NqDialog>, …
# Laravel, Livewire, Filament, TomatoPHP: <x-nq::button>, <x-nq::dialog>, …
composer require fadymondy/nasaq-php
php artisan vendor:publish --tag=nasaq-assets   # then @nasaqStyles @nasaqScripts, or ->plugin(NasaqPlugin::make())
<!-- Any page, no build step -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fadymondy/nasaq/dist/nasaq.css">
<script defer src="https://cdn.jsdelivr.net/npm/@fadymondy/nasaq/dist/cdn/nasaq-alpine.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js"></script>

Laravel + Inertia uses this package directly (React or Vue). The setup for every stack is on Get started, and each component page shows its code for React, shadcn, Vue, Blade and HTML + Alpine. The MCP server serves the same examples.

Prefer to own the code? Use the shadcn registry

The same components are published as a shadcn registry: files are copied into your app and depend only on Base UI, cva, clsx, tailwind-merge and lucide.

// components.json
{ "registries": { "@nasaq": "https://docs.nasaqui.com/r/{name}.json" } }
npx shadcn@latest add @nasaq/button

Index: https://docs.nasaqui.com/registry.json

MCP for AI assistants

@fadymondy/nasaq-mcp lets an assistant list components and read their manuals, source, stories and tokens.

npx -y @fadymondy/nasaq-mcp                      # stdio
# hosted (streamable HTTP): https://mcp.nasaqui.com/mcp

Links

  • Docs and lab: https://docs.nasaqui.com
  • Site: https://nasaqui.com
  • Source and issues: https://github.com/fadymondy/nasaq

Maintainers: publishing

The first publish of each package is done by hand (npm only lets you attach a trusted publisher to a package that exists); later releases are automated by .github/workflows/release.yml (changesets, OIDC provenance).

pnpm install --frozen-lockfile
pnpm typecheck && pnpm lint && pnpm test && pnpm check:components
pnpm check:package                 # build + publint + attw + use-client check
npm login
pnpm release                       # builds both packages, then `changeset publish` (publishes what is not on npm yet)
git push --follow-tags

MIT © Fady Mondy