npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tsops

v1.8.0

Published

TypeScript-first toolkit for planning, building, and deploying to Kubernetes

Readme

tsops

TypeScript-first toolkit for planning, building, and deploying to Kubernetes.

Installation

npm install -D tsops
# or
pnpm add -D tsops
# or
yarn add -D tsops

Or install globally:

npm install -g tsops
# or
pnpm add -g tsops

Usage

tsops <command> [options]

Commands

plan

Resolves the configuration into a deployment plan and prints the results.

tsops plan
tsops plan --namespace prod
tsops plan --app api
tsops plan --namespace prod --app api

Output example:

- api @ prod (us) -> ghcr.io/org/api:abc123, host=api.example.com
- frontend @ prod (us) -> ghcr.io/org/frontend:abc123

build

Builds and pushes Docker images for configured apps.

tsops build
tsops build --app api
tsops build --app api --namespace prod  # Determines dev/prod platform

Incremental builds (monorepo optimization):

# Build only apps affected by changes since last commit
tsops build --filter HEAD^1

# Build only apps affected by changes compared to main branch
tsops build --filter main

# Build only apps affected by changes compared to origin/main
tsops build --filter origin/main

# Force rebuild even if image exists in registry
tsops build --force

The --filter flag compares changed files against the specified git reference and builds only applications whose build.context directory contains changed files. This is especially useful in CI/CD pipelines for monorepo projects where you want to build only what changed.

Output example:

📊 Detected 3 changed file(s) compared to HEAD^1
Building 1 affected app(s): api

✅ Built images:
   • api: ghcr.io/org/api:abc123

deploy

Generates Kubernetes manifests and applies them using kubectl.

tsops deploy
tsops deploy --namespace prod
tsops deploy --app api
tsops deploy --namespace prod --app api

Output example:

- api @ prod
  • Deployment/api
  • Service/api
  • Ingress/api
  • Certificate/api-tls

Options

All commands support:

  • -n, --namespace <name> – Target a single namespace
  • --app <name> – Target a single app
  • -c, --config <path> – Path to config file (default: tsops.config)
  • --dry-run – Log actions without executing external commands

Build-specific options:

  • --filter <ref> – Build only apps affected by changes compared to git ref (e.g., HEAD^1, main, origin/main)
  • -f, --force – Force rebuild even if image already exists in registry

Help

tsops --help
tsops plan --help
tsops build --help
tsops deploy --help

Configuration Files

The CLI looks for configuration files in this order:

  1. Specified path via --config
  2. tsops.config (tries .ts, .mts, .cts, .js, .mjs, .cjs extensions)

TypeScript Configs

For TypeScript configs, you need a runtime that can execute them:

# Using tsx
pnpm tsx node_modules/.bin/tsops plan --config tsops.config.ts

# Or if you have tsx globally
tsops plan  # Will work with tsops.config.ts

Alternatively, compile your config to JavaScript first:

tsc tsops.config.ts
tsops plan --config tsops.config.js

Environment Variables

Some tag strategies require environment variables:

  • GIT_SHA – Used by tagStrategy: 'git-sha'
  • GIT_TAG – Used by tagStrategy: 'git-tag'

Example:

export GIT_SHA=$(git rev-parse HEAD)
tsops build --app api

Examples

Full Workflow

# 1. Plan what will be deployed
tsops plan --namespace prod

# 2. Build images for production
export GIT_SHA=$(git rev-parse HEAD)
tsops build

# 3. Deploy to production
tsops deploy --namespace prod

# 4. Deploy only API to staging (with dry-run)
tsops deploy --namespace staging --app api --dry-run

CI/CD Integration

Basic workflow:

# .github/workflows/deploy.yml
- name: Deploy to production
  env:
    GIT_SHA: ${{ github.sha }}
  run: |
    pnpm tsops build --app api
    pnpm tsops deploy --namespace prod --app api

Optimized monorepo workflow (build only changed apps):

# .github/workflows/build-changed.yml
name: Build Changed Apps

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Required for git diff
      
      - name: Setup pnpm
        uses: pnpm/action-setup@v2
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'
      
      - name: Install dependencies
        run: pnpm install
      
      - name: Build changed apps
        env:
          GIT_SHA: ${{ github.sha }}
          DOCKER_REGISTRY: ghcr.io/${{ github.repository_owner }}
          DOCKER_USERNAME: ${{ github.actor }}
          DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Build only apps affected by changes in this PR/commit
          pnpm tsops build --filter ${{ github.event.pull_request.base.sha || 'HEAD^1' }}
      
      - name: Deploy changed apps
        if: github.ref == 'refs/heads/main'
        run: |
          pnpm tsops deploy --namespace prod

Using with Turborepo (recommended for monorepos):

// turbo.json
{
  "tasks": {
    "tsops:build": {
      "dependsOn": ["^build"],
      "inputs": ["src/**", "Dockerfile", "$DOCKER_REGISTRY"],
      "cache": false  // Docker builds have side effects
    }
  }
}
# In CI: Build only packages/apps affected by changes
turbo run build --filter=[HEAD^1]

# Then build Docker images for changed apps
pnpm tsops build --filter HEAD^1

Configuration Example

// tsops.config.ts
import { defineConfig } from 'tsops'

export default defineConfig({
  project: 'myapp',
  
  namespaces: {
    dev: {
      domain: 'dev.myapp.com',
      replicas: 1
    },
    prod: {
      domain: 'myapp.com',
      replicas: 3
    }
  },
  
  clusters: {
    'us-cluster': {
      apiServer: 'https://k8s.us.example.com',
      context: 'us-k8s',
      namespaces: ['dev', 'prod']
    }
  },
  
  images: {
    registry: 'ghcr.io/myorg',
    tagStrategy: 'git-sha'
  },
  
  apps: {
    api: {
      ingress: ({ domain }) => `api.${domain}`,
      build: {
        type: 'dockerfile',
        context: '.',
        dockerfile: 'Dockerfile'
      },
      env: ({ replicas }) => ({
        NODE_ENV: replicas > 1 ? 'production' : 'development',
        REPLICAS: String(replicas)
      })
    }
  }
})

Related Packages

  • @tsops/core – Core library with programmatic API
  • @tsops/k8 – Kubernetes manifest builders

Development

pnpm build       # Compile TypeScript

The CLI binary is defined in package.json:

{
  "bin": {
    "tsops": "./dist/index.js"
  }
}