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

Introducing ts-validator: Static Analysis for Runtime Validation in TypeScript APIs with Rust blog post fallback blur image Introducing ts-validator: Static Analysis for Runtime Validation in TypeScript APIs with Rust blog post main image
Stephen CollinsApr 27, 2025
1 min

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.