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

@servicenow/eslint-plugin-aiux-app

v0.4.0

Published

ESLint rules for AIUX scoped app correctness and SDK/compiler contracts

Readme

@servicenow/eslint-plugin-aiux-app

ESLint rules for AIUX scoped-app correctness. Two families:

  1. SDK/compiler contracts — decorators and runtime APIs that the Now SDK and AIUX build extract statically from your source. The compiler reads these at build time, so a value the linter can't see is a value the build can't serialize. Catching them here turns a silent runtime miss into a build-time error. These rules only fire on APIs imported from @servicenow/aiux-components-core (or the @servicenow/karuna/aiux-components-core re-export) and Lit's lit/decorators.js, so unrelated local functions with the same names are never flagged.
  2. Glide API call conventions — how fetch / aiuxFetch calls to ServiceNow Glide APIs (/api/now, /api/sn_*, /api/x_*) must be written so SSR auth, tracing, batching, timeouts, and GraphQL error handling work. These rules classify the call by AST structure (URL shape, ctx.protocol/ctx.hostname construction, GraphQL endpoint) rather than by import source, and match the call by name (fetch, aiuxFetch, getHeaders, plus window.fetch / *.aiuxFetch).

Install

pnpm add -D @servicenow/eslint-plugin-aiux-app

Usage

import aiuxApp from '@servicenow/eslint-plugin-aiux-app';

export default [...aiuxApp.recommended];

The recommended config sets only the plugin + rules; your config must already parse decorators (e.g. @babel/eslint-parser with @babel/plugin-proposal-decorators). Or build your own from the rules export:

export default [
  {
    plugins: {'@servicenow/aiux-app': {rules: aiuxApp.rules}},
    rules: {
      '@servicenow/aiux-app/valid-decorators': 'error',
      '@servicenow/aiux-app/literal-requirements': 'error',
      '@servicenow/aiux-app/no-property-config-mix': 'error'
    }
  }
];

Rules

SDK / compiler contracts

| Rule | Severity | What it catches | | ------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | valid-decorators | error | AIUX SDK decorators with the wrong literal type (@discoverable('true')), out-of-range enum values (@category('system'), @protectionPolicy('write')), non-array @roles, misspelled/unknown decorators destructured from decorators, @customElement tag names missing a hyphen, @config on a non-property, and @externalConfig without a string key. | | literal-requirements | error | Non-string-literal arguments to getSystemProperty / isPluginActive / getUserPreference. The build plugin scans these call sites and prefetches the named value; a dynamic argument can't be extracted, so the value is silently absent at runtime. | | no-property-config-mix | error | A field decorated with both AIUX @config and Lit @property. @config fields must be internal state — a parent setting the attribute after mount conflicts with the constructor assignment. Use @state (or no Lit field decorator). | | no-page-imports | error | Importing a route page.[jt]s module as a shared dependency. Page modules are route entry points; move shared code to a non-route module and import that instead. |

These map to a contract the compiler enforces silently. The value either makes it into the manifest or it doesn't — there's no degraded middle state to warn about — so the failure mode is a feature that quietly doesn't work on the instance. Linting is the only place this surfaces before deploy.

Glide API call conventions

| Rule | Severity | What it catches | | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | graphql-requires-error-check | error | A fetch / aiuxFetch to /api/now/graphql whose enclosing function does not check the response body for errors after the call (a .errors access or a recognized helper such as resolveApiErrors). GraphQL can return HTTP 200 with errors in the body, so response.ok is not enough. Configure extra helper names via errorCheckHelpers. | | require-relative-aiux-fetch-url | error | An aiuxFetch to a Glide API built as an absolute or same-origin (${ctx.protocol}://${ctx.hostname}/api/...) URL. Use a relative /api/... URL so SSR can inject auth, tracing, batching, and timeouts. Relative URLs and non-Glide absolute URLs are allowed. | | no-manual-getheaders-with-aiux-fetch | error | Forwarding getHeaders(ctx) into an aiuxFetch headers option (inline, via a variable, or via a hoisted options object). aiuxFetch owns AIUX header/auth handling; pass only explicit headers like Content-Type. | | prefer-aiux-fetch-for-glide-api | warn | A raw fetch() to a Glide API that is GraphQL, or any non-relative (absolute / ${origin}-constructed / dynamic-prefix) Glide URL. Prefer aiuxFetch(). Plain relative REST (fetch('/api/now/table/...'), including dynamic table names and query params) is intentionally allowed. |

These classify the URL by AST structure, not by scanning the source text for keywords, so ordinary table/field names (cmdb_ci_database, a ?origin= query param) and comments never trigger a false positive.

Contract drift

valid-decorators hardcodes the AIUX decorator surface (names + enum value sets) for static analysis, but the source of truth is the decorators export in @servicenow/aiux-components-core. test/contract.invariant.test.js asserts the two stay in lockstep — if the SDK adds, removes, or renames a decorator and the rule isn't updated, that test fails (rather than the rule silently false-flagging a new decorator as unknownDecorator).