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

@abgov/nx-adsp

v13.33.3

Published

Government of Alberta - Nx plugin for ADSP apps.

Readme

@abgov/nx-adsp

Nx plugin for bootstrapping ADSP applications for the Government of Alberta.

The plugin provides generators for Node/Express services, React, Angular, and Vue 3 frontends, .NET services, and fullstack solutions. When @abgov/nx-oc is also installed in the workspace, OpenShift deployment YAML is automatically included in the generated output.

Prerequisites

Install only the framework peers for the generators you use — they are declared as optional peer dependencies, so a workspace that only builds Vue apps doesn't need @nx/react, @nx/angular, etc.

| Generator | Required peer dependency | | ---------------------------------------------------------------------------- | ------------------------------------------- | | react-app | @nx/react | | angular-app | @nx/angular | | vue-app | @nx/vue | | dotnet-service | @nx-dotnet/core | | react-dotnet | @nx/react, @nx-dotnet/core | | express-service | @nx/express | | pevn, mevn (full-stack) | @nx/express, @nx/vue | | pern, pean (full-stack) | @nx/express, @nx/react/@nx/angular | | react-form, react-task-list | existing React project in the workspace | | vue-detail-view, vue-workspace-view, vue-admin-crud, vue-intake-view | existing vue-app project in the workspace |

Installation

npm i -D @abgov/nx-adsp

Quick Start

# 1. Create a workspace
npx create-nx-workspace my-workspace

# 2. Install the plugin and any required peer dependencies
npm i -D @abgov/nx-adsp @nx/express

# 3. Set up nx-adsp's own workspace-root concerns (ADSP SDK MCP server, VS Code
#    settings) — always run this right after installing the plugin. Every
#    app/service generator below also runs it as one of its own steps, but
#    running it here means grounded ADSP platform knowledge is available
#    immediately, not only once you've scaffolded your first app.
npx nx g @abgov/nx-adsp:init

# 4. Generate a quickstart (interactive prompts fill missing options)
npx nx g @abgov/nx-adsp:express-service my-service --env dev --tenant my-tenant

Full-stack quickstart (PEVN → sandbox)

This is the end-to-end path a coding agent can follow from an empty folder to a running full-stack app in an OpenShift sandbox. The plugins require Nx 23, which create-nx-workspace@latest produces by default.

Prerequisites for the sandbox deploy (steps 4–5): podman (machine started on macOS), oc logged in to the sandbox cluster, and the GitHub CLI (gh) authenticated as an account with write:packages on your registry org.

Coding agents: run generators with --no-interactive and every required option (name, --env, --sandboxProject, etc.) supplied — otherwise Nx prompts and your session hangs waiting for input. Setting CI=true in the env has the same effect and also skips the Nx Cloud prompt. (nx run <target> executors don't prompt — this only applies to nx g generators.) Also pass --skipAgent — see Agent consultation for why you want to, not just how. The commands below already follow this.

# 1. Empty folder → Nx workspace (the plugins require Nx 23)
npx create-nx-workspace@latest my-solution --preset=apps --workspaceType=integrated --nxCloud=skip --no-interactive
cd my-solution

# 2. Install the plugins + stack peers (match @nx/* to the workspace nx version)
NXV=$(node -p "require('./node_modules/nx/package.json').version")
npm i -D @abgov/nx-oc @abgov/nx-adsp "@nx/express@$NXV" "@nx/vue@$NXV" "@nx/node@$NXV" "@nx/js@$NXV" "@nx/eslint@$NXV"

# 3. Sign in to ADSP once (opens a browser; token is cached for later generator runs)
npx @abgov/adsp-cli login --env test --tenant "<Your Tenant>" --scope adsp-cli-admin

# 4. Scaffold a Postgres + Express + Vue + Node solution
npx nx g @abgov/nx-adsp:pevn acme --env=dev --tenant=my-tenant --no-interactive --skipAgent

# 5. Add sandbox targets (registry derives from the git remote, or pass --registry=ghcr.io/<org>;
#    the database is auto-detected from the service — no --database needed)
npx nx g @abgov/nx-oc:sandbox acme-service --sandboxProject=<namespace> --registry=ghcr.io/<org> --tenant=my-tenant --env=dev --no-interactive
npx nx g @abgov/nx-oc:sandbox acme-app --sandboxProject=<namespace> --tenant=my-tenant --env=dev --no-interactive

# 6. Deploy — backend first so the frontend's /api proxy resolves
npx nx run acme-service:sandbox
npx nx run acme-app:sandbox            # or: --deployBackend to bring the backend up in the same run

Each generated app has an AGENTS.md (framework + ADSP context) and, once step 5 runs, a .openshift/<app>/SANDBOX.md deploy/troubleshooting runbook. See @abgov/nx-oc for the sandbox deploy details.

Generators

init

Sets up nx-adsp's own workspace-root concerns: installs the ADSP SDK MCP server (@abgov/adsp-sdk-mcp-server) as a dev dependency and registers it in .mcp.json, and shared VS Code settings. Every app/service generator below already runs this as one of its own steps — always run it directly right after installing the plugin, too, so grounded ADSP platform knowledge (tenant/realm/role model, @abgov/adsp-service-sdk reference) is available immediately, not only once you've scaffolded your first app. That gap matters for a decision made before any app exists — a design pass, for instance — which a scaffolding-generator side effect can never reach in time.

npx nx g @abgov/nx-adsp:init

No options. Idempotent — merges into existing .mcp.json/.vscode/settings.json without clobbering another server, a customized adsp-sdk entry, a version you've pinned yourself, or unrelated settings; safe to re-run. Project-scoped MCP servers only load at session start, so install dependencies and then reconnect (or restart) your MCP client after running this before relying on the new tools — the generator's own output says so as a reminder.

The server is a dev dependency rather than an on-demand npx -y fetch so that the version your agent executes is the one your lockfile resolved and npm audit can see — along with its transitive dependencies. The .mcp.json entry uses npx --no, which prefers the local install over anything in npm's _npx cache, and refuses to reach the registry for a version you haven't installed. Plain npx would fetch and run one silently, because npm assumes --yes whenever stdin isn't a TTY, as it never is for a stdio MCP server.

One caveat worth knowing: --no treats an already-populated _npx cache entry as satisfying the request, so on a machine that previously ran the npx -y form it will use that cached copy rather than erroring. Run npm install before relying on the pin — with the dependency present, the local copy always wins.


express-service

Creates a Node/Express backend service configured for ADSP.

npx nx g @abgov/nx-adsp:express-service my-service --env dev --tenant my-tenant

| Option | Alias | Required | Description | | ------------- | ----- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | — | Yes | Name of the service | | env | -e | No | ADSP environment / access service. Defaults to test = access-uat.alberta.ca (UAT — use for dev and pre-prod); prod = access.alberta.ca; dev = ADSP platform dev (restricted) | | tenant | -t | No | ADSP tenant name; resolves the Keycloak realm by name (sign in once with @abgov/adsp-cli — see Authentication) | | tenantRealm | -tr | No | Keycloak realm UUID; overrides the realm resolved from --tenant | | accessToken | -at | No | Access token for non-interactive retrieval of ADSP configuration |

OpenAPI docs are generated from the same Zod schemas already used for request validation (@asteasolutions/zod-to-openapi) and served at /swagger/docs/v1 — no separate spec to hand-maintain. The root / endpoint's _links.docs points at it, which is what ADSP's directory service polls to aggregate the service's API docs into https://api.adsp.alberta.ca/{tenant} (once the service has a directory entry — a one-time setup step outside this generator).


react-app

Creates a React/Redux frontend application configured for ADSP. Requires @nx/react.

npx nx g @abgov/nx-adsp:react-app my-app --env dev --tenant my-tenant

| Option | Alias | Required | Description | | --------------- | ----- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | — | Yes | Name of the application | | env | -e | No | ADSP environment / access service. Defaults to test = access-uat.alberta.ca (UAT — use for dev and pre-prod); prod = access.alberta.ca; dev = ADSP platform dev (restricted) | | tenant | -t | No | ADSP tenant name; resolves the Keycloak realm by name (sign in once with @abgov/adsp-cli — see Authentication) | | tenantRealm | -tr | No | Keycloak realm UUID; overrides the realm resolved from --tenant | | accessToken | -at | No | Access token for non-interactive retrieval of ADSP configuration | | pairedProject | — | No | Name of an existing backend service project to derive the nginx/dev-server proxy and the adsp:proxy-service: sandbox tag from automatically — the project must already exist | | proxy | — | No | Nginx proxy rule(s) as { location, proxyPass } or an array of such objects — additional entries --pairedProject doesn't cover; can't duplicate its location |

Running this generator standalone against a backend that's already scaffolded? Pass --pairedProject <backend-project-name> instead of hand-computing --proxy — it derives the same http://<name>:3333/<name>/ convention pevn/pern/pean/mevn already use internally, plus the tag @abgov/nx-oc:sandbox needs to pre-create the backend's Service.

The generated Playwright e2e project includes an axe-core accessibility check (a11y.spec.ts), scoped to WCAG 2.1 A/AA, that runs automatically as part of the e2e target — no separate command needed. angular-app and vue-app include the same check.

Its coverage is the ROUTES array inside that spec, which ships as ['/'] — the only route a freshly generated app has. Add to it as the app gains routes, from a generator or by hand; no generator maintains the list, and / is mostly app shell, so it exercises little of what the app is actually built from. Expect genuine failures once expanded: some come from inside @abgov/web-components' shadow DOM and need an upstream fix rather than an app-side change.


angular-app

Creates an Angular frontend application configured for ADSP. Requires @nx/angular.

npx nx g @abgov/nx-adsp:angular-app my-app --env dev --tenant my-tenant

Accepts the same options as react-app.


vue-app

Creates a Vue 3 frontend application configured for ADSP, using GoA web components (@abgov/web-components) and @dsb-norge/vue-keycloak-js for authentication. Requires @nx/vue.

npx nx g @abgov/nx-adsp:vue-app my-app --env dev --tenant my-tenant

Accepts the same options as react-app, plus:

| Option | Required | Description | | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | layout | No | Top-level app shell: header (default) is a goa-app-header + hero banner + footer (public-facing); internal is a goa-work-side-menu shell with no header/banner/footer (staff-facing). Pair two runs against the same --pairedProject for a public+internal frontend pairing over one backend |

Every generated app provisions a shared vue-components library — Goab* v-model wrappers over the design system plus reusable app-shell pattern components (AppLayout, AppHeader, AppFooter, AppSideMenu, SessionExpiredBanner) — see the generated app's own AGENTS.md for the full contract. Four more generators retrofit common view shapes into an existing vue-app project; see below.


dotnet-service

Creates an ASP.NET Core backend service configured for ADSP. Requires @nx-dotnet/core.

npx nx g @abgov/nx-adsp:dotnet-service my-service --env dev --accessToken $TOKEN

| Option | Alias | Required | Description | | ------------- | ----- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | name | — | Yes | Name of the service | | env | -e | No | ADSP environment / access service. Defaults to test = access-uat.alberta.ca (UAT — use for dev and pre-prod); prod = access.alberta.ca; dev = ADSP platform dev (restricted) | | accessToken | -at | No | Access token for non-interactive retrieval of ADSP configuration |


react-dotnet

Composite generator that creates both a React frontend and a .NET backend as a fullstack solution. Requires @nx/react and @nx-dotnet/core.

npx nx g @abgov/nx-adsp:react-dotnet my-solution --env dev

Accepts the same options as dotnet-service.


react-form

Adds a React component generated from an existing ADSP Form Definition to an existing project. The generator fetches form definitions from the ADSP Form service for the target environment.

npx nx g @abgov/nx-adsp:react-form my-app --env test

| Option | Alias | Required | Description | | ------------- | ----- | -------- | ------------------------------------------------------------------------------------------------- | | project | — | Yes | Name of the existing Nx project to add the form component to | | env | -e | No | ADSP environment to fetch form definitions from. Defaults to test (UAT / access-uat.alberta.ca) | | accessToken | -at | No | Access token for non-interactive retrieval of ADSP configuration |


react-task-list

Adds a React task list component driven by an ADSP Task Queue to an existing project.

npx nx g @abgov/nx-adsp:react-task-list my-app --env test

Accepts the same options as react-form.


vue-detail-view

Adds a record-detail view (loading/error/loaded states, optional status badge, back button) to an existing vue-app project, built on the shared RecordDetailShell pattern component.

npx nx g @abgov/nx-adsp:vue-detail-view my-app --name=application-detail --resource=applications --route=/applications/:id --fields='[{"key":"status","label":"Status","type":"badge"}]'

| Option | Required | Description | | -------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | project | Yes | The vue-app project to add the view to | | name | Yes | View name, e.g. application-detail generates src/views/ApplicationDetailView.vue | | resource | Yes | API resource path segment — the view fetches /api/v1/<resource>/:id | | route | Yes | Route path added to router/index.ts, e.g. /applications/:id. Must contain a :id param | | fields | Yes | JSON array of fields rendered in the record's info list, in display order: { key, label, type?: "text"\|"date"\|"currency"\|"badge" } — a JSON string, not a comma-separated CLI array (see note below) | | heading | No | Page heading. Defaults to the view name, title-cased | | requiresAuth | No | Whether the generated route requires authentication. Defaults to true |


vue-workspace-view

Adds a staff-facing, paginated list view (a debounced search filter bar + sortable columns) to an existing vue-app project, built on the shared WorkspaceTable pattern component.

npx nx g @abgov/nx-adsp:vue-workspace-view my-app --name=applications --resource=applications --route=/applications --detailRoute=/applications --columns='[{"key":"status","label":"Status","type":"badge","sortable":true}]'

| Option | Required | Description | | -------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | project | Yes | The vue-app project to add the view to | | name | Yes | View name, e.g. applications generates src/views/ApplicationsListView.vue | | resource | Yes | API resource path segment — fetches /api/v1/<resource>?page=&limit=&search=&sortBy=&sortDir= | | route | Yes | Route path added to router/index.ts, e.g. /applications | | columns | Yes | JSON array of table columns, in display order: { key, label, type?: "text"\|"date"\|"currency"\|"badge", sortable?, options?: [{value,label}], badgeMap?: {value: badgeType} } — supply options for any column stored as a code (or the table shows the code), and badgeMap on a badge column to give each status its colour — a JSON string (see note below) | | detailRoute | No | If set, each row gets a "View" action linking to `${detailRoute}/${row.id}` — typically a vue-detail-view's route with the :id segment dropped | | filterable | No | Whether to generate a debounced search input above the table. Defaults to true | | heading | No | Page heading. Defaults to the view name, title-cased | | pageSize | No | Rows per page. Defaults to 20 | | icon | No | Ionicon name for the generated side-menu entry. Defaults to list. goa-work-side-menu-item renders a blank item without one | | requiresAuth | No | Whether the generated route requires authentication. Defaults to true |


vue-admin-crud

Adds a simple admin CRUD screen pair (a WorkspaceTable list view with a Create action and per-row Edit, plus a create/update Edit view) to an existing vue-app project — suited to small lookup-table style admin screens, not large paginated workspaces (see vue-workspace-view for that).

npx nx g @abgov/nx-adsp:vue-admin-crud my-app --name=regions --resource=regions --route=/regions --fields='[{"key":"name","label":"Name"},{"key":"active","label":"Active","type":"checkbox"}]'

| Option | Required | Description | | --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | project | Yes | The vue-app project to add the views to | | name | Yes | View name, e.g. regions generates src/views/RegionsListView.vue and src/views/RegionsEditView.vue | | resource | Yes | API resource path segment — fetches /api/v1/<resource> (list), /api/v1/<resource>/:id (load one), POST /api/v1/<resource> (create), PUT /api/v1/<resource>/:id (update) | | route | Yes | List route path added to router/index.ts, e.g. /regions. The edit/create route is added as `${route}/:id` (visiting ${route}/new creates) | | fields | Yes | JSON array of fields, in display/form order: { key, label, type?: "text"\|"checkbox", required? } — a JSON string (see note below) | | heading | No | List page heading. Defaults to the view name, title-cased | | singularLabel | No | Singular label used in "Create "/"Edit " headings and buttons. Defaults to --heading (override for irregular plurals) | | icon | No | Ionicon name for the generated side-menu entry. Defaults to settings. goa-work-side-menu-item renders a blank item without one | | requiresAuth | No | Whether the generated routes require authentication. Defaults to true |


vue-intake-view

Adds a route-per-step intake wizard (Stepper + StepErrorSummary, a required read-only review step, and a confirmation page) to an existing vue-app project. Cross-step state is server-persisted — each step PUTs/POSTs to /api/v1/<resource>/:id and refetches on mount, so there's no client-side draft caching. Every field is currently a plain text input.

npx nx g @abgov/nx-adsp:vue-intake-view my-app --name=application --resource=applications --route=/applications --steps='[{"key":"personal-info","label":"Personal information","fields":[{"key":"fullName","label":"Full name"}]}]'

| Option | Required | Description | | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | project | Yes | The vue-app project to add the views to | | name | Yes | Base name for the generated views, e.g. application generates <Step>StepView.vue per step plus ApplicationReviewView.vue/ApplicationConfirmationView.vue | | resource | Yes | API resource path segment. Each step fetches/saves /api/v1/<resource>/:id; the review step's Submit posts /api/v1/<resource>/:id/submit | | route | Yes | Base route, e.g. /applications. Steps become /applications/:id/<step-key>, plus /review and /confirmation. Start a new intake at /applications/new/<first-step-key> | | steps | Yes | JSON array of steps, in order: { key, label, fields: [{ key, label, required? }] } — a JSON string (see note below) | | referenceField | No | Field on the submitted record holding the business reference shown on the confirmation page. Defaults to reference; falls back to the route id when absent | | requiresAuth | No | Whether the generated routes require authentication. Defaults to true |


Note on JSON-string options (fields/columns/steps): Nx's own CLI arg coercion only supports comma-separated primitive lists for array-typed schema options, not JSON — a JSON string is the only CLI syntax that survives it, so these options are declared as string and parsed internally. A plain array also works when the generator is invoked programmatically (e.g. from a script), bypassing CLI parsing entirely.

Authentication

Most generators call ADSP APIs during generation, which needs an ADSP access token. Sign-in is delegated to @abgov/adsp-cli — log in once (interactive browser) and its cached token is reused across generator runs. There's no separate login built into this plugin.

# Sign in once. --scope adsp-cli-admin grants the Keycloak-admin capability some
# generators use to provision a service's OAuth client (safe to request without it).
npx @abgov/adsp-cli login --env <dev|test|prod> --tenant "<Your Tenant>" --scope adsp-cli-admin

When you run a generator:

  • if a valid cached token exists, generation proceeds with no prompt;
  • if ADSP_CLIENT_ID/ADSP_CLIENT_SECRET are set (a CI service account — requires @abgov/adsp-cli ^1.7.0+ and the tenant's adsp-cli-ci Keycloak client enabled with credentials generated), a fresh token is acquired non-interactively via that account, no browser and no prior adsp login needed;
  • otherwise, an interactive run launches adsp login for you (browser); a non-interactive run (--no-interactive / CI) fails with the exact adsp login command to run first, or the two env vars above to set instead.

Generator flags that steer which tenant/token is used:

| Flag | Effect | | ----------------------- | ----------------------------------------------------------------------------------- | | --tenant <name> | Resolves the Keycloak realm by tenant name (anonymous lookup) and targets it | | --tenantRealm <uuid> | Use the realm UUID directly; combine with --tenant to override the resolved realm | | --accessToken <token> | Supply a pre-obtained token directly (CI/CD), bypassing the CLI |

With none of these, the generator lets adsp login's interactive picker resolve the tenant. Don't have a tenant yet? That picker also offers a + Create a new tenant choice — available in dev/test (never prod), for an account whose core-realm roles include beta-tester or tenant-service-admin, and (unless tenant-service-admin) that doesn't already own a tenant (one per admin email). Picking it prompts for a name and waits for the new realm to finish provisioning before continuing the login as that tenant. Requires @abgov/adsp-cli ^1.4.0+ (this plugin pins ^1.7.0 or later).

Agent consultation

express-service, react-app, angular-app, vue-app, and the fullstack composites connect to ADSP's own agent-service after base scaffolding and hold an interactive, multi-turn conversation with an ADSP-aware agent that can read and modify key integration files (main.ts, environment.ts, events.ts, database.ts) based on a description you provide. The socket connection and file upload start immediately, in parallel with prompting for that description.

This needs the same tenant/token as Authentication above, plus a reachable agent-service — it falls back silently to base scaffolding if either is missing, or if the run is non-interactive (--no-interactive, no TTY, or CI=true). Skip it explicitly with --skipAgent, regardless of interactivity.

Note for coding agents: skip this. It exists to let a human describe what they want built to a separate, remote agent working from nothing but that description. You already have the actual requirements and the surrounding codebase context that conversation exists to gather — make any needed customizations directly, after scaffolding, rather than through an indirect round-trip to a second, less-informed agent. Pass --skipAgent explicitly rather than relying on --no-interactive alone: --skipAgent is a plain option check at the generator level, while --no-interactive's detection is built on argv inspection this plugin's own code notes could go stale on an Nx upgrade — belt and suspenders, not a real behavior difference today.

nx-oc integration

If @abgov/nx-oc is installed in the workspace, the quickstart generators (express-service, react-app, angular-app, dotnet-service, react-dotnet) automatically include OpenShift deployment YAML in their output. See the @abgov/nx-oc README for details.

Local development

To test the plugin locally against a workspace:

# 1. Build the plugin
nx run nx-adsp:build

# 2. In a separate test workspace, install from the build output
npm i -D /path/to/nx-tools/dist/packages/nx-adsp

# 3. Run a generator
npx nx g @abgov/nx-adsp:express-service my-service --tenant my-tenant-realm-uuid

To add a new generator to this plugin:

nx g @nx/plugin:generator [generatorName] --project nx-adsp