Skip to content

About

Understand any codebase in seconds. A local-first CLI that detects your stack, services, environment, routes, scripts, and setup issues.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

9 stars

Watchers

0 watching

Forks

Latest commit

 

History

40 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RepoLens

Understand any repository in seconds.

npm version CI status Node.js 22 or newer MIT license No telemetry

English · Português (Brasil)

RepoLens reads a codebase and tells you how it fits together: the stack, what has to be running, which environment variables you need, how to start it, and what's misconfigured.

No configuration needed. No cloud upload. No AI API. It never runs your code.

npx @douglas-strey/repolens

RepoLens output for a pnpm + Turborepo monorepo: project type, languages, package manager, runtimes, frameworks per package, workspace packages, a suggested quick start, Docker services with ports, databases, environment variables, scripts, API routes, CI jobs, tooling and one potential issue

Why

Joining a project usually starts with 20 minutes of archaeology. Which package manager? Which Node version, and why does the Dockerfile disagree with .nvmrc? What has to be running locally? Which env vars does the code actually read, and why isn't that one in .env.example?

RepoLens does that pass for you, reading only the files in the repository.

Quick start

npx @douglas-strey/repolens          # overview of the current directory
npx @douglas-strey/repolens doctor   # setup problems, with suggested fixes
npx @douglas-strey/repolens setup    # set up a fresh clone: env file, services, dependencies
npx @douglas-strey/repolens ../other-repo --json

Or install it to use the shorter command, repolens:

brew install douglas-strey/tap/repolens   # macOS and Linux (Homebrew)
npm install -g @douglas-strey/repolens    # any OS with Node.js 22+

Works on macOS, Linux and Windows. The npm package needs Node.js 22 or newer; Homebrew installs Node for you.

Just cloned it? repolens setup creates the env file from the example, starts the backing services and installs dependencies, after showing you exactly what it will run.

Scanning a repository you don't trust? Run RepoLens from outside it, e.g. cd ~ && npx @douglas-strey/repolens ~/path/to/repo, or use a global install. When npx runs inside a repository, npm itself honors that repository's .npmrc and node_modules, which could substitute a different package before RepoLens even starts.

What it shows

Project Type (monorepo, app, library, CLI), languages, package manager, runtime versions, Go main packages and bin commands, Git branch and remote
Frameworks Per workspace package, with version and the evidence behind each detection
Workspace pnpm / npm / Yarn / Bun workspaces, Turborepo, Nx, Lerna, go.work, with each package's framework
Quick start Suggested first commands: copy the env file, start Compose services, install, run
Services Docker Compose services with images, published ports and profiles, plus Dockerfiles (base images, stages, exposed ports)
Databases PostgreSQL, MySQL, MongoDB, Redis, SQLite and more, from drivers, Compose images, env URLs and Prisma / Drizzle / TypeORM config, plus the ORM in use
Environment Every variable: is it set in .env, documented in .env.example, used in code? Names only; values are never printed
Scripts package.json scripts with the exact command to run them, plus Makefile, justfile, Taskfile and Deno tasks
Routes API routes and pages for Nuxt, Next.js, Express, Fastify, NestJS, Hono, Gin, Echo, chi, Fiber, Gorilla mux and net/http
CI Workflows and what each job does (lint, test, build, deploy, …)
Tooling Test frameworks, linters, formatters, type checkers, Git hooks and build tools

Use --verbose to see low-confidence findings, the evidence behind each detection, and every variable, route and script.

repolens doctor

doctor runs 35 checks for problems that cost teams time. Each finding has a stable code, a one-line explanation and a suggested fix:

repolens doctor output: checks grouped by category with one environment warning and a suggested fix

Some of the things it catches:

  • env vars used in code but missing from .env.example, and documented ones nothing reads
  • .env files tracked by Git, or not covered by .gitignore
  • a real credential committed to .env.example (AWS keys, GitHub tokens, Stripe live keys, …), reported by variable name only
  • secrets exposed to the browser (NEXT_PUBLIC_…SECRET, VITE_…PASSWORD)
  • package-lock.json next to pnpm-lock.yaml, or a lockfile that contradicts packageManager
  • runtime versions with known vulnerabilities: a pinned PHP, Node.js or Go release older than its line's latest security release
  • Node versions that disagree across .nvmrc, .node-version, engines, Dockerfiles and CI, and end-of-life versions
  • a go.mod that asks for a newer Go than the Docker image or CI provides
  • two Compose services publishing the same port, and DATABASE_URL pointing at 5433 while Postgres is published on 5432
  • env_file entries that don't exist, obsolete Compose version: keys
  • turbo.json still using pipeline on Turborepo 2, legacy .eslintrc with ESLint 9+, duplicated workspace config
  • config files that don't parse

See every check in docs/diagnostics.md.

repolens doctor              # exits 1 on errors
repolens doctor --strict     # also fails on warnings
repolens doctor --online     # also check dependencies against OSV.dev
repolens doctor --json       # for scripts and CI

A plain repolens scan always exits 0 when it completes, so adding it to a CI log never breaks a build. Gate on doctor instead:

- run: npx --yes @douglas-strey/repolens doctor --fail-on error

Known vulnerabilities in your runtimes

A security release only protects the projects that upgrade. doctor reads every place a project pins its runtime, from Dockerfiles to CI steps and version files, and tells you when that version has known vulnerabilities. The PHP image you forgot in a Dockerfile shows up the day the fix ships:

repolens doctor output: an error for PHP 8.3.10, pinned in the CI workflow and the Dockerfile, which misses 10 security releases rated up to critical, with the CVEs fixed in PHP 8.3.36 and a link to the announcement, and a warning for a Go 1.26.2 image that misses 6 security releases

  • PHP, Node.js and Go. An exact pin older than the latest security release of its line is reported with how many fixes it misses, the severity the project gave them, the CVEs and the version to upgrade to.
  • A critical fix fails the run. Missing a fix rated critical is an error, so repolens doctor exits with 1 in CI; other missed fixes are warnings. A repository's own config can't turn the check off or lower it.
  • Straight from the source, still offline. The security releases come from php.net, the Node.js security posts and the Go release history, in a table that ships with RepoLens and is updated with every release. The scan makes no network requests, so upgrading RepoLens is how you get the latest advisories.
  • Only versions that are really pinned. php:8.3-fpm, ^8.3 and engines ranges follow the latest patch and aren't reported; php:8.3.10-fpm is.
  • Your dependencies too, when you ask. repolens doctor --online looks every exact version in your lockfiles (npm, pnpm, Yarn, Bun, Composer, Go modules) up in OSV.dev and reports the advisories with the version that fixes them. It is the only thing in RepoLens that uses the network, and it sends package names and versions, nothing else.

Details in docs/diagnostics.md.

repolens setup

Just cloned a project? setup does the quick start for you: it creates your local env file from the example, starts the backing services with Docker Compose and installs dependencies (npm, pnpm, Yarn, Bun or Go modules). Try it with --dry-run first to see the plan without running anything:

repolens setup --dry-run output: a plan that copies .env.example to .env and runs pnpm install, listing the postinstall script it triggers, with the project's own db:up script left for the developer

Installing dependencies runs code from the project and its dependencies, so setup is upfront about it:

  • It shows the plan first, including every install lifecycle script the project defines (postinstall, prepare, …) and the images Compose will pull or build.
  • It asks before running anything. Answer y to go ahead; without a terminal it refuses to run unless you pass --yes.
  • It only runs commands it builds itself. Project scripts such as make setup or pnpm db:up are listed under "Skipped" for you to run.
  • It never touches your values. An existing .env is left alone, and a new one is never filled in.
  • It checks your Node.js version against engines.node before installing, and stops at the first step that fails. Running it again is safe.
repolens setup                    # show the plan, ask, then run it
repolens setup --dry-run          # only show the plan
repolens setup --ignore-scripts   # install without lifecycle scripts (untrusted code)
repolens setup --yes              # don't ask (CI, scripts)

When it finishes, setup tells you whether repolens doctor still finds problems and how to start the project. Details in docs/cli.md and docs/security.md.

repolens mcp

Let your AI assistant ask RepoLens about the project. repolens mcp is a Model Context Protocol server: Claude Code, Codex, Cursor and other MCP clients start it and call its tools whenever they need to know how the project fits together, instead of reading dozens of files to find out:

repolens mcp answering a get_services tool call: the Docker Compose services with their images and ports, the command that starts them, the databases and the ORM, as the Markdown text the assistant receives

  • Six tools: get_project_overview, get_services, get_environment_variables, get_routes, get_scripts and get_diagnostics. Each answers with the matching part of the Markdown report (or JSON, on request), for the whole project or one package (path: "apps/web").
  • Always current. Every call scans the files as they are, so answers follow your edits.
  • Same guarantees as the CLI. It only reads files, reports environment variables by name and never their values, and doesn't look outside the project.
  • No extra dependencies. The protocol is built into RepoLens and speaks both the current MCP revision and the earlier ones.

Add it to Claude Code:

claude mcp add repolens -- npx -y @douglas-strey/repolens mcp

To Codex:

codex mcp add repolens -- npx -y @douglas-strey/repolens mcp

Or to Cursor, in .cursor/mcp.json:

{
  "mcpServers": {
    "repolens": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@douglas-strey/repolens", "mcp", "${workspaceFolder}"]
    }
  }
}

For repositories you don't trust, install RepoLens once (npm install -g @douglas-strey/repolens) and use repolens mcp as the command: npx run inside a repository honors its .npmrc. Details in docs/cli.md.

Configuration

RepoLens needs no configuration. To adjust it, add a repolens.config.json to the project (shared with everyone who scans it, including CI) or a user config at ~/.config/repolens/config.json (your defaults everywhere):

{
  "$schema": "https://unpkg.com/@douglas-strey/repolens/schema/config.schema.json",
  "ignore": ["legacy/", "src/generated/"],        // .gitignore syntax
  "doctor": {
    "failOn": "warning",                            // default for --fail-on
    "rules": { "ENV_UNUSED": "off", "LOCKFILE_MISSING": "error" }
  },
  "environment": { "provided": ["FLY_*"] }          // set by the platform, never "missing"
}

repolens config shows which files apply and the settings in effect, and --no-config ignores them all. Configuration is plain JSON that RepoLens never executes, and a repository's own config can't turn off its security checks. See docs/configuration.md.

JSON output

repolens --json | jq '.environment.variables[] | select(.used and (.documented | not)) | .name'
repolens --json | jq '.routes.routes[] | "\(.method) \(.path)"'

The JSON output is versioned ("schemaVersion": 1), deterministic (no timestamps, sorted arrays, relative paths only) and documented in docs/json-schema.md. TypeScript types are exported from the package:

import { scan } from '@douglas-strey/repolens'

const result = await scan({ cwd: '/path/to/repo' })
console.log(result.frameworks.map((f) => f.name))

Reports and agent context

repolens report writes the whole picture as Markdown, which is handy for onboarding docs, technical audits, or pasting into an AI chat:

repolens report --output REPOLENS.md

repolens agent init (experimental) generates short, structured context for coding agents such as Claude Code, Codex, Cursor or Copilot. It covers the commands to run, the conventions RepoLens can back with evidence ("use pnpm, not npm", "Node 22", "CI runs lint, test and build"), the structure, services, env var names and known issues:

repolens agent init        # writes .repolens/*.md
repolens agent             # prints agent-context.md to stdout

Point your agent at it from AGENTS.md or CLAUDE.md. Review the files before committing them; they never contain secret values.

Supported technologies

Area Support
Languages JavaScript, TypeScript and Go in depth. File counts for Python, Rust, Ruby, PHP, Java, Kotlin, Swift, C/C++, C#, Shell and more
Package managers npm, pnpm (including catalogs), Yarn Classic and Berry, Bun, Go modules; packageManager and devEngines
Runtimes Node.js (.nvmrc, .node-version, .tool-versions, mise, engines, Volta, devEngines, Dockerfiles, CI), Go, PHP (composer.json, .php-version, Dockerfiles, setup-php), Bun, Deno
Monorepos pnpm, npm, Yarn and Bun workspaces, Turborepo, Nx, Lerna, go.work
Frameworks Nuxt, Next.js, Remix, React Router, SvelteKit, Astro, Angular, React, Vue, Svelte, Solid, Preact, Qwik, Express, Fastify, NestJS, Koa, Hono, hapi, Elysia, AdonisJS, tRPC, Electron, React Native, Expo, Gatsby, Docusaurus, VitePress; Go: Gin, Echo, chi, Fiber, Gorilla mux, gRPC, net/http
Routes Nuxt (server routes and pages, srcDir), Next.js (App and Pages Router, basePath, pageExtensions), Express, Fastify, NestJS, Hono, Gin, Echo, chi, Fiber, Gorilla mux, net/http; router prefixes are resolved across files, including Go routers passed to functions
Databases & ORMs PostgreSQL, MySQL, MariaDB, SQLite/libSQL, MongoDB, Redis/Valkey, CockroachDB, SQL Server, ClickHouse and more; Prisma, Drizzle, TypeORM, Sequelize, MikroORM, Kysely, Knex, Mongoose, GORM, Ent, sqlx, sqlc
Containers Docker Compose (all file names, overrides and variants, local include and extends, long and short syntax), Dockerfiles (multi-stage, ARG substitution)
CI GitHub Actions, GitLab CI (with local include and job extends), CircleCI, Forgejo/Gitea Actions; Azure Pipelines, Jenkins, Travis, Bitbucket, Buildkite, Drone and Woodpecker are listed
Tooling Vitest, Jest, Mocha, AVA, node:test, Bun test, Playwright, Cypress, go test, pytest; ESLint, Biome, Oxlint, Prettier, golangci-lint, Ruff; Husky, Lefthook, lint-staged; Vite, webpack, Rollup, esbuild, tsup, tsdown and more

Other repositories still get languages, Makefile/justfile targets, CI, key config files and the generic doctor checks. Missing something? Request a detector; most are a table entry and a test.

Privacy and security

RepoLens is built to be the first thing you run in a repository you don't know yet.

  • It never executes anything from the repository. No scripts, no config files (it reads nuxt.config.ts as text), no Docker. It doesn't even run git: repository config can make git run arbitrary commands, so branch, remotes and tracked files are read straight from .git/. The one exception is repolens setup, which you run on purpose: it shows each command and the scripts it will trigger, and asks first.
  • It never prints secret values. The .env parser keeps variable names and throws the values away. Committed text it echoes back (scripts, dependency URLs, Git remotes) is redacted. The test suite checks that sentinel secrets never show up in any output format.
  • It only reads inside the directory you point it at. Symlinks are resolved and checked, directory symlinks are never followed, and FIFOs, binaries and huge files are skipped.
  • No telemetry, no network by default. RepoLens makes no network requests unless you run repolens doctor --online, which sends package names and versions to OSV.dev.

The full model is in docs/security.md. Found a hole? Please report it privately.

How it works

RepoLens walks the repository once, respecting .gitignore and skipping node_modules, vendor and build caches. Independent detectors then read what they need through a shared, cached, sandboxed context, each producing one section of the result. Doctor rules check those facts, and renderers turn them into terminal, JSON, Markdown or agent output.

walk (.gitignore-aware) → file index → detectors (parallel, memoized) → doctor rules → renderers

Every uncertain finding carries a confidence level and its evidence, and low-confidence findings stay hidden unless you ask for them. Runtime dependencies are yaml, ignore and semver, none of which has dependencies of its own. More in docs/architecture.md.

Speed: on an Apple M1 Max with Node.js 26, scanning this repository (about 420 files) takes around 35 ms, a synthetic 500-package monorepo (3,000 files) around 250 ms, and 3,000 packages (18,000 files) around 1.2 s. Run pnpm bench to measure on your machine.

Roadmap

v0.5 (now): everything above. JavaScript/TypeScript and Go in depth; terminal, JSON, Markdown and agent output; an MCP server for AI assistants; 36 doctor checks, including known vulnerabilities in pinned runtimes and, with --online, in locked dependencies; repolens setup for a fresh clone; user and project configuration files, with per-finding ignores and a monorepo root's config.

Next

  • Python (Django, Flask, FastAPI, uv/Poetry), Rust (Cargo workspaces), PHP (Laravel, Composer)
  • More routes: SvelteKit, Remix / React Router, Astro endpoints
  • Submitting the formula to homebrew-core (so brew install repolens works without the tap)

Later

  • A plugin API for third-party detectors (@repolens/detector-*)
  • Architecture and dependency graphs
  • Editor extensions

Nothing on this list exists yet. Follow it on the roadmap board, where every item has an issue to comment on if you'd like to help build it, and ROADMAP.md describes each one, with where to start and how big it is. Ideas and votes are welcome in Discussions.

FAQ

Why is the npm package called @douglas-strey/repolens? The unscoped repolens names on npm were already taken or too close to existing packages. The command you run is still repolens.

Does it upload my code or use an AI model? No. Everything happens locally with static analysis. There is no account or API key, and no network access unless you run repolens doctor --online, which sends package names and versions (never code) to OSV.dev.

Is it safe on a repository I don't trust? That's the main design goal: it never executes project code, config files, hooks or git, and it never reads outside the directory you scan (except the enclosing .git metadata and the repository root's config when you scan a subdirectory). repolens setup is the exception you opt into: it installs dependencies, which runs the project's install scripts, so it lists them and asks first (--ignore-scripts skips them). See docs/security.md.

It reported something wrong or missed something. Please open an issue with the file names involved. Run with --verbose to see the evidence behind each detection.

How is this different from a linter? Linters check code. RepoLens checks how a repository is put together: the setup that decides whether a new contributor can run it on day one.

Contributing

Contributions are very welcome, especially new detectors and doctor checks.

pnpm install
pnpm test
pnpm dev -- ../some-project

Looking for a first task? The good first issues are small, self-contained and not taken yet. Then read CONTRIBUTING.md and docs/creating-a-detector.md.

License

MIT © Douglas Strey

About

Understand any codebase in seconds. A local-first CLI that detects your stack, services, environment, routes, scripts, and setup issues.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

9 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages