Gathering detailed insights and metrics for oatsjs
Gathering detailed insights and metrics for oatsjs
Gathering detailed insights and metrics for oatsjs
Gathering detailed insights and metrics for oatsjs
@tryloop/oats
🌾 OATS - OpenAPI TypeScript Sync. The missing link between your OpenAPI specs and TypeScript applications. Automatically watch, generate, and sync TypeScript clients from your API definitions.
@loopkitchen/oats
🌾 OATS - OpenAPI TypeScript Sync. The missing link between your OpenAPI specs and TypeScript applications. Automatically watch, generate, and sync TypeScript clients from your API definitions.
npm install oatsjs
Typescript
Module System
Min. Node Version
Node Version
NPM Version
TypeScript (96.19%)
JavaScript (3.81%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
20 Commits
5 Branches
2 Contributors
Updated on Jun 30, 2025
Latest Version
2.2.0
Package Id
oatsjs@2.2.0
Unpacked Size
315.34 kB
Size
66.39 kB
File Count
54
NPM Version
10.8.2
Node Version
20.19.2
Published on
Jun 30, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
12
21
Stop manually syncing your OpenAPI specs with TypeScript clients. OATS watches your backend API changes and automatically regenerates TypeScript clients in real-time.
You're building a TypeScript full-stack app with:
Every time you change your backend API, you need to:
That's 6 manual steps for every API change! 😱
OATS automates this entire workflow. Just run:
1npx oatsjs start
Now when you change your backend API, OATS automatically:
1# In your frontend project (or monorepo root) 2npm install --save-dev oatsjs 3# or 4yarn add -D oatsjs
Create oats.config.json
in your project root:
1{ 2 "services": { 3 "backend": { 4 "path": "./backend", 5 "port": 8000, 6 "startCommand": "npm run dev", 7 "apiSpec": { 8 "path": "/api/openapi.json" // Runtime endpoint (recommended) 9 } 10 }, 11 "client": { 12 "path": "./api-client", 13 "generator": "@hey-api/openapi-ts", 14 "packageName": "@myorg/api-client" 15 }, 16 "frontend": { 17 "path": "./frontend", 18 "port": 3000, 19 "startCommand": "npm run dev" 20 } 21 } 22}
Minimal config example (OATS uses smart defaults for everything else):
1{ 2 "services": { 3 "backend": { 4 "path": "./backend", 5 "startCommand": "npm run dev", 6 "apiSpec": { "path": "/api/openapi.json" } 7 }, 8 "client": { 9 "path": "./api-client", 10 "generator": "@hey-api/openapi-ts" 11 } 12 } 13}
Note: Frontend configuration is optional! If you're running oatsjs from your frontend project, it will just sync the backend and client without starting another frontend server.
port
and startCommand
are required for frontendWhen you do configure a frontend service, both port
and startCommand
are required because:
npm start
, yarn dev
, ng serve
)1{ 2 "scripts": { 3 "dev": "vite", 4 "dev:oats": "oatsjs start" // Add this 5 } 6}
1yarn dev:oats
That's it! Your entire stack is now running with automatic API synchronization.
1# npm 2npm install --save-dev oatsjs 3 4# yarn 5yarn add -D oatsjs 6 7# pnpm 8pnpm add -D oatsjs
OATS uses intelligent comparison algorithms to detect meaningful changes in your OpenAPI specs:
Works with any OpenAPI client generator:
@hey-api/openapi-ts
swagger-typescript-api
openapi-generator-cli
1{ 2 "services": { 3 "backend": { 4 "path": "../backend", // Path to backend (relative or absolute) 5 "port": 4000, // Backend dev server port (optional) 6 "startCommand": "yarn dev", // Command to start backend 7 "runtime": "node", // Runtime: "node" (default) or "python" 8 "python": { // Python-specific config (only if runtime is "python") 9 "virtualEnv": "venv", // Virtual environment directory 10 "packageManager": "pip", // Package manager: "pip", "poetry", or "pipenv" 11 "executable": "python" // Python executable (default: "python") 12 }, 13 "apiSpec": { 14 "path": "src/swagger.json" // Path to OpenAPI spec (relative to backend) 15 } 16 }, 17 "client": { 18 "path": "../api-client", // Path to TypeScript client project 19 "packageName": "@myorg/api", // NPM package name of the client 20 "generator": "custom", // Generator type (see below) 21 "generateCommand": "yarn generate", // Command to generate client 22 "buildCommand": "yarn build", // Command to build client 23 "linkCommand": "yarn link" // Command to link for local dev 24 }, 25 "frontend": { // OPTIONAL - only if you want oatsjs to start it 26 "path": ".", // Path to frontend 27 "port": 5173, // REQUIRED - Must match your dev server port 28 "startCommand": "yarn dev", // REQUIRED - Your dev server command 29 "packageLinkCommand": "yarn link" // Command to link packages 30 } 31 }, 32 "sync": { // OPTIONAL - defaults shown below 33 "strategy": "smart", // "smart" or "always" - smart skips if no changes 34 "debounceMs": 1000, // Wait time before regenerating (ms) 35 "autoLink": true, // Automatically link packages after generation 36 "notifications": false, // Desktop notifications for sync events 37 "retryAttempts": 3, // Retry failed operations 38 "retryDelayMs": 2000, // Delay between retries (ms) 39 "runInitialGeneration": false, // Generate client on startup 40 "ignore": ["**/node_modules/**"] // Paths to ignore in file watching 41 }, 42 "log": { // OPTIONAL - logging configuration 43 "level": "info", // Log level: debug, info, warn, error 44 "colors": true, // Use colored output 45 "timestamps": false, // Show timestamps in logs 46 "showServiceOutput": true, // Show backend/frontend console output 47 "quiet": false, // Quiet mode - only essential messages 48 "file": "./oats.log" // Optional log file path 49 } 50}
OATS automatically handles port conflicts by default. When a port is already in use:
To disable automatic port killing:
1{ 2 "sync": { 3 "autoKillConflictingPorts": false // Default: true 4 } 5}
Enable performance tracking and optimizations:
1{ 2 "sync": { 3 "showStepDurations": true, // Show timing for each sync step 4 "pollingInterval": 3000 // Polling interval for runtime specs (ms) 5 } 6}
For Python backends like FastAPI that generate OpenAPI specs at runtime:
Example for FastAPI:
1{ 2 "apiSpec": { 3 "path": "/openapi.json" // Fetched from http://localhost:8000/openapi.json 4 } 5}
If you're running oatsjs from your frontend project, here's the minimal config:
1{ 2 "services": { 3 "backend": { 4 "path": "../backend", 5 "startCommand": "yarn dev", 6 "apiSpec": { 7 "path": "src/swagger.json" 8 } 9 }, 10 "client": { 11 "path": "../api-client", 12 "packageName": "@myorg/api-client", 13 "generator": "custom", 14 "generateCommand": "yarn generate", 15 "buildCommand": "yarn build" 16 } 17 } 18}
1{ 2 "client": { 3 "generator": "custom", 4 "generateCommand": "yarn generate", // Your existing generate command 5 "buildCommand": "yarn build" 6 } 7}
1{ 2 "client": { 3 "generator": "@hey-api/openapi-ts", 4 "generatorConfig": { 5 "input": "./swagger.json", 6 "output": "./src", 7 "client": "axios" 8 } 9 } 10}
oatsjs start
Start all services with automatic synchronization.
1oatsjs start [options] 2 3Options: 4 --init-gen Run initial client generation on startup 5 -c, --config Path to config file (default: oats.config.json) 6 --quiet Quiet mode - only show essential messages 7 --no-colors Disable colored output
Examples:
1# Start with default config 2oatsjs start 3 4# Generate client before starting (useful for first run) 5oatsjs start --init-gen 6 7# Use custom config file 8oatsjs start --config my-oats.config.json 9 10# Quiet mode - only oatsjs messages, no service output 11oatsjs start --quiet 12 13# Disable colors 14oatsjs start --no-colors
oatsjs init
Interactively create a configuration file.
1oatsjs init [options] 2 3Options: 4 -f, --force Overwrite existing configuration 5 -y, --yes Use defaults without prompting
oatsjs validate
Check if your configuration is valid.
1oatsjs validate [options] 2 3Options: 4 -c, --config Path to config file
oatsjs detect
Auto-detect your project structure and create config.
1oatsjs detect
Note: This will scan your project and try to find:
Project Structure:
my-project/
├── backend/ # FastAPI backend
├── api-client/ # Generated TypeScript client
└── frontend/ # React app
oats.config.json:
1{ 2 "services": { 3 "backend": { 4 "path": "../backend", 5 "port": 8000, 6 "runtime": "python", 7 "python": { 8 "virtualEnv": "venv" 9 }, 10 "startCommand": "source venv/bin/activate && uvicorn main:app --reload --port 8000", 11 "apiSpec": { 12 "path": "runtime:/openapi.json" // FastAPI generates at runtime 13 } 14 }, 15 "client": { 16 "path": "../api-client", 17 "packageName": "@myapp/api-client", 18 "generator": "@hey-api/openapi-ts", 19 "generateCommand": "npm run generate", 20 "buildCommand": "npm run build" 21 }, 22 "frontend": { 23 "path": "./", 24 "port": 3000, 25 "startCommand": "npm start" 26 } 27 } 28}
Project Structure:
my-project/
├── backend/ # Express API
├── api-client/ # Generated TypeScript client
└── frontend/ # React app
oats.config.json:
1{ 2 "services": { 3 "backend": { 4 "path": "../backend", 5 "port": 4000, 6 "startCommand": "npm run dev", 7 "apiSpec": { 8 "path": "src/swagger.json" 9 } 10 }, 11 "client": { 12 "path": "../api-client", 13 "packageName": "@myapp/api-client", 14 "generator": "custom", 15 "generateCommand": "npm run generate", 16 "buildCommand": "npm run build", 17 "linkCommand": "npm link" 18 }, 19 "frontend": { 20 "path": ".", 21 "port": 3000, 22 "startCommand": "npm start", 23 "packageLinkCommand": "npm link" 24 } 25 } 26}
Project Structure:
my-monorepo/
├── apps/
│ ├── api/ # NestJS backend
│ └── web/ # Next.js frontend
└── packages/
└── api-client/ # Generated client
oats.config.json:
1{ 2 "services": { 3 "backend": { 4 "path": "./apps/api", 5 "port": 3333, 6 "startCommand": "nx serve api", 7 "apiSpec": { 8 "path": "swagger.json" 9 } 10 }, 11 "client": { 12 "path": "./packages/api-client", 13 "packageName": "@myapp/api-client", 14 "generator": "custom", 15 "generateCommand": "yarn openapi-ts", 16 "buildCommand": "yarn build" 17 }, 18 "frontend": { 19 "path": "./apps/web", 20 "port": 4200, 21 "startCommand": "nx serve web" 22 } 23 } 24}
1{ 2 "services": { 3 "backend": { 4 "path": "../services/main-api", 5 "port": 4000, 6 "startCommand": "docker-compose up api", 7 "apiSpec": { 8 "path": "docs/openapi.yaml" 9 } 10 }, 11 "client": { 12 "path": "../packages/main-api-client", 13 "packageName": "@company/main-api", 14 "generator": "custom", 15 "generateCommand": "yarn codegen", 16 "buildCommand": "yarn tsc" 17 }, 18 "frontend": { 19 "path": "../apps/dashboard", 20 "port": 8080, 21 "startCommand": "yarn serve" 22 } 23 }, 24 "sync": { 25 "debounceMs": 2000, // Longer debounce for larger APIs 26 "retryAttempts": 5 27 } 28}
Solution: OATS now automatically kills processes using required ports! If you still have issues:
1{ 2 "services": { 3 "backend": { "port": 4001 }, // Change to available port 4 "frontend": { "port": 5174 } // Change to available port 5 } 6}
Solution: OATS now includes Vite HMR integration! Check that:
yarn link
or npm link
)vite.config.ts
:1export default defineConfig({ 2 optimizeDeps: { 3 exclude: ['@yourorg/api-client'] // Exclude linked packages 4 } 5})
Solution: Use npx or add to package.json scripts:
1# Direct usage 2npx oatsjs start 3 4# Or add to package.json 5"scripts": { 6 "dev:sync": "oatsjs start" 7}
1. Start: OATS starts your backend, frontend, and watches for changes
↓
2. Port Detection: Uses port-based detection to know when services are ready
↓
3. Watch: File watcher monitors your OpenAPI spec file
↓
4. Detect: When spec changes, OATS compares with previous version
↓
5. Copy: Copies swagger.json to client directory for local generation
↓
6. Generate: Run your generator command with local spec
↓
7. Build: Build the TypeScript client package
↓
8. Link: Ensure client is linked to frontend (yarn/npm link)
↓
9. HMR Trigger: Touch .oats-sync file to trigger Vite hot-reload
↓
10. Reload: Frontend hot-reloads with new types
Robust Architecture:
Smart Detection: OATS uses intelligent comparison to avoid unnecessary regeneration:
1# Make API change 2# Wait... 3# Manually copy swagger.json 4cp ../backend/swagger.json ../client/ 5 6# Generate client 7cd ../client && yarn generate 8 9# Build client 10yarn build 11 12# Link to frontend 13yarn link 14cd ../frontend && yarn link "@myorg/api-client" 15 16# Restart frontend 17# Repeat for every API change... 🔄
1# Just run once 2yarn dev:oats 3 4# Make API changes 5# Everything syncs automatically! ✨
Feature | Manual Process | Build Scripts | OATS |
---|---|---|---|
Automatic sync | ❌ | ❌ | ✅ |
Smart detection | ❌ | ❌ | ✅ |
Zero config | ❌ | ❌ | ✅ |
Hot reload | ❌ | Partial | ✅ |
Error recovery | ❌ | ❌ | ✅ |
Multi-service | ❌ | Complex | ✅ |
OATS is built with production reliability in mind:
We welcome contributions! Please see our Contributing Guide for details.
1# Clone the repository 2git clone https://github.com/shekhardtu/oatsjs.git 3 4# Install dependencies 5npm install 6 7# Run tests 8npm test 9 10# Start development 11npm run dev
MIT © Hari Shekhar
OATS is inspired by the challenges faced by developers working with OpenAPI specifications and TypeScript in modern microservices architectures. Special thanks to:
Made with ❤️ and 🌾 for developers who deserve better tooling
GitHub • npm • Issues • Discussions
No vulnerabilities found.
No security vulnerabilities found.