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

notiqo

v0.2.4

Published

Notiqo CLI - scan repositories and generate analytics tracking plans

Readme

Notiqo CLI

notiqo scans a source repository, finds the analytics events it already sends (Mixpanel, Amplitude, Segment, Firebase, PostHog, custom wrappers) and turns them into a tagging guide that Notiqo can import. It is deterministic, runs offline and fits in a CI job.

What it does — and what it does not

  • Does: detect tracked events and their parameters from code, flag naming issues, suggest missing events and funnels from industry templates, write tracking-plan.md / tracking-plan.json / notiqo-guide.json, and push the guide into a Notiqo project through the same backend as @notiqo/mcp.
  • Does not: call any LLM. For AI-assisted guides (business context, event definitions, measurement goals) use @notiqo/mcp from Claude Code or Codex. The CLI covers what an agent does not do well repeatably: sweeping large repositories and running in CI.

Quick start

npx notiqo scan .

That writes tracking-plan.md next to your code. To get the guide Notiqo imports and preview the import without writing anything:

npx -y @notiqo/mcp login <project-id>    # paste the token from Notiqo → Integrate → CLI token
npx notiqo scan . --format guide --only-existing --push --project <project-id>

Add --yes to apply the plan. Without --yes a push is always a dry-run.

Requires Node.js 20 or newer.

Commands and options

notiqo scan [path] [options]

| Option | Description | Default | |--------|-------------|---------| | --format <md\|json\|guide\|both> | Files to write: md, json, guide (notiqo-guide.json) or both (all three) | md | | --only-existing | Emit only events detected in code, no suggestions (recommended for --push and CI) | false | | --app-type <type> | Force the app type used for suggestions and funnels: ecommerce, saas, fintech, edtech, social, marketplace, content, telecom | auto-detect | | --push | Plan the import of the guide into a Notiqo project (dry-run unless --yes) | false | | --project <id> | Target Notiqo project (or NOTIQO_PROJECT_ID / .notiqo/config.json) | — | | --yes | Apply the planned operations instead of only printing them | false | | --json | With --push: print the plan as JSON on stdout; exit 1 if the planner reports issues | false | | --token <token> | Notiqo token ntq_live_… (prefer login locally or NOTIQO_TOKEN in CI) | — |

Environment variables

| Variable | Purpose | |----------|---------| | NOTIQO_TOKEN | Token created in Notiqo → Integrate → CLI token. Overrides the token saved by login; an empty value or a literal ${NOTIQO_TOKEN} is ignored. Never commit it. | | NOTIQO_PROJECT_ID | Default target project for --push. | | NOTIQO_URL | Override the Notiqo Edge Functions base URL (local or staging). |

The project id can also live in the scanned repository as .notiqo/config.json:

{ "projectId": "00000000-0000-4000-8000-000000000000" }

Getting a token

  1. Open your Notiqo workspace → Integrate (in the sidebar) → CLI token.
  2. Click Create CLI token; it starts with ntq_live_ and is shown once.
  3. On your machine, run npx -y @notiqo/mcp login <project-id> (the dialog shows it with your project filled in) and paste the token. It is checked against Notiqo and saved in ~/.notiqo/credentials.json, which both this CLI and the Notiqo MCP server read; no restart of Claude Code or Codex is needed. In CI, store it as the NOTIQO_TOKEN secret instead.

The token is resolved in this order: --token, a real NOTIQO_TOKEN, then the token saved by login for the target project. It acts as you: it can only write to projects where you have an editing role.

Push: how the import works

--push reuses the flow of @notiqo/mcp's notiqo_import_guide:

  1. mcp-context reads the target project (events, params, funnels, metrics, naming rules).
  2. The guide is planned locally with the same Dart planner Notiqo's dashboard uses, and the dry-run report is printed: what will be created or updated, the GA4 dimension budget and what to review first.
  3. Only with --yes are the operations sent to mcp-apply. Events land as drafts with an import origin, so they can be reviewed in Notiqo.

Events detected in code are imported with status existing and a code reference (path:line). If the project does not have them yet, they are created as drafts and the planner reports it as an issue — that is expected on a first import.

Example

$ notiqo scan . --only-existing --push --project 1111-…

Notiqo Scan Results
===================
Detected framework:    react
Existing tracked events: 3
...
Planning import into Notiqo project 1111-… (dry-run; add --yes to apply)...

# Dry-run de importación
...
### notiqo_propose_event — 3 (3 de alta, 0 de actualización)
- + purchase
- + add_to_cart
- + coupon_applied
...
Dry-run only: 8 operation(s) planned, nothing written. Re-run with --yes to apply.

CI

A GitHub Actions job that fails when the scan finds events the plan does not know about, and applies the import on the default branch:

name: notiqo
on:
  pull_request:
  push:
    branches: [main]

jobs:
  tracking-plan:
    runs-on: ubuntu-latest
    env:
      NOTIQO_TOKEN: ${{ secrets.NOTIQO_TOKEN }}
      NOTIQO_PROJECT_ID: ${{ vars.NOTIQO_PROJECT_ID }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      # Dry-run on pull requests: the JSON plan is the job output.
      - if: github.event_name == 'pull_request'
        run: npx notiqo scan . --only-existing --push --json > notiqo-plan.json
      - if: github.event_name == 'pull_request'
        uses: actions/upload-artifact@v4
        with:
          name: notiqo-plan
          path: notiqo-plan.json
      # Apply on main.
      - if: github.ref == 'refs/heads/main'
        run: npx notiqo scan . --only-existing --push --yes

With --json stdout carries only { projectId, ops, issues, applied } and the scan summary goes to stderr. The exit code is 1 whenever issues is not empty, so review the artifact before treating a red job as a real problem.

Supported input

| Language / framework | Parsing | |----------------------|---------| | TypeScript, TSX, JavaScript, JSX (React, Next.js, Angular, Node) | tree-sitter AST, regex fallback for TS/TSX | | Dart (Flutter) | tree-sitter AST, regex fallback | | Python | tree-sitter AST | | Kotlin, Java (Android) | regex extractors |

Native tree-sitter grammars are optionalDependencies and are loaded only when a file of that language is scanned. If a grammar fails to install (no C++ toolchain, unsupported platform) the CLI still runs and warns that it is using the regex extractors for that language.

Detected SDK patterns:

| SDK | Patterns | |-----|----------| | Firebase | .logEvent(name: 'event'), FirebaseAnalytics.instance.logEvent(...) | | Mixpanel | mixpanel.track('event', {...}) | | Amplitude | amplitude.track('event', {...}) | | Segment | analytics.track('event', {...}) | | PostHog | posthog.capture('event', {...}) | | Custom | analytics.trackEvent(...), trackEvent(...), sendEvent(...) |

Output files

  • tracking-plan.md — human-readable: existing events, improvements, suggested events, funnels.
  • tracking-plan.json — the same plan as data.
  • notiqo-guide.json — the tagging guide, validated against the schema exported by @notiqo/mcp (@notiqo/mcp/schema.json). Events detected in code have status: "existing" and a codeRef; suggestions have status: "new"; params shared by three or more events become globalParams.

Examples of the markdown and JSON output live in docs/examples/.

Development

npm install
npm run build
npm test            # vitest
npm run scan -- test/fixtures/react-mixpanel

Layout:

src/
  api/notiqo-client.ts        HTTP client for mcp-context / mcp-apply
  cli/                        commander entry point and the scan command
  core/                       domain types, ports and the scan orchestrator
  scanner/                    tree-sitter factory, AST and regex extractors
  event-generator/            rule-based suggestions and naming checks
  funnel-detector/            industry funnel templates
  guide/                      TrackingPlan → guide, Dart planner, push flow
  tracking-plan/              markdown/JSON rendering and file writing
test/                         vitest suites and fixtures
docs/plans/                   design notes (Spanish)

License

MIT