Introducing ts-validator: Static Analysis for Runtime Validation in TypeScript APIs with Rust

What you will learn
- What limitations does TypeScript have when it comes to runtime input validation?
- TypeScript can catch errors at compile time, but it does not ensure that runtime inputs, such as `req.body`, `req.query`, and `req.params`, are validated. This gap can lead to failures in type assumptions and allow untrusted external data to enter the system.
- How does the `ts-validator` tool help in API safety?
- The `ts-validator` analyzes TypeScript code to find instances of unvalidated external inputs before they can cause issues. By checking for runtime validation (like using `zod.parse`), it highlights areas where user input is not properly validated, thereby enhancing API safety.
- What are the key features of the `ts-validator` tool?
- `ts-validator` parses TypeScript files to build an abstract syntax tree (AST), identifies route handlers, tracks usage of external inputs, checks for runtime validation, and reports unvalidated data access locations. It supports different validation strategies, ensuring flexibility for developers.
- How can developers use `ts-validator` in their projects?
- Developers can use `ts-validator` directly via `npx` for quick analysis without installation, or they can install it as a local development tool using npm. This makes it easy to integrate into existing projects for ongoing safety checks.
- Why is it important to validate runtime inputs in API development?
- Validating runtime inputs is crucial to prevent security vulnerabilities and application errors that arise from untrusted data. Ensuring that all external inputs are checked helps maintain the integrity of the application and protects against potential exploitation or data corruption.
TypeScript helps catch errors at compile time, but it doesnβt guarantee that runtime inputs β like req.body
, req.query
, and req.params
β are properly validated.
In APIs, missing validation can lead to serious issues: type assumptions fail, and untrusted external data leaks into the system.
ts-validator is an open source Rust-based tool that statically analyzes TypeScript codebases to find unvalidated external inputs before they cause problems.
What ts-validator
Does
- Parses
.ts
and.tsx
files to build an abstract syntax tree (AST) - Walks the AST to find route handlers (e.g., Express
app.get
,app.post
) - Tracks usage of external inputs (
req.body
,req.query
,req.params
) - Checks whether runtime validation (like
zod.parse
) is applied - Reports locations where unvalidated data is accessed directly or through aliases
It supports different validation strategies, including strict (parse
only) and lenient (safeParse
allowed) modes.
The tool is designed to be fast and lightweight, running as a single compiled binary.
Example Output
Hereβs a run against a simple Express application:
π Starting analysis on examples/test-express-app/src with rules: zod-strict
Parsing files:
β
examples/test-express-app/src/middleware/authMiddleware.ts
β
examples/test-express-app/src/middleware/errorMiddleware.ts
β
examples/test-express-app/src/config/index.ts
β
examples/test-express-app/src/types.ts
β
examples/test-express-app/src/index.ts
β
examples/test-express-app/src/routes/postRoutes.ts
β
examples/test-express-app/src/routes/userRoutes.ts
π οΈ Parsing completed in: 2.238459ms
Analyzing files:
β
middleware/authMiddleware.ts β No violations found
β
middleware/errorMiddleware.ts β No violations found
β
config/index.ts β No violations found
β
src/types.ts β No violations found
β
src/index.ts β 1 controllers found
β
routes/postRoutes.ts β 5 controllers found
β
routes/userRoutes.ts β 5 controllers found
β Violations detected
[examples/test-express-app/src/routes/postRoutes.ts:28:17] Unvalidated direct access: req.query
[examples/test-express-app/src/routes/postRoutes.ts:28:45] Unvalidated direct access: req.query
[examples/test-express-app/src/routes/postRoutes.ts:41:46] Unvalidated direct access: req.params
[examples/test-express-app/src/routes/postRoutes.ts:60:37] Unvalidated direct access: req.body
[examples/test-express-app/src/routes/postRoutes.ts:102:22] Unvalidated direct access: req.params
[examples/test-express-app/src/routes/userRoutes.ts:32:46] Unvalidated direct access: req.params
[examples/test-express-app/src/routes/userRoutes.ts:67:22] Unvalidated direct access: req.params
[examples/test-express-app/src/routes/userRoutes.ts:70:26] Unvalidated direct access: req.body
[examples/test-express-app/src/routes/userRoutes.ts:90:46] Unvalidated direct access: req.params
π§Ή Analysis completed in 2.561292ms
β
7 files scanned | β 9 violations found | β±οΈ 2.571334ms total
How It Works
ts-validator
is split into small Rust crates:
- Parser: Finds and parses
.ts
/.tsx
files into ASTs (using SWC) - Analysis: Walks ASTs to find route handlers and track input usage
- Validation Rules: Checks whether runtime validation occurs
- Reporting: Outputs warnings, with optional JSON formatting
It can be run directly via npx
without installing anything:
npx @stephen-collins-tech/ts-validator path/to/your/file.ts
Or installed as a local development tool:
npm install --save-dev @stephen-collins-tech/ts-validator
Why It Exists
Thereβs a gap between what TypeScript checks at compile time and what applications actually need at runtime.
ts-validator
helps bridge that gap by identifying places where user input isnβt properly validated, without requiring runtime instrumentation or test coverage.
Itβs meant to be a fast, simple safeguard for projects that care about API safety.