Skip to content

feat(nextjs): codegen for runtimeEnv destructuring#1092

Merged
yamcodes merged 24 commits into
mainfrom
1072-featnextjs-codegen-for-runtimeenv-destructuring-1
May 31, 2026
Merged

feat(nextjs): codegen for runtimeEnv destructuring#1092
yamcodes merged 24 commits into
mainfrom
1072-featnextjs-codegen-for-runtimeenv-destructuring-1

Conversation

@yamcodes
Copy link
Copy Markdown
Owner

Fixes #1072

Adds a new codegen helper withArkEnv() inside @arkenv/nextjs/config that runs during Next.js config loading. It automatically extracts keys from your schema (env.ts) and generates a tailored createEnv factory inside env.gen.ts that pre-fills the runtimeEnv block.

This removes the boilerplate and the need to manually destructure environment variables to satisfy Next.js's static client inlining rules.

@yamcodes yamcodes added enhancement New feature or request good first issue Good for newcomers javascript Pull requests that update javascript code labels May 30, 2026
@yamcodes yamcodes linked an issue May 30, 2026 that may be closed by this pull request
@yamcodes yamcodes added the javascript Pull requests that update javascript code label May 30, 2026
@pullfrog
Copy link
Copy Markdown
Contributor

pullfrog Bot commented May 30, 2026

Pullfrog stalled

The agent stopped emitting events for 304s and was killed by the activity-timeout watchdog. 295 events were processed before the failure.

Recent agent stderr
INFO  2026-05-30T06:09:07 +30ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +30ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +31ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +30ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +31ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +30ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +29ms service=bus type=message.part.delta publishing
INFO  2026-05-30T06:09:07 +67ms service=bus type=message.part.updated publishing
INFO  2026-05-30T06:09:07 +26ms service=snapshot hash=210b1c2b43a52cd4f42f8bfd8b40b86938724bcf cwd=/home/runner/work/arkenv/arkenv git=/tmp/pullfrog-1GLbSU/.local/share/opencode/snapshot/f83218abeaddaccdb760ad016a903eaed7223bd4/6c5be8306450cbdc5e2e2d8f3a7b121cbb6fa3cc tracking
INFO  2026-05-30T06:09:07 +2ms service=bus type=message.part.updated publishing
INFO  2026-05-30T06:09:07 +2ms service=bus type=message.updated publishing
INFO  2026-05-30T06:09:08 +19ms service=bus type=message.updated publishing
INFO  2026-05-30T06:09:08 +0ms service=bus type=session.status publishing
INFO  2026-05-30T06:09:08 +1ms service=session.prompt session.id=ses_1888d3945ffea7C6jBCpoYka0N step=2 loop
INFO  2026-05-30T06:09:08 +3ms service=session.prompt session.id=ses_1888d3945ffea7C6jBCpoYka0N exiting loop
INFO  2026-05-30T06:09:08 +3ms service=bus type=session.status publishing
INFO  2026-05-30T06:09:08 +0ms service=bus type=session.idle publishing
INFO  2026-05-30T06:09:08 +18ms service=bus type=session.updated publishing
INFO  2026-05-30T06:09:08 +1ms service=bus type=session.diff publishing
INFO  2026-05-30T06:09:08 +10ms service=bus type=message.updated publishing

Pullfrog  | Rerun failed job ➔View workflow run | via Pullfrog | Using Kimi K2𝕏

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 30, 2026

🦋 Changeset detected

Latest commit: 9e034e8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@arkenv/nextjs Patch
arkenv Patch
@arkenv/cli Patch
@arkenv/bun-plugin Patch
@arkenv/vite-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added docs Improvements or additions to documentation tests This issue or PR is about adding, removing or changing tests @arkenv/nextjs Issues or Pull Requests involving the Next.js integration for ArkEnv labels May 30, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 30, 2026

Open in StackBlitz

arkenv

npm i https://pkg.pr.new/arkenv@1092

@arkenv/bun-plugin

npm i https://pkg.pr.new/@arkenv/bun-plugin@1092

@arkenv/cli

npm i https://pkg.pr.new/@arkenv/cli@1092

@arkenv/fumadocs-ui

npm i https://pkg.pr.new/@arkenv/fumadocs-ui@1092

@arkenv/nextjs

npm i https://pkg.pr.new/@arkenv/nextjs@1092

@arkenv/vite-plugin

npm i https://pkg.pr.new/@arkenv/vite-plugin@1092

commit: 2f4c251

@arkenv-bot
Copy link
Copy Markdown
Contributor

arkenv-bot Bot commented May 30, 2026

📦 Bundle Size Report

Package Size Limit Diff Status
arkenv 1.73 kB 1.95 kB 0.0%
arkenv/standard 1.01 kB 1.07 kB 0.0%
arkenv/core 441 B 500 B 0.0%
@arkenv/nextjs 2.03 kB 2.93 kB 0.0%

All size limits passed!

@yamcodes

This comment was marked as outdated.

@yamcodes

This comment was marked as resolved.

@github-actions github-actions Bot added www Improvements or additions to arkenv.js.org @arkenv/cli Issues or Pull Requests involving the ArkEnv CLI labels May 30, 2026
@arkenv-bot
Copy link
Copy Markdown
Contributor

arkenv-bot Bot commented May 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (Asia/Almaty)
arkenv Ready Ready Preview, Comment May 31 2026, 1:48 PM (Asia/Almaty)

@yamcodes

This comment was marked as resolved.

@yamcodes

This comment was marked as resolved.

@yamcodes

This comment was marked as resolved.

@yamcodes

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

Important

The new commits moved the default generated output to a generated/ subdirectory, but several documentation references still point to the old co-located ./env.gen path. Additionally, getUsageInstructions in the CLI scaffold utils is now dead code.

Reviewed changes — moved the default generated env factory from co-located env.gen.ts to generated/env.gen.ts (relative to the schema directory), removed // @ts-nocheck from generated output, and updated tests and CLI templates to match.

  • Relocated default output pathwithArkEnv now writes to generated/env.gen.ts by default instead of co-located env.gen.ts, keeping generated files organized in a dedicated folder.
  • Removed // @ts-nocheck — the generated factory no longer suppresses TypeScript checks, improving type safety.
  • Updated CLI scaffolding — Next.js template now imports from ./generated/env.gen and no longer emits manual runtimeEnv boilerplate.
  • Updated testsconfig.test.ts and env-template.test.ts assertions reflect the new default path and removed ts-nocheck.

⚠️ Stale documentation references to old default path

The default output path changed from env.gen.ts to generated/env.gen.ts, but the following docs still tell users to import from ./env.gen:

  • apps/www/content/docs/nextjs/index.mdx — step 1 example imports from ./env.gen
  • packages/nextjs/README.md — setup example imports from ./env.gen
  • .changeset/nextjs-codegen-helper.md — example usage imports from ./env.gen

These should be updated to ./generated/env.gen (or note that the path depends on the outputPath option).

ℹ️ Nitpicks

  • packages/cli/src/features/scaffold/utils.tsgetUsageInstructions is no longer called by executor.ts (replaced by inline logic in getNextStepsNote). Consider removing the function and its tests to avoid dead code.

Note: 2 inline comment(s) dropped because they did not anchor to lines inside the PR diff:

  • packages/cli/src/features/scaffold/utils.ts:28 (RIGHT) — line 28 (RIGHT) is not inside a diff hunk
  • packages/cli/src/features/scaffold/utils.test.ts:6 (RIGHT) — line 6 (RIGHT) is not inside a diff hunk

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2𝕏

@yamcodes
Copy link
Copy Markdown
Owner Author

LGTM

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

Important

The new commits add CLI bootstrap codegen and JSDoc, but documentation still references the old co-located ./env.gen path in several places. Additionally, getUsageInstructions remains dead code after being replaced by inline logic in getNextStepsNote.

Reviewed changes — added CLI post-scaffold codegen for Next.js, expanded planner bootstrap eligibility, and added detailed JSDoc to ArkEnvConfigOptions.

  • Added Next.js bootstrap codegen in executor.ts — after scaffolding, the CLI now runs runCodegen via node -e to generate the initial env.gen.ts for Next.js projects.
  • Expanded planner bootstrap framework listnextjs is now included alongside vite and bun-fullstack as a framework that receives post-scaffold bootstrapping.
  • Added JSDoc to ArkEnvConfigOptions — documented schemaPath and outputPath with descriptions, defaults, and usage examples.

⚠️ Stale documentation references to old default path

The default output path changed to generated/env.gen.ts, but the following docs still tell users to import from ./env.gen:

  • apps/www/content/docs/nextjs/index.mdx — step 1 example imports from ./env.gen
  • packages/nextjs/README.md — setup example imports from ./env.gen
  • .changeset/nextjs-codegen-helper.md — example usage imports from ./env.gen

These should be updated to ./generated/env.gen (or note that the path depends on the outputPath option).

ℹ️ Nitpicks

  • packages/cli/src/features/scaffold/utils.tsgetUsageInstructions is no longer called by getNextStepsNote (replaced by inline logic). Consider removing the function and its tests to avoid dead code.

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2𝕏

@yamcodes
Copy link
Copy Markdown
Owner Author

Some people don't like codegen, we should have a way to opt out like in the CLI.

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — addressed prior review feedback and added tsconfig paths resolution for Next.js scaffolding imports.

  • Fixed stale documentation references — all docs, changeset, and README examples now correctly import from ./generated/env.gen instead of the old co-located ./env.gen.
  • Removed dead codegetUsageInstructions and its test file were deleted after being replaced by inline logic in getNextStepsNote.
  • Added tsconfig paths resolution for Next.js — the planner now detects @/* path mappings in tsconfig.json and generates an appropriate @/... import path for the scaffolded env.ts when the generated directory falls inside the mapped folder. Falls back to a relative path otherwise.
  • Updated all validator templatesarktypeTemplate, zodTemplate, and valibotTemplate now accept an optional nextjsImportPath parameter, passed through from the planner.

Pullfrog  | View workflow run | Using Kimi K2𝕏

Copy link
Copy Markdown
Contributor

@pullfrog pullfrog Bot left a comment

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — added --no-codegen (-C) CLI flag, interactive prompt, and disableCodegen scaffolding path to let users opt out of automatic env.gen.ts generation.

  • Added --no-codegen flag and alias -C — parsed in CLI, passed through InitInput to the wizard, and surfaced in help output and docs.
  • Added interactive nextjsCodegen prompt — asks users whether to enable automated codegen during scaffolding, defaulting to true.
  • Implemented disableCodegen scaffolding branch — when opted out, templates fall back to manual runtimeEnv + direct arkenv import; planner skips bootstrap; executor skips post-scaffold codegen.
  • Updated tests and docs — CLI parser tests, help alignment tests, planner tests, and www docs all reflect the new flag and flow.

Pullfrog  | View workflow run | Using Kimi K2𝕏

@yamcodes
Copy link
Copy Markdown
Owner Author

Needs final QA but we're practically there

@yamcodes

This comment was marked as resolved.

Comment thread .changeset/disable-codegen-option.md Outdated
Comment thread .changeset/disable-codegen-option.md Outdated
Comment thread packages/cli/src/features/scaffold/utils.test.ts Outdated
@yamcodes yamcodes merged commit c6c30ab into main May 31, 2026
19 checks passed
@yamcodes yamcodes deleted the 1072-featnextjs-codegen-for-runtimeenv-destructuring-1 branch May 31, 2026 08:45
@arkenv-bot arkenv-bot Bot mentioned this pull request May 31, 2026
yamcodes pushed a commit that referenced this pull request May 31, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## arkenv@0.11.1

### Patch Changes

- #### Add `Infer<T>` helper to resolve environment variable types
_[`#1092`](#1092)
[`c6c30ab`](c6c30ab)
[@yamcodes](https://github.com/yamcodes)_

Introduce the `Infer<T>` type helper, allowing developers to extract the
inferred output types of their environment schemas. It supports both
declarative schema shapes and compiled schemas (like Zod or ArkType
types).

    Usage:

    ```ts
    import { createEnv, type Infer } from "arkenv";
    import { type } from "arktype";

    const schema = {
      PORT: type.number,
    };

    export type Env = Infer<typeof schema>;
    ```

## @arkenv/bun-plugin@0.1.7

### Patch Changes

<details><summary>Updated 1 dependency</summary>

<small>


[`c6c30ab`](c6c30ab)

</small>

-   `arkenv@0.11.1`

</details>

## @arkenv/cli@0.2.6

### Patch Changes

- #### Implement Next.js separate files mode, shared entry point, and
native extends API
_[`#1084`](#1084)
[`d921785`](d921785)
[@yamcodes](https://github.com/yamcodes)_

Introduce dedicated entry points for `@arkenv/nextjs/server`,
`@arkenv/nextjs/client`, and `@arkenv/nextjs/shared` to prevent metadata
leakage and support compile-time bundler-enforced isolation. Add a
native `extends` API to merge validated outputs of extended proxies
while maintaining proxy-level protections.

Also update the CLI `init` wizard to support interactive layout
selection (Strict 3-file vs Simple 1-file) and `--strict` / `--simple`
flags to bypass interactive selection.

    Example server usage:

    ```ts
    import { createEnv } from "@arkenv/nextjs/server";
    import { env as clientEnv } from "./env.client";

    export const env = createEnv(
      { DATABASE_URL: "string" },
      { extends: [clientEnv] }
    );
    ```

    Example client usage:

    ```ts
    import { createEnv } from "@arkenv/nextjs/client";

    export const env = createEnv(
      { NEXT_PUBLIC_API_URL: "string" },
      {
        runtimeEnv: {
          NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
        },
      }
    );
    ```

- #### Update Next.js scaffolding template to use codegen workflow
_[`#1092`](#1092)
[`c6c30ab`](c6c30ab)
[@yamcodes](https://github.com/yamcodes)_

Update the CLI `nextjs` scaffolding template to adopt the new
`@arkenv/nextjs/config` codegen workflow. The generated `env.ts` file
now imports the auto-generated `createEnv` factory from `env.gen.ts`
instead of directly importing from `@arkenv/nextjs`, which eliminates
the need to manually destructure `runtimeEnv` variables.

Additionally, update the CLI usage instructions to guide developers on
wrapping their Next.js configuration using the `withArkEnv` helper
inside `next.config.ts`.

#### Add `--no-codegen` CLI option and dedicated prompt for Next.js
scaffolding

Introduce a `--no-codegen` (or `-C`) option and an interactive prompt to
allow developers to opt out of the Next.js automatic environment
variable code generation workflow. When opted out, the CLI scaffolds the
project to use standard runtimeEnv destructuring and skips post-scaffold
code generation bootstrapping.

## @arkenv/nextjs@0.0.4

### Patch Changes

- #### Implement Next.js separate files mode, shared entry point, and
native extends API
_[`#1084`](#1084)
[`d921785`](d921785)
[@yamcodes](https://github.com/yamcodes)_

Introduce dedicated entry points for `@arkenv/nextjs/server`,
`@arkenv/nextjs/client`, and `@arkenv/nextjs/shared` to prevent metadata
leakage and support compile-time bundler-enforced isolation. Add a
native `extends` API to merge validated outputs of extended proxies
while maintaining proxy-level protections.

Also update the CLI `init` wizard to support interactive layout
selection (Strict 3-file vs Simple 1-file) and `--strict` / `--simple`
flags to bypass interactive selection.

    Example server usage:

    ```ts
    import { createEnv } from "@arkenv/nextjs/server";
    import { env as clientEnv } from "./env.client";

    export const env = createEnv(
      { DATABASE_URL: "string" },
      { extends: [clientEnv] }
    );
    ```

    Example client usage:

    ```ts
    import { createEnv } from "@arkenv/nextjs/client";

    export const env = createEnv(
      { NEXT_PUBLIC_API_URL: "string" },
      {
        runtimeEnv: {
          NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
        },
      }
    );
    ```

- #### Add `withArkEnv` configuration helper for Next.js
_[`#1092`](#1092)
[`c6c30ab`](c6c30ab)
[@yamcodes](https://github.com/yamcodes)_

Add a Next.js configuration wrapper in `@arkenv/nextjs/config` that
automates client-side and shared environment variable destructuring in
the `runtimeEnv` block:

    ```typescript
    // next.config.ts
    import { withArkEnv } from "@arkenv/nextjs/config";
    import type { NextConfig } from "next";

    const nextConfig: NextConfig = {
      reactStrictMode: true,
    };

    export default withArkEnv(nextConfig);
    ```

    Key features:

- **Zero-Boilerplate Destructuring**: Statically extract `client` and
`shared` keys from your `env.ts` schema and generate a tailored
`createEnv` factory in `generated/env.gen.ts` that pre-fills the
`runtimeEnv` block.
- **Development Watcher**: Automatically start a lightweight file
watcher in development mode to regenerate `generated/env.gen.ts` on the
fly when `env.ts` changes.
- **Customizable Output**: Support custom schema and output paths,
enabling developers to write generated files to a dedicated folder
(e.g., `src/generated/env.gen.ts`).
- **Deprecate Direct Exports**: Mark direct `createEnv` and default
`arkenv` exports from the main and `react-server` entry points as
deprecated to steer developers toward the new codegen workflow.

    Example usage in `env.ts`:

    ```typescript
    // env.ts
    import { createEnv } from "./generated/env.gen";

    export const env = createEnv({
      client: {
        NEXT_PUBLIC_API_URL: "string",
      },
      shared: {
        NODE_ENV: "string",
      },
    });
    ```

<details><summary>Updated 1 dependency</summary>

<small>


[`c6c30ab`](c6c30ab)

</small>

-   `arkenv@0.11.1`

</details>

## @arkenv/vite-plugin@0.1.1

### Patch Changes

<details><summary>Updated 1 dependency</summary>

<small>


[`c6c30ab`](c6c30ab)

</small>

-   `arkenv@0.11.1`

</details>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

@arkenv/cli Issues or Pull Requests involving the ArkEnv CLI @arkenv/nextjs Issues or Pull Requests involving the Next.js integration for ArkEnv arkenv Changes to the `arkenv` npm package. docs Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers javascript Pull requests that update javascript code tests This issue or PR is about adding, removing or changing tests www Improvements or additions to arkenv.js.org

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(nextjs): codegen for runtimeEnv destructuring

1 participant