Skip to content

Comments

feat(bun-plugin): include NODE_ENV as an allowed public environment variable#804

Merged
yamcodes merged 2 commits intoyamcodes:mainfrom
joakimbeng:bun-plugin-node-env
Feb 23, 2026
Merged

feat(bun-plugin): include NODE_ENV as an allowed public environment variable#804
yamcodes merged 2 commits intoyamcodes:mainfrom
joakimbeng:bun-plugin-node-env

Conversation

@joakimbeng
Copy link
Contributor

@joakimbeng joakimbeng commented Feb 20, 2026

Bun already exposes process.env.NODE_ENV to the frontend and with this change it's possible to type it with ArkEnv, in same fashion as other public env vars.

Hopefully you think this is a good idea! ☺️

Summary by CodeRabbit

  • New Features

    • NODE_ENV is now exposed to the frontend with type support, matching Bun’s standard behavior.
  • Documentation

    • Docs updated to show NODE_ENV is included among publicly exposed environment variables alongside BUN_PUBLIC_*.
  • Tests

    • Added a test ensuring NODE_ENV is not filtered out and is correctly represented in the exposed environment.

@github-actions github-actions bot added docs Improvements or additions to documentation tests This issue or PR is about adding, removing or changing tests labels Feb 20, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

Walkthrough

The bun-plugin now exposes NODE_ENV by default alongside BUN_PUBLIC_* variables; this updates the env filtering logic, adds a test, updates README, and adds a changeset for a minor release. (49 words)

Changes

Cohort / File(s) Summary
Changeset
.changeset/few-lights-ask.md
New changeset added declaring a minor release for @arkenv/bun-plugin and documenting NODE_ENV as publicly exposed.
Core logic & tests
packages/bun-plugin/src/utils.ts, packages/bun-plugin/src/utils.test.ts
Filter in processEnvSchema expanded to include NODE_ENV in addition to BUN_PUBLIC_*; added unit test asserting NODE_ENV is preserved and JSON-stringified in the env map.
Documentation
packages/bun-plugin/README.md
README examples and description updated to include NODE_ENV in the automatic client-exposed environment variables and type/schema examples.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

@arkenv/bun-plugin

Suggested reviewers

  • yamcodes

Poem

🐰
I nibble keys beneath the sun,
NODE_ENV hops out to join the fun,
PUBLIC_* pals line up in a row,
Frontend types now softly glow,
A small hop forward — off I run. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: adding NODE_ENV as a publicly exposed environment variable in the bun-plugin.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@changeset-bot
Copy link

changeset-bot bot commented Feb 20, 2026

🦋 Changeset detected

Latest commit: 2cbd2d2

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

This PR includes changesets to release 1 package
Name Type
@arkenv/bun-plugin Minor

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

@joakimbeng
Copy link
Contributor Author

@all-contributors please add @joakimbeng for code, doc

@allcontributors
Copy link
Contributor

@joakimbeng

I've put up a pull request to add @joakimbeng! 🎉

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/bun-plugin/src/utils.ts (1)

19-21: Consider extracting "NODE_ENV" as a named constant for symmetry with prefix.

prefix is already a named const on line 19. Extracting the hardcoded "NODE_ENV" to a similar constant keeps the filter condition self-documenting and makes future additions (e.g., other Bun-exposed built-ins) easier to manage.

♻️ Proposed refactor
 	const prefix = "BUN_PUBLIC_";
+	const builtinPublicKeys = ["NODE_ENV"] as const;
 	const filteredEnv = Object.fromEntries(
-		Object.entries(env).filter(([key]) => key === "NODE_ENV" || key.startsWith(prefix)),
+		Object.entries(env).filter(([key]) => (builtinPublicKeys as readonly string[]).includes(key) || key.startsWith(prefix)),
 	);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bun-plugin/src/utils.ts` around lines 19 - 21, The filter uses the
hardcoded string "NODE_ENV" alongside the prefix constant; extract "NODE_ENV"
into a named constant (e.g., const NODE_ENV_KEY = "NODE_ENV") and update the
filter in Object.fromEntries to use that constant so the check in filteredEnv
references prefix and NODE_ENV_KEY (and makes adding other built-ins easier);
update any related references to the named constant in this module (symbols:
prefix, filteredEnv, env) for symmetry and clarity.
packages/bun-plugin/src/utils.test.ts (1)

37-49: LGTM! Consider using vi.stubEnv for safer env isolation.

The test logic, schema syntax ("'development' | 'test' | 'production'" per ArkType conventions), and assertions are all correct.

As an optional improvement, replacing the manual process.env.X = value + process.env = originalEnv teardown pattern with Vitest's built-in vi.stubEnv / vi.unstubAllEnvs() would make the isolation more robust (Vitest owns the cleanup and handles non-configurable descriptors correctly):

-import { afterEach, beforeEach, describe, expect, it } from "vitest";
+import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
-	it("should not filter out NODE_ENV", () => {
-		process.env.NODE_ENV = "development";
+	it("should not filter out NODE_ENV", () => {
+		vi.stubEnv("NODE_ENV", "development");

And in afterEach:

 	afterEach(() => {
-		process.env = originalEnv;
+		vi.unstubAllEnvs();
 	});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bun-plugin/src/utils.test.ts` around lines 37 - 49, Replace manual
env mutation in the test that touches process.env with Vitest's environment
stubbing utilities: use vi.stubEnv to set NODE_ENV for the test case that calls
processEnvSchema and ensure cleanup by calling vi.unstubAllEnvs (or
vi.restoreAllEnvs) in the shared afterEach; update the test that references
NODE_ENV and any teardown that resets process.env to use vi.stubEnv("NODE_ENV",
"development") and remove manual process.env reassignment so Vitest handles
isolation safely for tests exercising processEnvSchema.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bun-plugin/src/utils.ts`:
- Line 21: In the Object.entries(env).filter(...) expression replace the
single-quoted 'NODE_ENV' with a double-quoted "NODE_ENV" to comply with the
Biome rule and match existing literals (look for the
Object.entries(env).filter(([key]) => key === 'NODE_ENV' ||
key.startsWith(prefix)) usage in utils.ts and change the string literal to
"NODE_ENV").

---

Nitpick comments:
In `@packages/bun-plugin/src/utils.test.ts`:
- Around line 37-49: Replace manual env mutation in the test that touches
process.env with Vitest's environment stubbing utilities: use vi.stubEnv to set
NODE_ENV for the test case that calls processEnvSchema and ensure cleanup by
calling vi.unstubAllEnvs (or vi.restoreAllEnvs) in the shared afterEach; update
the test that references NODE_ENV and any teardown that resets process.env to
use vi.stubEnv("NODE_ENV", "development") and remove manual process.env
reassignment so Vitest handles isolation safely for tests exercising
processEnvSchema.

In `@packages/bun-plugin/src/utils.ts`:
- Around line 19-21: The filter uses the hardcoded string "NODE_ENV" alongside
the prefix constant; extract "NODE_ENV" into a named constant (e.g., const
NODE_ENV_KEY = "NODE_ENV") and update the filter in Object.fromEntries to use
that constant so the check in filteredEnv references prefix and NODE_ENV_KEY
(and makes adding other built-ins easier); update any related references to the
named constant in this module (symbols: prefix, filteredEnv, env) for symmetry
and clarity.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/bun-plugin/README.md (1)

63-118: Consider adding a NODE_ENV schema example to improve discoverability.

All usage examples currently only demonstrate BUN_PUBLIC_* variables. Since the entire motivation of this PR is enabling TypeScript typing for NODE_ENV, showing that pattern at least once would make the docs immediately actionable for readers.

📝 Proposed addition to the Simple Setup example
 export default type({
   BUN_PUBLIC_API_URL: 'string',
   BUN_PUBLIC_DEBUG: 'boolean',
+  NODE_ENV: "'development' | 'production' | 'test'",
 });

Based on learnings, the project convention for enumerated environment variable values is to use ArkType string literal syntax (e.g., "'development' | 'production' | 'test'").

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bun-plugin/README.md` around lines 63 - 118, Add a NODE_ENV example
to both the Simple Setup and Advanced Setup examples by including an enumerated
ArkType string literal for NODE_ENV (e.g., "'development' | 'production' |
'test'") alongside the existing BUN_PUBLIC_* entries; update the src/env.ts
auto-discover example that calls type({ ... }) and the arkenv(type({...}))
passed into plugins so readers can see how to type NODE_ENV with the type()
helper and when passing the schema directly to the arkenv plugin.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/bun-plugin/README.md`:
- Around line 63-118: Add a NODE_ENV example to both the Simple Setup and
Advanced Setup examples by including an enumerated ArkType string literal for
NODE_ENV (e.g., "'development' | 'production' | 'test'") alongside the existing
BUN_PUBLIC_* entries; update the src/env.ts auto-discover example that calls
type({ ... }) and the arkenv(type({...})) passed into plugins so readers can see
how to type NODE_ENV with the type() helper and when passing the schema directly
to the arkenv plugin.

…ariable

Bun already exposes `process.env.NODE_ENV` to the frontend and with this change it's possible to type it with ArkEnv,
in same fashion as other public env vars.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/bun-plugin/src/utils.ts (1)

20-20: Consider hoisting allowed to a module-level constant.

allowed is a fixed Set that is reconstructed on every processEnvSchema call. Since its contents never change, extracting it to the module scope avoids repeated allocation.

♻️ Proposed refactor
+const ALLOWED_KEYS = new Set(["NODE_ENV"]);
+
 export function processEnvSchema<T extends SchemaShape>(
   ...
 ) {
   const prefix = "BUN_PUBLIC_";
-  const allowed = new Set(["NODE_ENV"]);
   const filteredEnv = Object.fromEntries(
-    Object.entries(env).filter(([key]) => allowed.has(key) || key.startsWith(prefix)),
+    Object.entries(env).filter(([key]) => ALLOWED_KEYS.has(key) || key.startsWith(prefix)),
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bun-plugin/src/utils.ts` at line 20, Hoist the constant Set
currently created inside processEnvSchema to module scope to avoid
reconstructing it on every call: move the declaration const allowed = new
Set(["NODE_ENV"]) out of the processEnvSchema function and export or keep it as
a module-level const (e.g., allowed) then update processEnvSchema to reference
this module-level allowed instead of recreating it; ensure no behavior change
and run tests/type checks to validate.
packages/bun-plugin/src/utils.test.ts (1)

37-49: Add a failure-case test for an invalid NODE_ENV value.

The new test covers only the happy path. Per coding guidelines, both success and failure cases should be tested. A test for an invalid value (e.g., "staging") would confirm that createEnv (and thus processEnvSchema) throws when the schema isn't satisfied.

✅ Suggested additional test
it("should throw when NODE_ENV is an invalid value", () => {
    process.env.NODE_ENV = "staging";

    expect(() =>
        processEnvSchema({
            NODE_ENV: "'development' | 'test' | 'production'",
        } as const),
    ).toThrow();
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bun-plugin/src/utils.test.ts` around lines 37 - 49, Add a
failing-case unit test that asserts processEnvSchema throws for an invalid
NODE_ENV value: set process.env.NODE_ENV = "staging" and call processEnvSchema({
NODE_ENV: "'development' | 'test' | 'production'" } as const) inside an
expect(() => ...).toThrow(); ensure the new it test name describes the failure
case (e.g., "should throw when NODE_ENV is an invalid value") so it complements
the existing happy-path test; reference the existing test harness in
utils.test.ts and keep the assertion style consistent with the other tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bun-plugin/README.md`:
- Line 76: Update the ArkType string examples for NODE_ENV to use outer-double /
inner-single quotes to match the project's canonical pattern and the new test;
specifically change the example for the symbol NODE_ENV from the current
outer-single/inner-double form to the form "'development' | 'test' |
'production' = 'development'" (also update the second occurrence noted at the
same file/line range); ensure the README examples mirror the string quoting used
by utils.test.ts and project guidelines.

---

Nitpick comments:
In `@packages/bun-plugin/src/utils.test.ts`:
- Around line 37-49: Add a failing-case unit test that asserts processEnvSchema
throws for an invalid NODE_ENV value: set process.env.NODE_ENV = "staging" and
call processEnvSchema({ NODE_ENV: "'development' | 'test' | 'production'" } as
const) inside an expect(() => ...).toThrow(); ensure the new it test name
describes the failure case (e.g., "should throw when NODE_ENV is an invalid
value") so it complements the existing happy-path test; reference the existing
test harness in utils.test.ts and keep the assertion style consistent with the
other tests.

In `@packages/bun-plugin/src/utils.ts`:
- Line 20: Hoist the constant Set currently created inside processEnvSchema to
module scope to avoid reconstructing it on every call: move the declaration
const allowed = new Set(["NODE_ENV"]) out of the processEnvSchema function and
export or keep it as a module-level const (e.g., allowed) then update
processEnvSchema to reference this module-level allowed instead of recreating
it; ensure no behavior change and run tests/type checks to validate.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 23, 2026

Open in StackBlitz

npm i https://pkg.pr.new/arkenv@804
npm i https://pkg.pr.new/@arkenv/bun-plugin@804
npm i https://pkg.pr.new/@arkenv/fumadocs-ui@804
npm i https://pkg.pr.new/@arkenv/vite-plugin@804

commit: 2cbd2d2

@yamcodes
Copy link
Owner

Hey @joakimbeng! This is a great idea! Instant approve!

@yamcodes yamcodes merged commit 6f8b4f0 into yamcodes:main Feb 23, 2026
17 of 18 checks passed
yamcodes pushed a commit that referenced this pull request Feb 23, 2026
Adds @joakimbeng as a contributor for code, doc.

This was requested by joakimbeng [in this
comment](#804 (comment))

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
Co-authored-by: arkenv-bot[bot] <237618717+arkenv-bot[bot]@users.noreply.github.com>
@arkenv-bot arkenv-bot bot mentioned this pull request Feb 23, 2026
yamcodes added a commit that referenced this pull request Feb 23, 2026
Natural continuation of #804 - that was the runtime change, this PR is
the typing change.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added NODE_ENV support in environment schemas with automatic
validation at startup and full type safety when included in the schema.

* **Documentation**
* Updated documentation with NODE_ENV usage examples and typing
guidance.

* **Chores**
  * Updated dependency versions across examples and playgrounds.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
yamcodes pushed a commit that referenced this pull request Feb 23, 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/bun-plugin@0.1.5

### Patch Changes

- #### Support `NODE_ENV` in schema
_[`#804`](#804)
[`6f8b4f0`](6f8b4f0)
[@joakimbeng](https://github.com/joakimbeng)_

When `NODE_ENV` is included in your schema, it is now validated at
startup and correctly typed.

    ```ts
    // src/env.ts
    import { type } from "arkenv";

    export default type({
      BUN_PUBLIC_API_URL: "string.url",
      NODE_ENV: "'development' | 'production' | 'test'",
    });
    ```

    ```tsx
// process.env.NODE_ENV is now typed as "development" | "production" |
"test"
    <p>Mode: {process.env.NODE_ENV}</p>
    ```

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

docs Improvements or additions to documentation tests This issue or PR is about adding, removing or changing tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants