Skip to content
Documentation menu

Documentation

Little Owl analyses a project on disk and reports on its structure. It needs no configuration to be useful, and no service to talk to.

The mental model

Three concepts carry everything else. If you understand these, the rest of the documentation is reference material you can read when you need it.

  • Baseline. A recorded snapshot of what healthy means for this project — the scores, the counts behind them, and the findings that existed at the time. It only moves when you move it.
  • Scope. What a change was supposed to touch. Anything outside it gets reported, which is the guardrail for “I asked for a fix to orders and it also rewrote authentication”.
  • Drift. The distance between now and the baseline, expressed both as score movement and as the concrete counts that caused it.

Language support

TypeScript and JavaScript are parsed into a full syntax tree. Python and Go are analysed line by line — genuinely supported, and genuinely shallower. Everything that comes from the import graph or from git works the same in all four.

Analysis capabilities by language. TypeScript and JavaScript are parsed into a full syntax tree; Python and Go are analysed line by line.
CapabilityTSJSPyGo
Dependency graphGo resolves at package levelsupportedsupportedsupportedsupported
Circular dependenciessupportedsupportedsupportedsupported
Layers and boundariesDriven by directories, so language-agnosticsupportedsupportedsupportedsupported
File and function sizesupportedsupportedsupportedsupported
Cyclomatic complexityKeyword-counted outside TS/JSsupportedsupportedsupportedsupported
Duplicate blocksTextual, so it works anywheresupportedsupportedsupportedsupported
Impact and reverse depssupportedsupportedsupportedsupported
Code archaeologyReads git, not codesupportedsupportedsupportedsupported
Project mapsupportedsupportedsupportedsupported
Dead codeConfidence is capped below high for Python and Gosupportedsupportedsupportedsupported
Test gapsRecognises test_*.py and *_test.gosupportedsupportedsupportedsupported
React component budgetssupportedsupportednot supportednot supported
Type-safety rulesNeeds types to existsupportednot supportednot supportednot supported
Dependency hygieneReads package.json onlysupportedsupportednot supportednot supported
Structural pattern rulesGo exports are functions onlysupportedsupportedsupportednot supported

TypeScript

Full AST

.ts .tsx .mts .cts

TypeScript compiler API — full syntax tree

Imports, exports, dynamic imports, path aliases, functions, components, cyclomatic complexity, nesting, `any`, assertions and suppressions.

Rules only this language gets

  • type-safety/explicit-any
  • type-safety/suppression
  • type-safety/unsafe-assertion
  • type-safety/js-in-ts-project
  • next/server-import-in-client
  • react/effect-dependency-risk

JavaScript

Full AST

.js .jsx .mjs .cjs

TypeScript compiler API — full syntax tree

Everything TypeScript gets, minus the type-safety rules that need types to exist. JSX, CommonJS `require` and ESM are all understood.

Rules only this language gets

  • next/server-import-in-client
  • react/effect-dependency-risk

Python

Shallow

.py .pyi

Line and indentation based

Imports and the dependency graph, relative and absolute module resolution, function boundaries by indentation, complexity, module sizes, and three known smells.

Limits: Not a full parse. Re-exports through `__init__.py` are not followed, so a module reached only through a package export can look unreferenced. Decorators, metaclasses and dynamic attribute access are invisible. It will not replace Ruff.

Rules only this language gets

  • python/bare-except
  • python/mutable-default
  • python/global-state

Go

Shallow

.go

Line and brace based

Package clauses, grouped and single imports, module-relative resolution through go.mod, package-level cycles, function boundaries by brace balance, and oversized packages.

Limits: Exports are detected from capitalised functions only, so exported types, constants and variables are invisible to the dead-code and pattern rules. Build tags and generated code are not special-cased. It will not replace golangci-lint.

Rules only this language gets

  • go/ignored-error
  • go/large-package

What it writes to your project

Little Owl never modifies your source. It writes one directory, .little-owl/, containing your configuration and baseline — which belong in version control — plus a parse cache and a local review log, which do not. It adds those two to a .gitignore inside that directory the first time it writes anything, so the cache cannot end up in a pull request.