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

@nelm/chart-ts-sdk

v0.1.6

Published

The Nelm TypeScript SDK for generating Kubernetes manifests with TypeScript instead of Helm templates

Readme

@nelm/chart-ts-sdk

TypeScript SDK for generating Kubernetes manifests with TypeScript instead of Helm templates.

Runs under Deno. Reads a YAML render context from a file, passes it to your handler, and writes the resulting manifests as a multi-document YAML file.

Install

npm install @nelm/chart-ts-sdk

Quick Start

import {RenderContext, RenderResult, render} from "@nelm/chart-ts-sdk";

function generate($: RenderContext): RenderResult {
    return {
        manifests: [
            {
                apiVersion: 'apps/v1',
                kind: 'Deployment',
                metadata: {
                    name: $.Release.Name,
                    namespace: $.Release.Namespace,
                    labels: {
                        'app.kubernetes.io/name': $.Chart.Name,
                        'app.kubernetes.io/version': $.Chart.AppVersion,
                        'app.kubernetes.io/instance': $.Release.Name,
                    },
                },
                spec: {
                    replicas: $.Values.replicaCount ?? 1,
                    selector: {
                        matchLabels: {
                            'app.kubernetes.io/name': $.Chart.Name,
                            'app.kubernetes.io/instance': $.Release.Name,
                        },
                    },
                    template: {
                        metadata: {
                            labels: {
                                'app.kubernetes.io/name': $.Chart.Name,
                                'app.kubernetes.io/instance': $.Release.Name,
                            },
                        },
                        spec: {
                            containers: [
                                {
                                    name: $.Chart.Name,
                                    image: `${$.Values.image?.repository}:${$.Values.image?.tag}`,
                                    ports: [
                                        {
                                            name: 'http',
                                            containerPort: $.Values.service?.port ?? 80,
                                        },
                                    ],
                                },
                            ],
                        },
                    },
                },
            },
        ],
    };
}

render(generate);

How It Works

render is the entry point. It:

  1. Parses CLI arguments --input-file and --output-file
  2. Reads the input file as YAML and deserializes it into a RenderContext
  3. Calls your handler with the context
  4. Validates that the result contains a non-empty manifests array
  5. Serializes manifests into a multi-document YAML format separated by --- and writes the output file (or print to console if, no output file is specified).
deno run render.ts --input-file context.yaml --output-file manifests.yaml

API Reference

render(handler: RenderHandler): Promise<void>

Runs the render pipeline. Accepts a handler function that receives a render context and returns RenderResult.

RenderHandler

type RenderHandler<CtxType extends BaseRenderContext = RenderContext> = ($: CtxType) => Promise<RenderResult> | RenderResult;

The handler can be sync or async. The generic parameter allows using a narrower context type like WerfRenderContext.

RenderContext

The context passed to your handler. By convention, the parameter is named $.

interface RenderContext<ValuesType = Record<string, any>> extends BaseRenderContext {
    Values: ValuesType;                // Merged values (values.yaml + overrides)
    Release: Release;                  // Release metadata
    Chart: ChartMetadata;              // Chart.yaml contents
    Capabilities: Capabilities;        // Cluster capabilities
    Runtime: Record<string, any>;      // Runtime-specific data
    Files: Record<string, Uint8Array>; // Raw chart files
}

WerfRenderContext

Render context with werf service values pre-typed. Use this when deploying with werf.

interface WerfRenderContext<ValuesType = Record<string, any>> {
    Values: WerfServiceValues & ValuesType;  // Werf service values merged with user values
    Release: Release;
    Chart: ChartMetadata;
    Capabilities: Capabilities;
    Runtime: Record<string, any>;
    Files: Record<string, Uint8Array>;
}

interface WerfServiceValues extends Record<string, any> {
    global: {
        werf: WerfInfo;                // Werf project metadata with typed images
    };
}

interface WerfInfo {
    name: string;              // Project name
    version: string;           // Werf version
    repo: string;              // Container registry repo
    commit: {
        hash: string;
        date: {
            human: string;     // Human-readable date string
            unix: number;      // Unix timestamp
        };
    };
    images: Record<string, WerfImageInfo>;
    namespace?: string;
    env?: string;
    is_stub?: boolean;
    stub_image?: string;
    dockerconfigjson?: string;
}

WerfImageInfo

Per-image details available at $.Values.global.werf.images.<imageName>.

interface WerfImageInfo {
    registry: string;          // e.g. "registry.example.com"
    namespace: string;         // e.g. "myproject/myimage"
    name: string;              // e.g. "myimage"
    tag: string;
    digest: string;
    tag_digest: string;        // "tag@digest"
    image: string;             // Full registry/namespace reference
    repository: string;        // "namespace/name"
    ref: string;               // "image:tag@digest"
    ref_tag: string;           // "image:tag"
    repository_ref: string;    // "repository:tag@digest"
    repository_tag: string;    // "repository:tag"
    name_ref: string;          // "name:tag@digest"
    name_tag: string;          // "name:tag"
}

Release

interface Release {
    Name: string;        // Release name
    Namespace: string;   // Target namespace
    Revision: number;    // Release revision number
    IsInstall: boolean;  // true on initial install
    IsUpgrade: boolean;  // true on upgrade
    Service: string;     // Rendering service name
}

ChartMetadata

interface ChartMetadata {
    Name: string;
    Version: string;
    AppVersion: string;
    Description: string;
    Home: string;
    Icon: string;
    APIVersion: string;
    Condition: string;
    Tags: string[];
    Type: string;
    Keywords: string[];
    Sources: string[];
    Maintainers: Maintainer[];
    Annotations: Record<string, string>;
}

Capabilities

interface Capabilities {
    APIVersions: string[];       // Available API versions in the cluster
    KubeVersion: KubeVersion;    // Kubernetes version info
    HelmVersion: HelmVersion;    // Helm version info
}

interface KubeVersion {
    Version: string;  // e.g. "v1.28.0"
    Major: string;
    Minor: string;
}

interface HelmVersion {
    Version: string;
    GitCommit: string;
    GitTreeState: string;
    GoVersion: string;
}

RenderResult

interface RenderResult {
    manifests: object[] | null;  // Array of Kubernetes manifest objects
}

The manifests array must be non-empty — render throws if it's null, undefined, or empty.

Full Example

A more complete example with helper functions.

Input file (context.yaml):

Capabilities:
  APIVersions:
    - v1
  HelmVersion:
    go_version: go1.25.0
    version: v3.20
  KubeVersion:
    Major: "1"
    Minor: "35"
    Version: v1.35.0
Chart:
  APIVersion: v2
  Annotations:
    anno: value
  AppVersion: 1.0.0
  Condition: mychart.enabled
  Description: mychart description
  Home: https://example.org/home
  Icon: https://example.org/icon
  Keywords:
    - mychart
  Maintainers:
    - Email: [email protected]
      Name: john
      URL: https://example.com/john
  Name: mychart
  Sources:
    - https://example.org/mychart
  Tags: mychart
  Type: application
  Version: 1.0.0
Files:
  myfile: "content"
Release:
  IsInstall: false
  IsUpgrade: true
  Name: mychart
  Namespace: mychart
  Revision: 2
  Service: Helm
Values:
  image:
    repository: nginx
    tag: latest
  replicaCount: 1
  service:
    enabled: true
    port: 80
    type: ClusterIP

Render script (render.ts):

import {RenderContext, RenderResult, render} from "@nelm/chart-ts-sdk";

function trunc(str: string, max: number): string {
    if (str.length <= max) return str;
    return str.slice(0, max).replace(/-+$/, '');
}

function fullname($: RenderContext): string {
    if ($.Values.fullnameOverride) {
        return trunc($.Values.fullnameOverride, 63);
    }

    const chartName = $.Values.nameOverride || $.Chart.Name;

    if ($.Release.Name.includes(chartName)) {
        return trunc($.Release.Name, 63);
    }

    return trunc(`${$.Release.Name}-${chartName}`, 63);
}

function labels($: RenderContext): Record<string, string> {
    return {
        'app.kubernetes.io/name': $.Chart.Name,
        'app.kubernetes.io/instance': $.Release.Name,
        'app.kubernetes.io/version': $.Chart.AppVersion,
        'app.kubernetes.io/managed-by': $.Release.Service,
    };
}

function selectorLabels($: RenderContext): Record<string, string> {
    return {
        'app.kubernetes.io/name': $.Chart.Name,
        'app.kubernetes.io/instance': $.Release.Name,
    };
}

function generate($: RenderContext): RenderResult {
    const name = fullname($);

    return {
        manifests: [
            {
                apiVersion: 'apps/v1',
                kind: 'Deployment',
                metadata: {
                    name: name,
                    labels: labels($),
                },
                spec: {
                    replicas: $.Values.replicaCount ?? 1,
                    selector: {
                        matchLabels: selectorLabels($),
                    },
                    template: {
                        metadata: {
                            labels: selectorLabels($),
                        },
                        spec: {
                            containers: [
                                {
                                    name: name,
                                    image: `${$.Values.image?.repository}:${$.Values.image?.tag}`,
                                    ports: [
                                        {
                                            name: 'http',
                                            containerPort: $.Values.service?.port ?? 80,
                                        },
                                    ],
                                },
                            ],
                        },
                    },
                },
            },
        ],
    };
}

render(generate);

Run:

deno run render.ts --input-file context.yaml --output-file manifests.yaml

License

Apache-2.0