
Security News
The Changelog Podcast: Practical Steps to Stay Safe on npm
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.
@tryloop/oats
Advanced tools
๐พ 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.
Automatically sync OpenAPI specs to TypeScript clients. No manual steps, just real-time updates.
# Install
npm install -D @tryloop/oats
# Initialize config
npx oats init
# Start development
npx oats start
OATS eliminates the manual 6-step workflow of syncing OpenAPI changes:
With OATS: Change your API โ Everything syncs automatically โจ
OATS supports multiple configuration formats:
{
"$schema": "node_modules/@tryloop/oats/schema/oats.schema.json",
"services": {
"backend": {
"path": "./backend",
"port": 8000,
"startCommand": "npm run dev",
"apiSpec": {
"path": "/api/openapi.json"
}
},
"client": {
"path": "./api-client",
"packageName": "@myorg/api-client",
"generator": "@hey-api/openapi-ts"
},
"frontend": {
"path": "./frontend",
"port": 3000,
"startCommand": "npm run dev"
}
}
}
import { defineConfig } from '@tryloop/oats'
export default defineConfig({
services: {
backend: {
path: './backend',
port: 8000,
startCommand: 'npm run dev',
apiSpec: {
path: '/api/openapi.json'
}
},
client: {
path: './api-client',
packageName: '@myorg/api-client',
generator: '@hey-api/openapi-ts'
},
frontend: {
path: './frontend',
port: 3000,
startCommand: 'npm run dev'
}
}
})
Note: TypeScript configs are fully supported. OATS includes esbuild for consistent transpilation across all environments.
const { defineConfig } = require('@tryloop/oats')
module.exports = defineConfig({
// Same structure as TypeScript config
})
| Language | Frameworks | OpenAPI Support |
|---|---|---|
| Node.js | Express, Fastify, NestJS, Koa, Hapi | Static files or runtime generation |
| Python | FastAPI, Flask, Django REST | Runtime endpoints (e.g., /openapi.json) |
All major frameworks: React, Vue, Angular, Svelte, Next.js, Nuxt, Remix
generateCommand)| Command | Description | Options |
|---|---|---|
oats start | Start all services with auto-sync | --config, --quiet, --init-gen |
oats init | Create configuration interactively | --force, --yes |
oats validate | Validate configuration file | --config |
oats detect | Auto-detect project structure | - |
{
"services": {
"backend": {
"path": "../backend",
"port": 8000,
"runtime": "python",
"python": {
"virtualEnv": ".venv"
},
"startCommand": ".venv/bin/uvicorn main:app --reload",
"apiSpec": {
"path": "/openapi.json"
}
},
"client": {
"path": "../api-client",
"packageName": "@myapp/api",
"generator": "@hey-api/openapi-ts"
},
"frontend": {
"path": "./",
"port": 3000,
"startCommand": "npm start"
}
}
}
{
"services": {
"backend": {
"path": "./apps/api",
"port": 3333,
"startCommand": "nx serve api",
"apiSpec": {
"path": "swagger.json"
}
},
"client": {
"path": "./packages/api-client",
"packageName": "@myapp/api-client",
"generator": "custom",
"generateCommand": "yarn openapi-ts"
},
"frontend": {
"path": "./apps/web",
"port": 4200,
"startCommand": "nx serve web"
}
}
}
| Property | Description | Required |
|---|---|---|
path | Path to service directory | โ |
port | Port number (backend/frontend) | โ ๏ธ |
startCommand | Command to start service | โ |
runtime | "node" or "python" | โ |
apiSpec.path | Path to OpenAPI spec | โ |
โ ๏ธ Port is required for backend/frontend services, but not for client
| Option | Default | Description |
|---|---|---|
strategy | "smart" | "smart" or "aggressive" |
debounceMs | 1000 | Delay before regenerating |
autoLink | true | Auto-link packages |
pollingInterval | 5000 | For runtime API specs |
| Option | Default | Description |
|---|---|---|
level | "info" | "debug", "info", "warn", "error" |
colors | true | Enable colored output |
timestamps | false | Show timestamps in logs |
showServiceOutput | true | Display output from services |
OATS automatically handles port conflicts. To disable:
{
"services": {
"backend": {
"env": {
"OATS_AUTO_KILL_PORTS": "false"
}
}
}
}
npm ls @myorg/api-clientvite.config.tspackageName matches your client's package.jsonOATS automatically injects your backend URL into your frontend environment:
// Your frontend code
const API_URL = import.meta.env.VITE_OATS_BACKEND_BASE_URL || 'https://api.production.com'
How it works:
VITE_OATS_BACKEND_BASE_URLREACT_APP_OATS_BACKEND_BASE_URLNEXT_PUBLIC_OATS_BACKEND_BASE_URLVUE_APP_OATS_BACKEND_BASE_URLNo configuration needed - it just works!
OATS fully supports TypeScript configs (.ts files) with built-in transpilation:
export default defineConfig({...})Use npx or add to scripts:
{
"scripts": {
"dev:sync": "oats start"
}
}
Contributions welcome! See CONTRIBUTING.md for details.
# Clone repo
git clone https://github.com/loopkitchen/oats.git
# Install dependencies
yarn install
# Run tests
yarn test
# Start development
yarn dev
MIT ยฉ Hari Shekhar
FAQs
๐พ 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.
We found that @tryloop/oats demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.ย It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.