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

@dev.fast/code-graph

v0.2.10

Published

Headless SCIP indexing for TypeScript, JavaScript/JSX, Go, Rust, and Python. This document describes the unpublished `0.2.0` package. The package stores its graph in SQLite and exposes refresh, daemon, editor, and call-tree interfaces.

Readme

@dev.fast/code-graph

Headless SCIP indexing for TypeScript, JavaScript/JSX, Go, Rust, and Python. This document describes the unpublished 0.2.0 package. The package stores its graph in SQLite and exposes refresh, daemon, editor, and call-tree interfaces.

Quick start

TypeScript/JavaScript and Python use package-owned SCIP indexers. Python also requires Python 3.10+ plus pip3 or pip from the active environment. Selected Go projects use scip-go plus go; selected Rust projects use a rust-analyzer build with the scip subcommand plus cargo and rustc. rust-src is optional, but its presence and identity are fingerprinted because it changes Rust output. Missing Go/Rust tools or required host prerequisites are reported once per discovered family and skipped by default. A failed project is also isolated from other projects in its language family, so every successfully completed project can still be published. Pass --require-indexers for strict CI behavior: missing prerequisites and failed projects both fail closed before the graph is published.

Each language planner separates discovered candidate files from documents the indexer is required to emit. Emitted candidate documents are ingested, while strict completeness checks only the language's active project universe. Go derives that universe from go list in the indexer environment; Rust requires Cargo target roots and accepts emitted crate-module documents. This keeps platform/build-tagged Go files and Rust files outside the crate module graph from becoming false incomplete-output failures. Plans identify an authoritative or coverage context and may add context-local environment overrides. Context precedence is deterministic: authoritative output wins, followed by coverage contexts in lexical label order.

Candidate files legitimately outside every required indexer context still appear in the graph. Tree-sitter extracts their standalone file, declaration, import, and structural facts without creating cross-file semantic edges. Every file records one of semantic, semantic-coverage-context, syntax-only, or none; refresh and per-indexer summaries report counts for each status.

Rust's authoritative context asks rust-analyzer for all Cargo features and targets through a generated scratch config. If that widened configuration is invalid for a workspace (for example, mutually exclusive features), indexing retries once with rust-analyzer's default Cargo settings and records the downgrade on the project summary. Unreferenced Rust files remain syntax-only.

Go adds coverage contexts only for target files omitted by the authoritative build context. Incremental review extraction uses the changed files as targets; full extraction considers all selected Go files but creates at most indexer.maxCoverageContexts coverage plans (default 2). Planning evaluates build expressions and filename constraints against Linux, Darwin, and Windows on amd64 and arm64, adding literal positive build tags through GOFLAGS. Unmatched or over-cap files remain syntax-only.

Authoritative documents and symbols win deterministic merge conflicts. Coverage documents only fill missing files; their declarations retain the context label, and references resolve in that context before falling back to authoritative symbols. File nodes and persisted SCIP symbol rows carry context provenance so incremental refresh can re-merge deterministically.

pnpm --filter @dev.fast/code-graph refresh
pnpm --filter @dev.fast/code-graph refresh -- --root /path/to/repo --languages python,go
pnpm --filter @dev.fast/code-graph refresh -- --languages all --require-indexers

The exact supported language list is typescript, javascript, go, rust, and python. --languages all enables discovery for all five. An indexer is probed and started only when matching selected files exist. Non-zero probes, indexer crashes, malformed output, empty output, and project timeouts are recorded as typed project failures in normal mode. Output from a failed process is never ingested. Zero declarations from nonempty successfully indexed sources remains a hard correctness failure. Individually unresolved relationships are counted but do not fail extraction.

An explicit family command is authoritative and never falls back to PATH. The public @dev.fast/code-graph/indexers entry point exposes source-driven repository inspection and tool status APIs.

Configuration

Pass a JSON file with --config, or set CODE_GRAPH_CONFIG to a file path or inline JSON:

{
  "indexer": {
    "projectConcurrency": 4,
    "ignorePaths": ["fixtures/archive", ".cache/generated"],
    "families": {
      "go": {
        "command": "scip-go",
        "args": [],
        "env": {}
      }
    }
  }
}

Configuration is strict. The root accepts only indexer; indexer accepts only projectConcurrency, ignorePaths, and families; each family accepts only command, args, and env. The default project concurrency is capped at four.

indexer.ignorePaths contains repository-relative paths. Each path excludes itself and every descendant from discovery, incremental scans, refresh watching, and staleness checks. Paths are normalized, deduplicated, and sorted; absolute paths, repository-root or escaping paths, globs, and negation are rejected. Built-in exclusions for .dev/code-graphs and .dev/software-maps always apply. CODE_GRAPH_CONFIG remains the sole configuration entry point.

Indexing model

One canonical registry owns each indexer family's launch, project identity, incremental scope, project markers, source extensions, and language profiles. TypeScript and JavaScript share the TypeScript family.

Built-in indexers implement the internal versioned ScipFamilyPlugin contract under src/scip/families/ and are installed by the static tuple in src/scip/installed.ts. A family plugin owns its language profiles, project planning, launch identity, and value-only ingest refinements. Tree-sitter syntax enrichment is an optional language capability, so a valid SCIP indexer can provide declarations, symbol ownership, direct SCIP relationships, semantic coverage, and metrics without syntax-derived edges. This is a contributor boundary, not a runtime third-party plugin API or package export.

To add another built-in family, define its versioned family plugin and language profiles under src/scip/families/, including source extensions, project markers/planning, probe behavior, and prerequisites. Register the plugin in the static catalog at src/scip/installed.ts, then add unit, semantic fixture, packed package, and external-indexer coverage. Dynamic third-party package loading is intentionally out of scope.

Indexing runs by TypeScript config group, Go module, Cargo workspace, or Python project/environment. Every index is written to scratch space and streamed without materializing the full protobuf. SCIP definitions establish stable graph identities, then bounded Tree-sitter syntax facts join imports, calls, callbacks, hierarchy, type annotations, and state access to SCIP occurrences. Named local variables are retained from declaration syntax; parameters, anonymous outline frames, and object-literal breadcrumb entries are not used as semantic authority.

The semantic edge set is IMPORTS, IMPORTS_SYMBOL, REEXPORTS, CALLS, INSTANTIATES, COMPOSES, EXTENDS, IMPLEMENTS, RETURNS_TYPE, PARAM_TYPE, PROPERTY_TYPE, REGISTERS_CALLBACK, READS, and WRITES. Module edges may target an indexed file or ExternalPackage; all other semantic targets must resolve to one unambiguous declaration. Named callbacks require stable callable declarations, and anonymous closures are omitted. Unresolved targets are counted; the indexer never invents internal file nodes or dangling edges for them.

Only the JavaScript, TypeScript, TSX, Go, Rust, and Python WASM grammars are referenced. The production dependency tree contains no native tree-sitter, native grammar package, or node-gyp dependency.

SQLite and incremental refresh

Refresh writes a complete replacement database under .code-graph/work and atomically publishes .code-graph/state/graph.sqlite. Incremental refresh copies unchanged rows and patches affected source ownership. It reads previous inbound relationships and reindexes unchanged reverse dependents when their targets move or disappear.

Schema v4 persists non-local symbol identity in scip_symbols(family, project, symbol, node_id, source_file). Compatibility metadata includes extractor and schema versions, enabled languages, syntax and configuration fingerprints, SCIP tool and aggregate indexer fingerprints, and indexer usage. indexer_tools records source-driven availability, command, version, prerequisite versions, and discovered-file counts. The v4 indexer fingerprint also includes the operating system and architecture. Adding, removing, or changing a tool or prerequisite, or moving the graph between platforms, forces a full rebuild without changing schema v4.

graph_completeness and project_failures make partial graphs explicit. An incomplete graph is usable for the current session but cannot seed incremental refresh and is retried on the next session. Strict mode preserves the last good database and rejects the incomplete replacement.

Structural folding is intentionally absent from the persisted graph, snapshot, editor, and call-tree state. Compact source views use explicit elisions in the view specification.

sqlite3 .code-graph/state/graph.sqlite \
  "SELECT label, count(*) FROM nodes GROUP BY label ORDER BY label;"

sqlite3 .code-graph/state/graph.sqlite \
  "SELECT type, count(*) FROM edges GROUP BY type ORDER BY type;"

Verification

The default unit suite and the package-owned TypeScript/JavaScript/Python fixtures are offline. Go/Rust checks and the network corpus benchmark are explicit:

pnpm --filter @dev.fast/code-graph typecheck
pnpm --filter @dev.fast/code-graph test:unit
pnpm --filter @dev.fast/code-graph test:fixtures
pnpm --filter @dev.fast/code-graph test:semantic
pnpm --filter @dev.fast/code-graph test:scip-parity
pnpm --filter @dev.fast/code-graph test:scip-incremental
pnpm --filter @dev.fast/code-graph test:pack
pnpm --filter @dev.fast/code-graph test:external-indexers
pnpm --filter @dev.fast/code-graph benchmark:indexing-corpus -- --verify-baseline
pnpm --filter @dev.fast/code-graph verify:scip-only
pnpm --filter @dev.fast/code-graph verify:plugin-boundaries

benchmark:indexing-corpus is an opt-in testing and measurement tool, not a release or publish gate. Pass --verify-baseline to compare pinned repositories with their committed structural and semantic expectations, or --measure --repository <id> to print a candidate baseline. Like test:semantic -- --measure, it never rewrites committed fixtures. Corpus mirrors, archives, and extracted sources are cached under ~/.cache/dev-fast/indexing-corpus.

Editor and daemon

The daemon, SQLite-backed editor, snapshot resolvers, and call-tree interfaces consume declaration and relationship graph records:

pnpm --filter @dev.fast/code-graph daemon
pnpm --filter @dev.fast/code-graph editor
pnpm --filter @dev.fast/code-graph call-tree