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

spannercg

v0.1.5

Published

Code intelligence and knowledge graph for any codebase, served from Google Cloud Spanner — shared, compiler-accurate code context for AI agents over MCP.

Readme

spannercg

One shared code graph for your whole team, served from Google Cloud Spanner. The platform team indexes each repo once and publishes its graph to a shared Spanner instance. Every engineer's AI agent then reads that same graph: no local indexing, no per-repo setup. Ask how something works and get the exact source, the call paths, and the blast radius in one call, for repos you cloned and repos you never did.

Table of contents

The two roles

SpannerCG serves one shared code graph to a whole team. Which commands you run depends on which side of that graph you're on:

| | Platform team: runs the graph | Individual engineer: uses the graph | |---|---|---| | Goal | Onboard repos and keep their graphs fresh on the shared instance. | Get accurate answers in your agent about any onboarded repo. | | One-time setup | spannercg setup provisions or verifies the instance. | spannercg connect saves the connection settings and configures your agents. | | Per repo | census, then index to publish; sync to keep fresh. | Nothing. Open the repo; your agent attaches automatically. | | Indexing | Yes, with a SCIP artifact for compiler-verified references. | Never. Reads the published graph. | | What's committed | A small spannercg.json: the repo ID and exclude patterns, never cloud coordinates. | Nothing. You clone what the platform team set up. | | Main commands | setup, census, index, sync, repos, status --dashboard, drop-repo | connect, then repos to browse. Your agent does the rest. |

Get started

Every step is one command plus what you should see.

Install the CLI (everyone)

SpannerCG runs on Node.js 22.5 through 24. Node.js 25 is not supported.

  1. Check your Node.js version:

    node --version

    If the version is below 22.5, or is 25 or later, install Node.js 22 LTS:

    nvm install 22 && nvm use 22

    With Homebrew, run brew install node@22 && brew link --overwrite --force node@22 instead.

  2. Install the CLI:

    npm i -g spannercg
  3. Confirm that it resolves:

    spannercg --version

Connect as an individual engineer

Your platform team has onboarded the repos. Your whole setup is one command.

  1. Sign in to Google Cloud, then connect this machine. Get the project, instance, and registry database names from your platform team, who also grants you the roles/spanner.databaseReader role on the instance:

    gcloud auth application-default login
    spannercg connect

    The output is similar to the following. Your answers follow the marks:

    ┌  Connect this machine to your team's remote codebase knowledge
    │
    ◆  Google Cloud project id
    │  acme-prod
    │
    ◆  Spanner instance id
    │  spanner-code-knowledge
    │
    ◆  Registry database name
    │  spannercg-reg
    │
    ◇  Checking Google Cloud credentials…
    ◇  Checking access to the remote codebase knowledge…
    │
    ●  Connected — 12 repositories are served from this instance.
    ●  Saved to ~/.config/spannercg/config.json. Repos that commit a "repoId" now attach automatically.
    │
    ◆  Add the spannercg server to your coding agents now?
    │  Yes
    │
    └  Done — open any onboarded repo in your agent and just ask.
  2. Open an onboarded repo in your coding agent's workspace (Claude Code, Cursor, and others), and ask:

    "How does a payment request reach the database?"

    The answer quotes the relevant source, the call paths between the symbols, and what depends on them. In a repo that isn't onboarded, the agent falls back to its built-in tools.

  3. Ask about repos you haven't cloned. List what the instance serves:

    spannercg repos

    The output is similar to the following:

    Repos on instance spanner-code-knowledge:
    
      acme/payments-service · 6787b7c5 · java, python
      acme/checkout-web · 9f8e7d6c · typescript
      acme/inventory · 55aa01b2 · go

    Name any of them in your question:

    "In acme/inventory, how does a stock reservation get released when an order is cancelled?"

    You get the same kind of answer, for a repo you never checked out. If your agent uses its generic tools instead, say "use spannercg" once.

Note: That's the whole engineer setup. For agent configuration details, questions across repos, code search in the dashboard, and troubleshooting, see the detailed guide: Use SpannerCG with your AI agent.

Onboard repos as the platform team

  1. Provision the shared instance once. SpannerCG runs on a Spanner Enterprise edition instance that autoscales between 1 and 3 nodes:

    gcloud auth application-default login
    spannercg setup

    The output is similar to the following. Your answers follow the marks:

    ┌  spannercg setup
    │
    ◆  What do you want to do?
    │  Provision or manage the shared instance
    │
    ◇  Checking gcloud credentials…
    ●  Signed in as [email protected]
    │
    ◆  GCP project
    │  acme-prod
    │
    ◆  Spanner instance
    │  Create "spanner-code-knowledge"   (Enterprise · autoscales 1–3 nodes · recommended)
    │
    ◆  Region config
    │  regional-us-central1
    │
    ◆  Create "spanner-code-knowledge" in acme-prod (regional-us-central1)?
    │  Yes
    │
    ◇  Creating "spanner-code-knowledge"…
    ●  Created "spanner-code-knowledge" ✓
    │
    ◆  Configuration complete — Saved to ~/.config/spannercg/config.json
    │
    └  Ready. Onboard a repo:  cd <repo> && spannercg census  then  spannercg index --scip <artifact>
  2. Scope the corpus before you index. census classifies the repo's files and excludes the test fixtures that would degrade answer accuracy:

    cd your-project
    spannercg census

    The output is similar to the following:

    Backend: instance spanner-code-knowledge   (machine config from setup)
    Census — ~/code/payments-service
      1,482 indexable files · 1,210 code · 214 fixtures · 58 generated
    
      language        files            SCIP
      java              861  ████████░░░░  → scip-java
      python            621  █████░░░░░░░  → scip-python
    
    Recommended excludes (written to spannercg.json)
      **/__fixtures__/           −214   test fixtures — snippet/data files that poison name resolution
    
    To be indexed — 1,268 files across these directories (top 3)
      src                                    1,102
      scripts                                  108
      tools                                     58
    
    ✓ Added 1 exclude pattern to spannercg.json
  3. Build the graph and publish it. Use SCIP indexes from your CI build; they make symbol references compiler-exact. Pass one --scip per compiler toolchain:

    spannercg index --scip ci-artifacts/scip-java.scip --scip ci-artifacts/scip-python.scip

    The output is similar to the following:

    ℹ Backend: instance spanner-code-knowledge · project acme-prod   (machine config from setup)
    ◆  Publish this repo's codebase knowledge as "acme/payments-service" (database cg-acme-payments-service)?
    │  Yes
    │
    ●  Bound — repoId written to spannercg.json (commit it; corpus settings kept, no cloud coordinates stored)
    ℹ Corpus: excludes from spannercg.json (**/__fixtures__/)
    ┌  Building codebase knowledge
    │
    ◆  Indexed 1,268 files
    │
    ●  18,450 symbols, 61,204 relationships in 24s
    │
    ◆  Remote codebase knowledge: updated 1,268 files (0 unchanged) in 41s
    │
    ◆  Symbol catalog: recorded 1,268 files (0 unchanged) in 6s
    │
    └  Done

    Note: spannercg index also works without --scip; symbol references then resolve by best-effort name matching until you add an artifact. To produce the artifacts, see SCIP build recipes.

  4. Commit the repo ID that index wrote. The committed ID is how engineers get access: when they ask questions in a clone, their coding agent reads it to find the repo's knowledge on the shared instance. The file carries only the repo's name and your corpus settings, never a project, instance, or database name:

    git add spannercg.json && git commit -m "spannercg: onboard to shared graph"

    Repeat census and index for each repo. They all share the one instance, and engineers reach any of them by name.

  5. Keep it fresh. After changes merge, sync transfers only the changed files:

    spannercg sync

    The output is similar to the following:

    ┌  Syncing codebase knowledge
    │
    ◆  Synced 3 changed files
    │
    ●  3 modified — 41 symbols updated in 1.2s
    │
    └  Done
  6. See the instance. List what's indexed:

    spannercg repos

    The output is similar to the following:

    Repos on instance spanner-code-knowledge:
    
      acme/payments-service · 6787b7c5 · java, python
      acme/checkout-web · 9f8e7d6c · typescript
      acme/inventory · 55aa01b2 · go

    To watch it live instead, start the dashboard:

    spannercg status --dashboard

    The output is SpannerCG status dashboard is live at http://127.0.0.1:7317/. The page refreshes itself:

  7. Remove a repo when its graph is no longer needed:

    spannercg drop-repo acme/payments-service

    The command shows what it will delete and asks you to type the repo ID to confirm. Pass --yes in scripts. The output is similar to the following:

    ┌  Deleting the remote codebase knowledge for "acme/payments-service"
    │
    ◇  This deletes ────────────────────────────────────────────────╮
    │                                                               │
    │  graph database   cg-acme-payments-service                    │
    │  registry rows    1,268 files · 18,450 defs · 61,204 refs     │
    │  last indexed     6787b7c5fb4b                                │
    │  local spannercg.json keeps its repoId and excludes —         │
    │  a re-index reuses them                                       │
    │                                                               │
    │  Attached readers lose access until the repo is re-indexed.   │
    │                                                               │
    ├───────────────────────────────────────────────────────────────╯
    │
    ●  registry: repo record removed
    │
    ●  graph: database cg-acme-payments-service dropped
    │
    ◆  Kept your corpus settings (1 exclude pattern) — a re-index will use them.
    │
    └  Re-index anytime:  spannercg index

Note: These six steps cover one repo's happy path. For syncing from CI, dropping and re-adding repos, monitoring, and troubleshooting, see the detailed guide: Manage repos on the shared instance.

Configure your agents

spannercg connect offers this step at the end. To run it separately:

spannercg install

The installer lists the detected agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity, and Kiro — and marks each one configured. Restart your agent session afterward; agents read MCP configuration at session start.

To confirm that it works, ask your agent a "how does X work?" question and check that it calls spannercg_explore. One call should answer it.

To remove the server from every agent it was installed into:

spannercg uninstall

Project graphs and your machine configuration are left untouched. To remove the CLI itself, run npm uninstall -g spannercg.

Documentation

The quick start above covers the main path. The guides cover the rest:

Language support

Every supported language gets the same treatment: full structural extraction and cross-file resolution into one graph, with no per-language setup.

TypeScript · JavaScript · ArkTS · Python · Go · Rust · Java · C# · VB.NET · PHP · Ruby · C · C++ · CUDA · Objective-C · Metal · Swift · Kotlin · Scala · Dart · Lua · Luau · R · Nix · Erlang · CFML · COBOL · Solidity · Terraform/OpenTofu · Svelte · Vue · Astro · Liquid · Pascal/Delphi

Compiler-verified accuracy through --scip is available for TypeScript/JavaScript, Python, Java, Kotlin, C#, Go, Rust, Ruby, and C/C++. Every other language indexes with best-effort reference resolution.

Multi-language repos index into one graph across all their languages. Pass a separate SCIP artifact per language, such as spannercg index --scip scip-java.scip --scip scip-python.scip, so each language gets compiler-verified accuracy.

License

Licensed under the Apache License 2.0.

SpannerCG is based on and derived from CodeGraph by Colby Mchenry, originally released under the MIT License. That original license is retained in the NOTICE file.