Skip to main content

Running Kosko in Browser

Last month, ECMAScript modules (ESM) support was shipped in Kosko 1.1. Today, you can use ESM not only in Node.js, but also in browsers. Currently only the following packages are browser-ready. Please make sure to update these packages before using Kosko in a browser.

  • @kosko/env - 2.0.0
  • @kosko/generate - 1.2.0

Programmatic API#

Kosko can be used in browsers via the programmatic API. In the following example, first we use dynamic import to load environment variables. Then, use the resolve function to resolve and validate components. And finally, print the resolved manifests with the print function.

import env, { createAsyncLoaderReducers } from "@kosko/env";
import { resolve, print, PrintFormat } from "@kosko/generate";
// Load environment variables with dynamic import
env.setReducers((reducers) => [
global: () =>
import("./environments/dev/index.js").then((mod) => mod.default),
component: (name) =>
import(`./environments/dev/${name}.js`).then((mod) => mod.default)
(async () => {
// Resolve and validate components
const manifests = await resolve(
import("./components/nginx.js").then((mod) => mod.default)
// Print resolved manifests
{ manifests },
format: PrintFormat.YAML,
writer: { write: (data) => console.log(data) }

See using in browser for more details.

More Examples#

You can try Kosko in the playground, or check the following examples.

Breaking Changes#


The following APIs were changed in this release.

  • Environment class → Environment interface
  • SyncEnvironment class → createNodeCJSEnvironment function
  • AsyncEnvironment class → createNodeESMEnvironment function

You don't have to change anything, unless you initialize these classes manually.

// Before
const { Environment } = require("@kosko/env");
const env = new Environment(process.cwd());
// After
const { createNodeCJSEnvironment } = require("@kosko/env");
const env = createNodeCJSEnvironment({ cwd: process.cwd() });

Introducing Helm Support

Most popular apps are available as Helm charts. It was not easy to use them in Kosko directly. The all new @kosko/helm package can help you load Helm charts, and of course, it also supports Kubernetes OpenAPI schema validation.

@kosko/helm uses the helm template command to render chart templates and the @kosko/yaml package to load Kubernetes YAML.

First, you have to install the Helm CLI, then install the @kosko/helm package.

npm install @kosko/helm

Next, use the loadChart function to load Helm charts.

const { loadChart } = require("@kosko/helm");
name: "prom",
chart: "prometheus",
repo: "",
version: "13.6.0",
values: {
server: {
persistentVolume: {
enabled: true

See loading Helm chart for more details.

Kosko 1.1: ESM Support

Kosko comes with ECMAScript modules (ESM) support since v1.1. You can write components and environments in native ESM files. The following packages are updated for ESM support. Please make sure to update these packages before using ESM.

  • @kosko/cli - 1.2.0
  • @kosko/env - 1.1.0
  • @kosko/generate - 1.1.0
  • kosko - 1.1.0
  • @kosko/migrate - 2.0.0
  • @kosko/require - 2.0.0
  • @kosko/yaml - 1.0.0

The biggest difference between CommonJS and ESM is that @kosko/env is asynchronous in ESM. This is because import() is asynchronous. But don't freak out, it won't break your current code at all. @kosko/env is still synchronous in CommonJS.

When retrieving environments in ESM, you MUST add await as the example below.

import env from "@kosko/env";
const globalParams = await;
const componentParams = await env.component("demo");

Instead of module.exports, export components or environments with export default.

import { Deployment } from "kubernetes-models/apps/v1/Deployment";
import { Service } from "kubernetes-models/v1/Service";
export default [new Deployment({}), new Service({})];

For more details about how to enable ESM or programmatical usage, please check here.

Breaking Changes#


loadString and getResourceModule functions become asynchronous because of ESM support.


migrate and migrateString functions become asynchronous because of the breaking changes of @kosko/yaml package.


resolve function no longer allows resolve.AsyncOpts as options, please use ResolveOptions instead.


kubernetes-models is also updated for ESM support.

  • @kubernetes-models/base - 1.2.0
  • @kubernetes-models/cert-manager - 1.1.0
  • @kubernetes-models/contour - 1.1.0
  • @kubernetes-models/crd-generate - 1.2.0
  • @kubernetes-models/gke - 1.1.0
  • kubernetes-models - 1.1.0
  • @kubernetes-models/openapi-generate - 1.2.0
  • @kubernetes-models/prometheus-operator - 1.1.0
  • @kubernetes-models/read-input - 1.1.0
  • @kubernetes-models/sealed-secrets - 1.1.0
  • @kubernetes-models/string-util - 1.1.0
  • @kubernetes-models/validate - 1.1.0

Kosko 1.0 Released

It has been a long time since the last stable release v0.9. Recently, I decide to implement some features that I always want to have at work. Hope these new features can also help you.

Nested Manifests#

In v1.0, arrays and functions in components are flattened. This is useful for sharing manifests across components.

For instance, a database in Kubernetes is typically composed by a Deployment and a Service. To include a database in a component, before v1.0, you have to flatten these two manifests in the component by yourself. After v1.0, they are flattened automatically.

In this way, a database can be used as a single resource, which can be used everywhere in your components.

function createDatabase() {
return [new Deployment(), new Service()];
// Before v1.0
module.exports = [new Deployment(), ...createDatabase()];
// After v1.0
module.exports = [new Deployment(), createDatabase()];

More Information in ValidationError#

There was only path and index in ValidationError before v1.0. Sometimes it might be difficult to find where the error is. In v1.0, apiVersion, kind, namespace and name are added to ValidationError. The following is an example of the new error message.

ValidationError: data.metadata.annotations['dependencies'] should be string
- path: ".../components/config-api"
- index: [0]
- kind: "apps/v1/Deployment"
- name: "config-api"
at resolveComponent (.../node_modules/@kosko/generate/src/generate.ts:81:15)
at resolveComponent (.../node_modules/@kosko/generate/src/generate.ts:59:28)
at Object.generate (.../node_modules/@kosko/generate/src/generate.ts:134:30)
at generateHandler (.../node_modules/@kosko/cli/src/commands/generate/index.ts:156:18)
at handler (.../node_modules/@kosko/cli/src/commands/generate/index.ts:200:20)
at (.../node_modules/@kosko/cli/src/index.ts:12:3)

Loading Kubernetes YAML#

If you have been using Kubernetes for a while, you may have a lot of existing Kubernetes YAML files just like me. Instead of migrating YAML into JavaScript, try use the new package @kosko/yaml.

@kosko/yaml reads YAML files and transforms data into kubernetes-models classes, so your manifests are validated against Kubernetes OpenAPI schema.

const { loadFile } = require("@kosko/yaml");
module.exports = loadFile("manifest.yaml");

This package works better with "nested manifests", so please don't forget to upgrade to Kosko v1.0 first.

For more details, please check here.

Breaking Changes#

  • Drop support for Node.js 8.
  • @kosko/generate
    • The type of Manifest.index and ValidationError.index is changed from number to number[].
    • The type of is changed from any to unknown.