Skip to content

Base Primitive – resource()

resource() is the foundational primitive of the @cloudticon/k8s package. It lets you define Custom Resource Definitions (CRDs) entirely in TypeScript, with full schema validation powered by Zod.

Everything else — factory helpers, shared packages, operators — is built on top of this single function.

import { resource, z } from "github.com/cloudticon/k8s@master";
const MyResource = resource(apiVersion, kind, options);
ParameterTypeDescription
apiVersionstringFull API group and version, e.g. apps.example.com/v1.
kindstringCRD kind name, e.g. WebApp.
optionsobjectScope, schema, short names and other CRD metadata.
FieldTypeRequiredDescription
scope"Namespaced" | "Cluster"yesWhether the resource lives in a namespace or is cluster-wide.
specZod schema objectyesUser-provided desired state.
statusZod schema objectnoRuntime-owned observed state (never authored by users).
shortNamesstring[]noAliases for kubectl (e.g. ["wa"]kubectl get wa).
import { resource, z } from "github.com/cloudticon/k8s@master";
export const Cache = resource("infra.example.com/v1", "Cache", {
scope: "Namespaced",
spec: {
image: z.string(),
size: z.enum(["small", "medium", "large"]).default("small"),
},
});
Cache({ name: "redis", image: "redis:7" });

Cache is now a typed factory function — calling it produces a validated Kubernetes manifest.

import { resource, z } from "github.com/cloudticon/k8s@master";
export const WebApp = resource("apps.example.com/v1", "WebApp", {
scope: "Namespaced",
shortNames: ["wa"],
spec: {
image: z.string(),
replicas: z.number().default(1),
env: z.record(z.string()).optional(),
},
status: {
phase: z.enum(["Pending", "Running", "Failed"]),
ready: z.boolean(),
},
});
  • Type safetyWebApp({ name: "api", image: 123 }) is a compile-time error.
  • Runtime validation — Zod checks every value at build time, before anything reaches the cluster.
  • Generated CRD YAML — the CLI can emit the OpenAPI v3 schema for kubectl apply.
  • Short nameskubectl get wa works out of the box.
Concernspecstatus
AuthorUser / CI pipelineController / operator
MutableYes (declarative desired state)Yes (runtime observed state)
SchemaStrict — validated on applyInformational — set by runtime

Golden rule: users write spec, controllers write status.

Version your API group deliberately:

StageMeaning
v1alpha1Experimental — breaking changes expected.
v1beta1Mostly stable — deprecation notices given.
v1Stable — backward-compatible changes only.
export const WebApp = resource("apps.example.com/v1", "WebApp", { /* … */ });
export const WebAppV2 = resource("apps.example.com/v2", "WebApp", { /* … */ });

When evolving a CRD:

  1. Add new fields as optional first.
  2. Deprecate old fields in docs / changelogs.
  3. Bump the version only when removing or renaming fields.

@cloudticon/k8s also exports typed helpers for core Kubernetes resources:

import { deployment, service, ingress } from "github.com/cloudticon/k8s@master";

These follow the same pattern — they are thin, typed wrappers that emit standard manifests. Use them directly or compose them inside Factory Helpers.