Skip to content

tsopsTypeScript-first deployment toolkit

Deploy containerized applications with confidence using type-safe configuration

tsops logo

Installation

bash
npm install tsops
bash
pnpm add tsops
bash
yarn add tsops
bash
bun add tsops

Quick Example

Create this file at the root of your project as tsops.config.ts.

typescript
import { defineConfig } from 'tsops'

export default defineConfig({
  project: 'my-app',
  
  namespaces: {
    dev: { domain: 'dev.example.com', production: false },
    prod: { domain: 'example.com', production: true },
  },
  
  clusters: {
    local: {
      apiServer: 'https://kubernetes.docker.internal:6443',
      context: 'docker-desktop',
      namespaces: ['dev']
    }
  },
  
  images: {
    registry: 'ghcr.io/yourorg',
    tagStrategy: 'git-sha'
  },
  
  apps: {
    web: {
      ingress: ({ domain }) => ({ domain }),
      build: {
        type: 'dockerfile',
        context: './web',
        dockerfile: './web/Dockerfile'
      },
      env: ({ production }) => ({
        NODE_ENV: production ? 'production' : 'development'
        // ✅ In your app: config.url('otelCollector', 'service')
      })
    },
    api: {
      ingress: ({ domain }) => ({ domain: `api.${domain}` }),
      build: {
        type: 'dockerfile',
        context: './api',
        dockerfile: './api/Dockerfile'
      },
      env: () => ({
        // ✅ In your app: config.url('otelCollector', 'service')
      })
    },
    otelCollector: {
      image: 'otel/opentelemetry-collector:latest'
    }
  }
})

Use in your app (runtime)

Import your tsops.config.ts to access resolved endpoints and configuration at runtime.

ts
// Example: Using config in your app
import config from './tsops.config'

// ✅ Public ingress URL (external traffic)
const publicApiUrl = config.url('api', 'ingress')
// e.g. https://api.dev.example.com

// ✅ Service-to-service communication (internal)
const backendUrl = config.url('api', 'service')  // http://api
// or full DNS:
const backendUrl = config.url('api', 'cluster')  // http://api.prod.svc.cluster.local

export default async function Page() {
  const res = await fetch(`${backendUrl}/api/message`, { cache: 'no-store' })
  const data = res.ok ? await res.json() : { message: `HTTP ${res.status}` }
  return (
    <main>
      <h1>Frontend</h1>
      <p>Backend says: {data.message}</p>
    </main>
  )
}

Why tsops?

🎯
TypeScript-First
Author deployment strategy in TypeScript with full IntelliSense, literal inference, and compile-time guarantees.
📋
Diff-First Planner
Use planWithChanges() or the CLI to validate namespaces, view manifest diffs, and spot errors before deploy.
Smart Helpers
Access helpers like secret(), configMap(), and namespace variables directly inside app definitions.
🔒
Secret Guardrails
Catch placeholder values and missing keys automatically; reuse existing cluster secrets when appropriate.
🌐
Auto Networking
Generate ingress and TLS certificates with automatic protocol detection (http for local, https for production).
🔁
Runtime Reuse
Import the same config at runtime, switch namespaces with TSOPS_NAMESPACE, and resolve endpoints on demand.
⚙️
CI/CD Ready
Git-aware environment providers, deterministic image tags, and --dry-run flows slot neatly into pipelines.
🧹
Drift-Free Deployments
Automated orphan detection and cleanup keep your cluster in sync with your declared configuration.

What People Say

"tsops transformed our deployment workflow. No more YAML hell, just clean TypeScript configuration."

Production User

"The secret validation and type-safe configuration saved us hours of debugging."

DevOps Engineer

"Secret validation caught so many issues before they hit production. This tool pays for itself."

Platform Team Lead

Ready to Get Started?

📚 Read the Guide

Learn the basics and deploy your first app.

💡 See Examples

Explore monorepo, fullstack, and observability setups.

🔧 API Reference

Full API for helpers, types, and CLI.

Released under the MIT License.