How to Use Spectral in TypeScript
So, you want cleaner APIs. Fewer bugs. Better documentation. And you want all of that without losing your mind. Good news. Spectral is here to help. And yes, it plays very nicely with TypeScript.
TLDR: Spectral is a flexible linter for JSON and YAML files. It is often used to validate OpenAPI and AsyncAPI specs. In TypeScript, you can use Spectral to programmatically lint API definitions, create custom rules, and enforce consistent standards across your projects. Setup is simple, customization is powerful, and it helps catch problems early.
Let’s break it down. And let’s make it fun.
Contents
- 1 What Is Spectral?
- 2 Why Use Spectral with TypeScript?
- 3 Step 1: Install Spectral
- 4 Step 2: Basic Usage in TypeScript
- 5 What Do the Results Look Like?
- 6 Step 3: Using Custom Rules
- 7 Understanding “given” and “then”
- 8 Step 4: Creating Custom Functions
- 9 Step 5: Linting Files Instead of Strings
- 10 Integrating Spectral into a CI Pipeline
- 11 Best Practices
- 12 Common Mistakes
- 13 When Should You Use Spectral?
- 14 Why Developers Love It
- 15 Final Thoughts
What Is Spectral?
Spectral is a linter. But not for your TypeScript code.
It lints:
- OpenAPI specs
- AsyncAPI specs
- JSON files
- YAML files
Think of it as ESLint. But for API definitions.
If your OpenAPI file says something weird like this:
- Missing descriptions
- No response examples
- Bad naming conventions
- Inconsistent error formats
Spectral will gently (or aggressively) point it out.
Why Use Spectral with TypeScript?
You could just run Spectral from the command line. And that’s fine.
But when you use Spectral inside a TypeScript project, things get more powerful.
Now you can:
- Lint dynamically generated schemas
- Integrate validation into build tools
- Create automated API pipelines
- Write custom rules with full type safety
And let’s be honest. We like type safety. It makes us feel warm inside.
Step 1: Install Spectral
Start simple.
npm install @stoplight/spectral-core
npm install @stoplight/spectral-rulesets
npm install @stoplight/spectral-parsers
You might also install:
npm install @stoplight/spectral-formats
Now you’re ready.
Step 2: Basic Usage in TypeScript
Here’s a minimal example.
import { Spectral } from "@stoplight/spectral-core";
import { oas } from "@stoplight/spectral-rulesets";
import { Document, Parsers } from "@stoplight/spectral-core";
async function run() {
const spectral = new Spectral();
spectral.setRuleset(oas);
const apiDefinition = `
openapi: 3.0.0
info:
title: My API
version: 1.0.0
paths: {}
`;
const document = new Document(apiDefinition, Parsers.Yaml);
const results = await spectral.run(document);
console.log(results);
}
run();
What’s happening here?
- We create a Spectral instance
- We load the built-in OpenAPI ruleset
- We parse a YAML string
- We run the linter
- We print the issues
Simple. Clean. Effective.
What Do the Results Look Like?
Spectral returns an array of results.
Each result contains:
- Code – which rule failed
- Message – what went wrong
- Path – where it happened
- Severity – how bad it is
Example result:
{
code: "info-description",
message: "Info object must have a description.",
path: ["info"],
severity: 1
}
Now you can:
- Fail a CI build if severity is high
- Log custom messages
- Group errors by type
You are in control.
Step 3: Using Custom Rules
This is where things get exciting.
You can define your own rules.
Let’s say every endpoint must have a summary. No exceptions.
spectral.setRules({
"require-operation-summary": {
description: "Operations must have a summary",
given: "$.paths[*][*]",
then: {
field: "summary",
function: "truthy"
},
severity: 1
}
});
Now Spectral will complain if any operation is missing a summary.
This is fantastic for:
- Large teams
- Shared API standards
- Enterprise consistency
Understanding “given” and “then”
Every rule has two key parts.
given – where to look.
then – what to check.
The given field uses JSONPath. It’s like a treasure map for your schema.
Example:
$.paths[*][*]→ every operation$.components.schemas[*]→ every schema
The then part defines the validation function.
Common built-in functions:
- truthy – must exist
- pattern – must match regex
- enumeration – must match allowed values
- schema – must match JSON Schema
It’s like building logic blocks.
Step 4: Creating Custom Functions
Want more power?
Write your own validation function in TypeScript.
import { createRulesetFunction } from "@stoplight/spectral-core";
const startsWithUppercase = createRulesetFunction(
{
input: { type: "string" }
},
function (input) {
if (!input[0] || input[0] !== input[0].toUpperCase()) {
return [
{
message: "Must start with uppercase letter"
}
];
}
}
);
Then use it in your rules:
spectral.setRules({
"summary-uppercase": {
given: "$.paths[*][*].summary",
then: {
function: startsWithUppercase
}
}
});
Now your API summaries must be classy. Proper. Uppercase.
TypeScript helps here.
You get:
- Auto-complete
- Type checking
- Safer refactoring
Step 5: Linting Files Instead of Strings
Usually, you’ll lint actual files.
import { readFileSync } from "fs";
const file = readFileSync("./openapi.yaml", "utf8");
const document = new Document(file, Parsers.Yaml);
const results = await spectral.run(document);
Perfect for:
- Pre-commit hooks
- CLI tools
- Build scripts
You can even wrap this in a custom command.
Integrating Spectral into a CI Pipeline
This is where Spectral shines.
In your CI system:
- Load your API spec
- Run Spectral
- Fail if errors exist
Example:
if (results.some(r => r.severity === 0)) {
process.exit(1);
}
Now broken API definitions never reach production.
Your future self will thank you.
Best Practices
Let’s keep things clean and practical.
1. Start with Built-In Rules
Don’t reinvent the wheel. Use the OpenAPI ruleset first.
2. Add Team-Specific Rules
Enforce naming conventions. Require examples. Standardize error formats.
3. Keep Rules Small and Clear
One rule. One responsibility.
4. Use TypeScript Types Everywhere
Type your inputs. Type your outputs. Catch mistakes early.
5. Version Control Your Ruleset
Treat it like production code. Because it is.
Common Mistakes
Let’s avoid pain.
- Overloading rules – too many checks in one rule
- Ignoring warnings – they exist for a reason
- Not documenting custom rules
- Skipping CI integration
Spectral works best when it’s automatic. Not optional.
When Should You Use Spectral?
Use Spectral when:
- You publish APIs to other teams
- You maintain public APIs
- Your documentation must stay consistent
- You care about quality
If your API is “just for internal use,” you still benefit.
Because messy APIs grow fast. Very fast.
Why Developers Love It
Spectral is:
- Flexible
- Scriptable
- TypeScript-friendly
- CI-ready
It doesn’t force a rigid structure. It gives you building blocks.
You design your own API quality system.
Final Thoughts
Spectral with TypeScript is a powerful combo.
You get:
- Automated API validation
- Customizable rules
- Type-safe extensions
- Clean CI integration
It’s not complicated.
Install it. Run it. Add a few rules. Improve gradually.
Over time, your APIs become clearer. More predictable. More professional.
And the best part?
Most mistakes get caught before anyone else sees them.
That’s the kind of quiet productivity boost every developer loves.
Now go lint your APIs. Your future documentation will look amazing.
