What We Check

148 checks across 23 categories

25 core checks are free and open source. Activate a license to unlock all 148 checks including determinism, async safety, type validation, and more.

Free

Always included (25 checks)

๐Ÿ›ก

Security

7 checks
  • SEC001Hardcoded passwords, API keys, and secrets(Py, JS/TS, C#, Go, Rust, Ruby)
  • SEC002SQL queries built with string concatenation
  • SEC004Non-cryptographic random for security tokens

and 4 more checks

๐ŸŽฎ

C# / Unity

3 checks
  • CS001async void methods that crash on unhandled exceptions(C#)
  • CS002Debug.Log / Console.WriteLine left in production code(C#)
  • CS003GameObject.Find / GetComponent inside Unity Update() loops(C#)
๐Ÿ“

Schema Validation

2 checks
  • SCHEMA001Pydantic field nullability mismatches(Python)
  • SCHEMA002Pydantic/SQLAlchemy field type misalignment(Python)
โœจ

Quality Essentials

3 checks
  • QUAL001Silently swallowed exceptions hide real bugs(Py, JS/TS, C#, Go, Rust, Ruby)
  • QUAL009Files too long to review effectively
  • QUAL012Background tasks without trace IDs for debugging
๐Ÿ“

Project Setup

4 checks
  • PROJ001Missing CLAUDE.md for AI assistant context
  • PROJ005CLAUDE.md tracked in git but should be gitignored
  • PROJ007Large codebase with almost no automated tests

and 1 more check

๐Ÿ”’

Session Safety

1 check
  • SESS002Thread-unsafe database session sharing
๐Ÿ—

Structure Essentials

2 checks
  • STRUCT001Multiple classes in a single file(Python)
  • STRUCT013Same SDK client initialized in multiple files
โšก

Async Essentials

1 check
  • ASYNC001Async function called without await(Py, JS/TS)
๐Ÿ“ก

API Essentials

1 check
  • API007API endpoints without typed responses(Py, JS/TS)
Pro

Unlock with a license (123 checks)

๐Ÿ”

Extended Security

9 checks
  • SEC007OAuth callback missing state validation(Py, JS/TS)
  • SEC013Missing security headers on HTTP responses(JS/TS)
  • SEC017Regex-based HTML sanitizer can be bypassed(JS/TS)

and 6 more checks

๐ŸŽฏ

Determinism

9 checks
  • DET001Dictionary iteration without sorting causes flaky behavior
  • DET005Random without seed causes non-reproducible results(Py, JS/TS)
  • DET009Uncached LLM calls break reproducibility and waste tokens

and 6 more checks

๐Ÿš€

Performance

7 checks
  • PERF001Database calls inside loops (N+1 queries)(Py, JS/TS)
  • PERF005Render-blocking font imports slow first paint(JS/TS)
  • PERF007Public pages without a CDN configured(JS/TS)

and 4 more checks

๐Ÿ› 

Code Quality

16 checks
  • QUAL004Mutable default arguments shared between calls(Python)
  • QUAL011Functions with excessive cyclomatic complexity
  • QUAL014Case-insensitive email comparison missing

and 13 more checks

๐Ÿท

Type Safety

15 checks
  • TYPE008Explicit 'any' type usage defeats TypeScript's purpose(TS)
  • TYPE009process.env.VAR! non-null assertion can crash at runtime(TS)
  • TYPE013JSON.parse without runtime validation is unsafe(Py, TS)

and 12 more checks

โฑ

Async & Concurrency

5 checks
  • ASYNC002Blocking calls inside async functions(Py, JS/TS)
  • ASYNC003Fire-and-forget tasks without error handling(Py, JS/TS)
  • CONC001Check-then-act race conditions

and 2 more checks

๐Ÿ”Œ

API Design

6 checks
  • API001API calls without error handling(Py, JS/TS)
  • API005Frontend/backend type definitions drift apart
  • API006Shared types defined in multiple places

and 3 more checks

๐Ÿ”—

tRPC

4 checks
  • TRPC001tRPC procedures without input validation(TS)
  • TRPC002Inline Zod schemas instead of shared types(TS)

and 2 more checks

๐Ÿ–ฅ

Frontend

13 checks
  • FRONT002window/document access without SSR guard(JS/TS)
  • FRONT005useEffect used for side effects that should be event handlers(TS)
  • FRONT007Unbounded AI output rendered in the DOM(JS/TS)

and 10 more checks

๐Ÿงช

Testing

10 checks
  • TEST001Tests marked as skipped accumulate silently(Py, JS/TS)
  • TEST007Critical user flows missing E2E test coverage
  • TEST009Playwright waitForTimeout instead of event-driven waits

and 7 more checks

๐Ÿงฉ

Project Structure

8 checks
  • STRUCT004Direct sys.path manipulation breaks packaging
  • STRUCT010No clear frontend/backend separation(JS/TS)
  • STRUCT011Duplicate modules across packages cause import ambiguity

and 5 more checks

๐Ÿง 

Memory Safety

4 checks
  • MEM001Unbounded database queries load entire tables into memory
  • MEM003In-process accumulators grow without bound
  • MEM004Global state singletons break in worker / serverless environments

and 1 more check

๐Ÿ“…

Datetime

3 checks
  • DATE002Naive datetime without timezone causes silent bugs
  • DATE003Database datetime used without timezone awareness
  • DATE004getDay() returning UTC day mismatches local expectations
โ˜ธ

Infrastructure

4 checks
  • KUBE001Local filesystem used for application data in containers
  • KUBE002Ingress missing SSL redirect
  • RATE001API endpoint without rate limiting(Py, JS/TS)

and 1 more check

โš™

Project Config

4 checks
  • PROJ002Project not using git version control
  • PROJ003Missing pyright configuration
  • PROJ004Depending on beta / pre-release packages

and 1 more check

๐Ÿ“ฆ

Imports

1 check
  • IMPORT001Import shadows a Python builtin or keyword(Python)
๐Ÿ—ƒ

Migrations

2 checks
  • MIG001Alembic revision id overflows the VARCHAR(32) version column(Python)
  • MIG002Deploy scripts that suppress migration failures (|| true, stamp-after-upgrade)(Shell, Docker, CI)
๐Ÿ—

Session (Advanced)

1 check
  • SESS001Database session passed to background task
โ™ฟ

Accessibility

1 check
  • A11Y001Button text may be invisible on background color

Every check, in detail

Each rule has its own page: what it catches, why it matters, and how to fix it.

A11Y001button-contrastAPI001unhandled-api-errorAPI002inconsistent-api-namingAPI003missing-content-typeAPI004hardcoded-api-urlAPI005api-type-alignmentAPI006cross-file-type-mismatchAPI007untyped-api-responseASYNC001missing-awaitASYNC002blocking-in-asyncASYNC003fire-and-forget-taskASYNC004silent-catchCONC001check-then-actCONC002non-atomic-read-writeCS001csharp-async-voidCS002csharp-debug-log-in-productionCS003csharp-expensive-find-in-updateDATE002naive-datetimeDATE003db-datetime-awarenessDATE004getday-utc-mismatchDET001unsorted-dict-iterationDET002unsorted-set-iterationDET003missing-sort-tiebreakerDET004list-set-dedupDET005random-without-seedDET006datetime-now-usageDET007unsorted-directory-listingDET008hash-unsorted-collectionDET009uncached-llm-callFRONT001tabs-url-routingFRONT002window-ssr-unsafeFRONT003inline-jsx-handlerFRONT004nextjs-redirect-request-urlFRONT005useeffect-side-effect-unguardedFRONT006stale-time-dependent-uiFRONT007unbounded-ai-outputFRONT008loading-returns-nullFRONT009eager-queries-no-deferFRONT010useeffect-timer-no-cleanupFRONT011useeffect-listener-no-cleanupFRONT012vite-hmr-reload-guard-missingFRONT013step-state-no-historyIMPORT001reserved-keyword-importKUBE001local-filesystem-dataKUBE002ingress-ssl-redirectMEM001unbounded-queryMEM002unbounded-eager-loadMEM003in-process-accumulatorMEM004global-state-singletonMIG001alembic-revision-id-too-longMIG002migration-failure-maskedPERF001n-plus-one-queryPERF002uninstrumented-llm-callPERF003redundant-trpc-callsPERF004subscription-waterfallPERF005render-blocking-font-importPERF006uncached-public-pagePERF007no-cdn-configuredPROJ001missing-ai-context-filePROJ002missing-gitPROJ003pyright-configPROJ004beta-dependenciesPROJ005gitignored-claude-mdPROJ006firm-alias-commit-authorPROJ007low-test-coverage-ratioPROJ008macos-fork-safety-missingQUAL001exception-swallowingQUAL002unnamed-threadQUAL003complex-tupleQUAL004mutable-default-argumentQUAL005print-statementQUAL006todo-commentQUAL007broad-exceptionQUAL008magic-numberQUAL009file-too-longQUAL010url-state-not-persistedQUAL011code-complexityQUAL012background-task-tracingQUAL013mixed-boolean-operatorsQUAL014case-sensitive-emailQUAL015double-wrapped-email-addressQUAL016duplicate-external-creationQUAL017hardcoded-model-idQUAL018bash-syntax-in-shQUAL019duplicate-code-blocksRATE001missing-rate-limitRATE002in-memory-rate-limiterSCHEMA001pydantic-nullability-mismatchSCHEMA002pydantic-sqlalchemy-field-mismatchSEC001hardcoded-secretSEC002sql-injectionSEC003eval-usageSEC004insecure-randomSEC005inner-html-xssSEC006webhook-security-bypassSEC007oauth-state-validationSEC008plaintext-secretsSEC009email-header-injectionSEC010csv-formula-injectionSEC011unsanitized-htmlSEC012node-env-security-gateSEC013missing-security-headersSEC014error-detail-leakageSEC015fail-open-securitySEC017regex-html-sanitizerSESS001background-task-sessionSESS002thread-session-safetySTRUCT001multiple-classes-per-fileSTRUCT003imports-in-functionSTRUCT004sys-path-manipulationSTRUCT005relative-importsSTRUCT006hasattr-getattr-patternSTRUCT009class-filename-mismatchSTRUCT010mixed-frontend-backendSTRUCT011duplicate-modulesSTRUCT012naked-functionsSTRUCT013duplicate-client-initTEST001skipped-testsTEST003async-mock-issuesTEST004duplicate-test-helpersTEST005e2e-test-duplicationTEST006e2e-console-captureTEST007missing-e2e-testsTEST008playwright-test-slow-misuseTEST009playwright-wait-for-timeoutTEST010instant-visibility-before-assertTEST011playwright-or-strict-modeTRPC001trpc-procedure-no-inputTRPC002trpc-inline-zod-schemaTRPC003trpc-result-type-bypassTRPC004trpc-missing-error-handlingTYPE001weak-typingTYPE002naked-dict-for-structured-dataTYPE004missing-type-hintsTYPE005inline-type-definitionTYPE006dict-type-inconsistencyTYPE007duplicate-type-definitionTYPE008typescript-anyTYPE009env-non-null-assertionTYPE010unsafe-json-parseTYPE011inline-enum-duplicationTYPE012dom-selection-null-checkTYPE013unvalidated-json-parseTYPE015cross-language-type-duplicationTYPE016repeated-dict-key-assignmentTYPE017unstructured-dict-access-where-model-exists

Try it now

Free tier runs instantly with no signup. Upgrade anytime to unlock all 148 checks.

pip install stablestack