Getting started
Take a Next.js app from next build to a scale-to-zero Knative service.
Take an existing Next.js app from next build to a scale-to-zero Knative service. knext uses the
official Next.js Deployment Adapter API — no fork, no custom runtime.
Prerequisites. A Kubernetes cluster with Knative Serving installed, Next.js 16.x, a
container registry, and an object-storage bucket (gcs, s3, or minio).
0 · Install the packages
knext ships on the public npm registry under the @getknext scope. No registry
configuration, no auth token — a plain npm i is all it takes.
npm i @getknext/core # the adapter, the config type, and the CLI (bin: kn-next)
npx kn-next --version # the CLI is on your PATH via node_modules/.binTwo optional packages complete the picture — add them only if you need them:
npm i @getknext/db # typed drizzle-orm data layer over your DATABASE_URL
npm i @getknext/lib # runtime helpers: pooled DB clients, health checks, logger| Package | What it is for | Canonical imports |
|---|---|---|
@getknext/core | The official Next.js adapter, the typed deploy config, the ISR cache handler, and the kn-next CLI. Required. | '@getknext/core' (KnativeNextConfig), '@getknext/core/adapter', '@getknext/core/validate' |
@getknext/lib | Runtime helpers for an app running on knext: pooled Postgres clients, a MinIO client, a Cerbos client, health checks, and a preconfigured logger. | '@getknext/lib/clients', '@getknext/lib/health', '@getknext/lib/logger', '@getknext/lib/context' |
@getknext/db | The Data SDK — a thin drizzle-orm layer over your DATABASE_URL, with schema builders and one-shot writer-only migrations. | '@getknext/db', '@getknext/db/schema', '@getknext/db/migrate' |
What each package exports. @getknext/core exports the KnativeNextConfig type from its root,
the adapter from /adapter (what adapterPath points at), the ISR cache handler from
/adapters/cache-handler, and the pure config validator (validateConfig,
ConfigValidationError) from /validate. @getknext/lib exports getDbPool() / getDbPoolRO()
/ closeDbPool(), getMinioClient(), getCerbosClient(), checkDeepHealth() /
checkShallowHealth(), the logger, and the request-correlation helpers — all also re-exported
from the package root. @getknext/db exports getDb() / getDbRO() plus the whole of
drizzle-orm.
1 · Point Next.js at the adapter
Reference the knext adapter from your next.config.ts. The adapter forces output: 'standalone' at
build time.
import type { NextConfig } from 'next';
const config: NextConfig = {
// knext ships the official NextAdapter as a package export.
// adapterPath is top-level config on Next.js 16.2+.
adapterPath: '@getknext/core/adapter',
};
export default config;Next.js 16.0.x–16.1.x: the option lives under experimental on those versions
(experimental: { adapterPath: '@getknext/core/adapter' }). Next.js 16.2+ auto-migrates the old
experimental key with a warning; 16.0.x does not recognize the top-level form.
2 · Write the deploy config
knext reads a typed kn-next.config.ts. The config type is KnativeNextConfig, exported from
@getknext/core. The minimum valid config requires name, registry, and a storage block with
provider, bucket, and publicUrl.
import type { KnativeNextConfig } from '@getknext/core';
const config: KnativeNextConfig = {
name: 'acme',
registry: 'registry.example.com/acme',
storage: {
provider: 'gcs', // one of: gcs | s3 | minio | azure
bucket: 'acme-assets',
publicUrl: 'https://storage.googleapis.com/acme-assets',
},
scaling: { minScale: 0, maxScale: 20 }, // minScale 0 = scale to zero
// runtime: 'bun', // optional — run the standalone server under Bun, with
// // build-time bytecode precompilation. See /docs/bun-runtime.
};
export default config;storage.provider is validated against gcs | s3 | minio | azure. Each shells out to that cloud's
CLI (gsutil / aws / mc / az), which must be installed and authenticated in your build
environment. See Multi-cloud deploy.
The scaling block also carries the full set of autoscaling knobs (containerConcurrency,
poolMax, warmSchedule, burst-response tuning) — see Scale to zero.
To bind an existing Postgres, add a database block — see
Databases.
3 · Build, push, deploy
deploy is the default command — build → push → apply the NextApp CR. Validation runs
automatically when the config loads.
# build + push (digest is resolved automatically) and apply the NextApp CR
$ kn-next deploy --registry registry.example.com/acme
✓ image registry.example.com/acme@sha256:9f1c...
✓ NextApp/acme applied
✓ url https://acme.apps.example.com (scaled to 0)kn-next deploy flags: -r/--registry, -b/--bucket, -t/--tag, -n/--namespace,
--skip-build, --skip-upload, --dry-run (print the CR without applying), -h/--help,
-v/--version.
Then watch the rollout to real readiness — status exits non-zero if the app fails to come up, so
this pair works as a CI gate:
$ kn-next status acme --watch # polls until Ready=True (bounded)The operator is the source of truth. The CLI only ever applies the NextApp CR. The Go
operator reconciles it into a Knative Service — wiring autoscaling, optionally the bytecode-cache
volume, and rejecting any image that is not digest-pinned. See
Operator & the NextApp CRD.
The whole CLI at a glance
Every command below is npx kn-next <verb>. Anything that is not one of these words runs the
default deploy flow. Full flag tables are on the CLI reference.
| Command | What it does | What it writes |
|---|---|---|
npx kn-next deploy | Build → push → apply the digest-pinned NextApp CR. The default. | Applies the NextApp CR; uploads static assets to your bucket. |
npx kn-next doctor | Cluster-prereq preflight: CRD, operator, admission webhook, ingress class, Knative Serving. | Nothing — read-only. |
npx kn-next status | The operator's honest Ready / Degraded / Reconciling / DatabaseReady conditions. | Nothing — read-only. |
npx kn-next rollback | Pin serving traffic to a prior Knative Revision (or clear the pin). | One merge-patch of spec.traffic on the NextApp CR. |
npx kn-next db bind | Bind an existing Postgres Secret as DATABASE_URL. | One merge-patch of spec.database.secretRef on the NextApp CR. |
npx kn-next db migrate | Apply pending drizzle migrations against the writer, once. | Your database only — no cluster write. |
npx kn-next gc | Reap superseded _next/static/<build-id>/ prefixes (over-keep, never over-delete). | Deletes old asset prefixes from your bucket; reads the CR only. |
npx kn-next doctor # before your first deploy
npx kn-next deploy -r registry.example.com/acme # build → push → apply
npx kn-next status acme --watch # poll until Ready=True
npx kn-next rollback acme --to acme-00002 # pin 100% to a prior revision
npx kn-next db bind acme --secret acme-db # DATABASE_URL from a Secret
npx kn-next db migrate --dir ./drizzle # writer-only, idempotent
npx kn-next gc --dry-run # print the reap/keep plan onlybuild, cleanup, preview, and loadtest are not kn-next subcommands — they ship as
directly runnable entries in the package. See
Directly runnable entries.