Skip to content

Conversation

@kitsunoff
Copy link

Summary

  • Add detailed specification for TypeScript as alternative to Go templates
  • Define HelmContext API and types
  • Describe SDK package structure (@nelm/sdk)
  • Document development and deployment workflow
  • List CLI commands
  • Record design decisions

Files

  • docs/proposals/go-template-alternative/README.md — Overview
  • docs/proposals/go-template-alternative/api.md — HelmContext API
  • docs/proposals/go-template-alternative/sdk.md — SDK structure
  • docs/proposals/go-template-alternative/workflow.md — Workflow
  • docs/proposals/go-template-alternative/cli.md — CLI commands
  • docs/proposals/go-template-alternative/decisions.md — Design decisions

Key Decisions

  1. Runtime: quickjs-go (CGO), no WASM
  2. API: render(ctx) → Manifest[] (return-based, not emit)
  3. Context: Everything via ctx (no globals, no imports for runtime)
  4. Subcharts: Full isolation, Nelm orchestrates
  5. SDK: Types only + when() helper, all runtime from Go
  6. Values types: npm script with json-schema-to-typescript

🤖 Generated with Claude Code

ilya-lesikov and others added 2 commits November 27, 2025 22:22
Add detailed specification for TypeScript as Go templates alternative:
- HelmContext API and types
- SDK package structure
- Development and deployment workflow
- CLI commands
- Design decisions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@kitsunoff
Copy link
Author

  1. should use goja, because it's written in pure go, not cgo bindings

  2. esbuild must be bundled inside nelm cli

  3. for all native functions should use a ctx object in render function

Files: Files

// Functions (injected from Go)
lookup<T = unknown>(apiVersion: string, kind: string, namespace: string, name: string): T | null
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

lookup<T = unknown>(apiVersion: string, kind: string, namespace: string, name: string): T | null

// Serialization
toYaml(obj: unknown): string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of these functions not needed. Let the user use the libraries he wants


**Helper for conditionals:**
```typescript
import { when } from '@nelm/sdk'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

Key changes:
- Switch from quickjs-go to goja (pure Go, no CGO)
- Add data mechanism for external data fetching
- Remove lookup from render phase (deterministic renders)
- Remove helper functions (users use npm libraries)
- Add esbuild embedded in Nelm notes
- Add @nelm/types package structure with K8s types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@kitsunoff
Copy link
Author

I updated my draft
pls review again

## Files

```typescript
interface Files {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it

interface File {
  Name string
  Data []byte
}

We don't really need all these methods, the user can do it himself. And we have all the Data from files already at this point (Helm reads all of them into the memory, even if not used).

Chart: Chart
Capabilities: Capabilities
Files: Files
Data: D // Results from data() phase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably need something like this, but not now.

Comment on lines +115 to +116
ownerReferences?: OwnerReference[]
finalizers?: string[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ownerReferences?: OwnerReference[]
finalizers?: string[]

Not needed

apiVersion: string
kind: string
metadata: ObjectMeta
[key: string]: unknown
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how can it be done in TS, but this must work for data, spec, or whatever else, or a combination of.

return condition ? items : []
}

export default function render(ctx: HelmContext<Values>): Manifest[] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see something like RenderResult here instead of Manifest[].

interface RenderResult {
  ApiVersion: string // v1 for now
  Manifests: []Manifest
}

@@ -0,0 +1,367 @@
# Data Mechanism Proposal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not interested in this for now.


```bash
# Nelm runs internally:
esbuild src/index.ts --bundle --target=es5 --format=iife --outfile=vendor/bundle.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
esbuild src/index.ts --bundle --target=es5 --format=iife --outfile=vendor/bundle.js
esbuild src/index.ts --bundle --target=es5.1 --format=iife --outfile=vendor/bundle.js

if possible


| Package | Type | Purpose |
|---------|------|---------|
| `@nelm/types` | Types | HelmContext, Manifest, K8s resources |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not into TS/JS, so I don't know how to organize the TS SDK.


K8s types generated from OpenAPI spec in CI. Version managed in CI pipeline.

## @nelm/crd-to-ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can go without it for now. I guess for CRs you can just use any/unknown.

Comment on lines +110 to +117
"name": "mychart-ts",
"private": true,
"scripts": {
"generate:values": "json2ts ../values.schema.json -o src/generated/values.types.ts",
"generate:crd": "crd-to-ts --crd servicemonitors.monitoring.coreos.com -o src/generated/",
"typecheck": "tsc --noEmit",
"build": "esbuild src/index.ts --bundle --target=es5 --format=iife --outfile=vendor/bundle.js"
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't work with TS/JS, but I just want everything here to be as conventional/standard as possible.

@@ -0,0 +1,158 @@
# Feature: Go templates alternative
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is more up-to-date version now, which contains additional details, here:

https://github.com/werf/nelm/pull/497/files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants