Skip to content

Coercion Documentation#597

Merged
yamcodes merged 8 commits intocoercionfrom
567-coercion-documentation
Dec 22, 2025
Merged

Coercion Documentation#597
yamcodes merged 8 commits intocoercionfrom
567-coercion-documentation

Conversation

@yamcodes
Copy link
Owner

@yamcodes yamcodes commented Dec 22, 2025

Summary by CodeRabbit

  • New Features

    • Added comprehensive coercion documentation explaining automatic type conversion for environment variables.
  • Documentation

    • Updated documentation structure and navigation to reflect feature changes.
    • Removed morphs documentation.
  • Breaking Changes

    • Boolean morph feature has been removed; boolean coercion now handled through standard validation.
    • Port keyword validation enforced to numeric range 0-65535.
  • Chores

    • Renamed DEBUG environment variable to DEBUGGING with updated default value.

✏️ Tip: You can customize this high-level summary in your review settings.

- Update HOST type to accept "string.ip | 'localhost'"
- Update PORT type to "0 <= number.integer <= 65535"
- Refine README examples and error messages
- Changed env var name for clarity
- Updated usage in playgrounds and examples
@changeset-bot
Copy link

changeset-bot bot commented Dec 22, 2025

⚠️ No Changeset found

Latest commit: fabd8f9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 3 packages
Name Type
arkenv Minor
@arkenv/bun-plugin Patch
@arkenv/vite-plugin Patch

Click here to learn what changesets are, and how to add one.

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

@vercel
Copy link

vercel bot commented Dec 22, 2025

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

Project Deployment Review Updated (UTC)
arkenv Ready Ready Preview, Comment Dec 22, 2025 8:59pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Walkthrough

This pull request transitions ArkEnv's type coercion feature from "morphs" to "coercion," renaming documentation, updating environment variable schemas (HOST, PORT types; adding DEBUGGING variable), and implementing numeric keyword coercion tests and NaN handling logic updates across the codebase.

Changes

Cohort / File(s) Summary
Documentation & Metadata
apps/www/content/docs/arkenv/coercion.mdx, apps/www/content/docs/arkenv/morphs.mdx, apps/www/content/docs/arkenv/integrations/standard-schema.mdx, apps/www/content/docs/arkenv/meta.json
Added new coercion documentation file; deleted deprecated morphs documentation; removed "[New]" badge from standard-schema integration; updated navigation metadata to reference coercion instead of morphs in API section.
Examples & Playgrounds
apps/playgrounds/node/index.ts, examples/basic/index.ts
Renamed DEBUG environment variable to DEBUGGING, changed default from true to false in both playground and basic example configurations.
Configuration & Components
apps/www/components/banner.tsx, apps/www/source.config.ts
Updated banner to link to coercion documentation; added TypeScript module resolution paths for arkenv and @repo packages in Twoslash configuration.
Core Implementation
packages/arkenv/README.md, packages/arkenv/src/create-env.test.ts, packages/internal/keywords/src/index.ts
Updated README with revised schema types (HOST to "string.ip | 'localhost'", PORT to numeric range), added DEBUGGING variable; added numeric keywords coercion test suite; modified maybeParsedNumber to treat string "NaN" as numeric NaN value.
Changelog
.changeset/cyan-loops-hear.md
Updated changelog title from "Schema-Directed Coercion" to "Coercion"; documented breaking changes including removal of boolean morph and port keyword strictness.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

Possibly related PRs

Poem

🐰 Farewell to morphs, hello coercion—the old path fades away!
Numbers and booleans now parse straight, in the schema's display.
From playground to example, the variables are renamed with care,
String "NaN" finds its true form at last, a fix beyond compare! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title "Coercion Documentation" is partially related to the changeset but not the main point; the PR includes substantial code changes to coercion logic and environment variable handling alongside documentation updates. Consider a more descriptive title that reflects the primary change, such as "Refactor coercion system and update documentation" or "Replace morphs with built-in coercion and update docs".
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 567-coercion-documentation

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.

@github-actions github-actions bot added docs Improvements or additions to documentation arkenv Changes to the `arkenv` npm package. example Issues or Pull Requests concerning at least one ArkEnv example. (Found in the `examples/` directory) www Improvements or additions to arkenv.js.org labels Dec 22, 2025
- Disabled NaN coercion test case
- Added TODO comment for future implementation
- No functional code changes
@github-actions github-actions bot added the tests This issue or PR is about adding, removing or changing tests label Dec 22, 2025
@yamcodes yamcodes marked this pull request as ready for review December 22, 2025 20:43
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

♻️ Duplicate comments (1)
packages/arkenv/src/utils/coerce.ts (1)

149-154: Same NaN guard removal applies to array and object coercion paths.

The NaN guard has been removed consistently across all coercion paths (array items and object properties). This ensures uniform behavior but carries the same concerns about untested NaN handling mentioned in the root coercion path review.

Also applies to: 168-173, 177-182

🧹 Nitpick comments (3)
examples/basic/index.ts (1)

16-16: Consider renaming the log key for consistency.

The log property key is debug while the environment variable is DEBUGGING. For consistency, consider renaming to debugging.

🔎 Suggested change
 console.log({
 	host: env.HOST,
 	port: env.PORT,
 	nodeEnv: env.NODE_ENV,
-	debug: env.DEBUGGING,
+	debugging: env.DEBUGGING,
 });
packages/internal/keywords/src/index.ts (1)

3-10: Update JSDoc to reflect the new "NaN" handling.

The JSDoc states the output is "A number if the input is a numeric string; otherwise the original input." With the new behavior, the string "NaN" is now converted to numeric NaN, which should be documented.

🔎 Suggested JSDoc update
 /**
  * A loose numeric morph.
  *
  * **In**: `unknown`
  *
- * **Out**: A `number` if the input is a numeric string; otherwise the original input.
+ * **Out**: A `number` if the input is a numeric string (including `"NaN"`); otherwise the original input.
  *
  * Useful for coercion in unions where failing on non-numeric strings would block other branches.
  */
apps/www/content/docs/arkenv/coercion.mdx (1)

1-74: Comprehensive and well-structured coercion documentation.

The new documentation effectively explains ArkEnv's coercion feature with clear examples for numbers, booleans, and advanced use cases. The "How it works" and "Performance" sections provide valuable context for developers. The links to GitHub and Discord for feedback are helpful.

One minor optional suggestion: Line 71 could use "Currently" instead of "At the moment" for conciseness, though this is stylistic preference.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 167ba08 and 8b9d989.

📒 Files selected for processing (12)
  • apps/playgrounds/node/index.ts
  • apps/www/components/banner.tsx
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/www/content/docs/arkenv/integrations/standard-schema.mdx
  • apps/www/content/docs/arkenv/meta.json
  • apps/www/content/docs/arkenv/morphs.mdx
  • apps/www/source.config.ts
  • examples/basic/index.ts
  • packages/arkenv/README.md
  • packages/arkenv/src/create-env.test.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/internal/keywords/src/index.ts
💤 Files with no reviewable changes (2)
  • apps/www/content/docs/arkenv/morphs.mdx
  • apps/www/content/docs/arkenv/integrations/standard-schema.mdx
🧰 Additional context used
📓 Path-based instructions (11)
packages/arkenv/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/arktype.mdc)

packages/arkenv/**/*.ts: Use ArkType's type() function to define schemas in environment variable definitions
Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Use the scoped $ type system for custom types defined in scope.ts
Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Use union types for enums in ArkType schemas (e.g., "'dev' | 'prod'") instead of separate enum definitions
Leverage ArkType's built-in types (e.g., string.host, number.port) where possible in environment schemas
Convert ArkType validation errors to ArkEnvError for user-friendly error messages that include variable name and expected type

Files:

  • packages/arkenv/src/create-env.test.ts
  • packages/arkenv/src/utils/coerce.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

**/*.{ts,tsx}: Prefer type over interface for type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverage const type parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypes error)
Use as const where appropriate for immutable values (useAsConstAssertion error)
Don't reassign function parameters (noParameterAssign error)
Place default parameters last in function signatures (useDefaultParameterLast error)
Always initialize enum values (useEnumInitializers error)
Declare one variable per statement (useSingleVarDeclarator error)
Avoid unnecessary template literals (noUnusedTemplateLiteral error)
Prefer Number.parseInt over global parseInt (useNumberNamespace error)
Use kebab-case for TypeScript filenames (e.g., create-env.ts)
Use camelCase for function names (e.g., createEnv)
Use PascalCase for type names (e.g., ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
Use ArkEnvError for environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type

**/*.{ts,tsx}: Use createEnv(schema) as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) from src/types.ts when available instead of custom validation
Use ArkEnvError for environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...

Files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • apps/www/components/banner.tsx
  • packages/internal/keywords/src/index.ts
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Co-locate tests with components: Component.tsx next to Component.test.tsx

**/*.test.{ts,tsx}: Test individual functions, components, and hooks in isolation with mocked dependencies using the *.test.ts or *.test.tsx suffix
Mock process.env in tests for different scenarios and save/restore original env in beforeEach/afterEach hooks
Use Vitest's describe/it structure in test files
Test edge cases including invalid and missing environment variable values
Use Vitest for testing framework

**/*.test.{ts,tsx}: Use Vitest for unit and integration tests
Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Unit tests should execute in less than 100ms per test
Mock external dependencies (clipboard, network, etc.) in unit tests
Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)
Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Use Testing Library with user-event for real user simulation in component tests
Query by role, name, label, and text (accessibility first) in component tests
Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible
Keep tests fast, deterministic, and parallelizable
Mock at component boundaries (network, time, context)

Files:

  • packages/arkenv/src/create-env.test.ts
packages/arkenv/src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Main library implementation should be in src/create-env.ts, built-in validators in src/types.ts, error handling in src/errors.ts, and utilities in src/utils.ts

Files:

  • packages/arkenv/src/create-env.test.ts
  • packages/arkenv/src/utils/coerce.ts
**/*.{ts,tsx,json,md}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Biome for linting and formatting instead of ESLint and Prettier

Files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • apps/www/content/docs/arkenv/meta.json
  • packages/arkenv/README.md
  • packages/arkenv/src/utils/coerce.ts
  • apps/www/components/banner.tsx
  • packages/internal/keywords/src/index.ts
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
{bin,examples,playgrounds}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Console usage is allowed in bin/ and example/playground directories, otherwise treated as warning

Files:

  • examples/basic/index.ts
**/index.ts

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Use barrel exports (index.ts) for package entry points

Files:

  • examples/basic/index.ts
  • packages/internal/keywords/src/index.ts
  • apps/playgrounds/node/index.ts
examples/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

examples/**/*.{ts,tsx}: Ensure examples demonstrate secure default practices
Add examples in the examples/ directory for new functionality, demonstrating real-world usage patterns

Files:

  • examples/basic/index.ts
**/README.md

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Document environment requirements in README files

Files:

  • packages/arkenv/README.md
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Use self-closing JSX elements (useSelfClosingElements error)

Files:

  • apps/www/components/banner.tsx
apps/www/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/www/.cursor/rules/posthog-integration.mdc)

apps/www/**/*.{ts,tsx,js,jsx}: If using TypeScript, use an enum to store feature flag names. If using JavaScript, store feature flag names as strings to an object declared as a constant to simulate an enum. Use UPPERCASE_WITH_UNDERSCORE naming convention for enum/const object members.
If a custom property for a person or event is referenced in two or more files or two or more callsites in the same file, use an enum or const object with UPPERCASE_WITH_UNDERSCORE naming convention, similar to feature flags.

Files:

  • apps/www/components/banner.tsx
  • apps/www/source.config.ts
🧠 Learnings (26)
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.test.{ts,tsx} : Test edge cases including invalid and missing environment variable values

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • packages/arkenv/README.md
  • packages/arkenv/src/utils/coerce.ts
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • packages/arkenv/README.md
  • packages/arkenv/src/utils/coerce.ts
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • packages/arkenv/README.md
  • apps/www/content/docs/arkenv/coercion.mdx
📚 Learning: 2025-12-22T19:44:07.593Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:07.593Z
Learning: In examples/basic/index.ts: Use explicit ArkType syntax (e.g., "string.ip | 'localhost'", "0 <= number.integer <= 65535") instead of built-in validators (string.host, number.port) to showcase ArkType's type system capabilities for educational purposes.

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • packages/arkenv/README.md
  • packages/arkenv/src/utils/coerce.ts
  • apps/www/content/docs/arkenv/coercion.mdx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)

Applied to files:

  • packages/arkenv/src/create-env.test.ts
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Keep tests fast, deterministic, and parallelizable

Applied to files:

  • packages/arkenv/src/create-env.test.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • packages/arkenv/README.md
  • packages/arkenv/src/utils/coerce.ts
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to packages/arkenv/src/**/*.ts : Main library implementation should be in `src/create-env.ts`, built-in validators in `src/types.ts`, error handling in `src/errors.ts`, and utilities in `src/utils.ts`

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors

Applied to files:

  • packages/arkenv/src/create-env.test.ts
  • examples/basic/index.ts
  • packages/arkenv/README.md
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use descriptive environment variable names that indicate purpose and format

Applied to files:

  • examples/basic/index.ts
  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable errors, not generic errors

Applied to files:

  • examples/basic/index.ts
  • packages/arkenv/README.md
  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use UPPER_SNAKE_CASE for environment variables and constants

Applied to files:

  • examples/basic/index.ts
  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use PascalCase for type names (e.g., `ArkEnvError`)

Applied to files:

  • examples/basic/index.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use ArkType's `type()` function to define schemas in environment variable definitions

Applied to files:

  • packages/arkenv/README.md
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/playgrounds/node/index.ts
  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition

Applied to files:

  • packages/arkenv/README.md
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern

Applied to files:

  • packages/arkenv/README.md
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's type inference for TypeScript types instead of manual type definitions

Applied to files:

  • packages/arkenv/README.md
  • apps/www/content/docs/arkenv/coercion.mdx
  • apps/www/source.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export

Applied to files:

  • packages/arkenv/README.md
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Prefer `Number.parseInt` over global `parseInt` (`useNumberNamespace` error)

Applied to files:

  • packages/arkenv/src/utils/coerce.ts
  • packages/internal/keywords/src/index.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Organize imports automatically (Biome handles this)

Applied to files:

  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript 5.1+ features when appropriate

Applied to files:

  • apps/www/source.config.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript for the primary language throughout the project

Applied to files:

  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/index.ts : Use barrel exports (`index.ts`) for package entry points

Applied to files:

  • apps/www/source.config.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use the scoped `$` type system for custom types defined in `scope.ts`

Applied to files:

  • apps/www/source.config.ts
🧬 Code graph analysis (2)
packages/arkenv/src/create-env.test.ts (2)
packages/arkenv/src/create-env.ts (1)
  • createEnv (36-56)
packages/arkenv/src/index.ts (1)
  • createEnv (13-13)
examples/basic/index.ts (2)
apps/playgrounds/js/index.js (1)
  • env (3-7)
examples/basic-js/index.js (1)
  • env (3-7)
🪛 LanguageTool
apps/www/content/docs/arkenv/coercion.mdx

[style] ~71-~71: For conciseness, consider replacing this expression with an adverb.
Context: ... process.env. ## Disabling coercion At the moment, there is no way to disable coercion or...

(AT_THE_MOMENT)

🔇 Additional comments (10)
apps/www/components/banner.tsx (1)

9-16: LGTM!

The banner updates correctly reflect the new coercion documentation. The id, navigation path, and descriptive text are all properly aligned with the PR's rename from "morphs" to "coercion".

examples/basic/index.ts (1)

7-7: LGTM!

The environment variable rename from DEBUG to DEBUGGING and the default value change to false are consistent with the PR objectives. The naming follows UPPER_SNAKE_CASE convention as per coding guidelines.

packages/internal/keywords/src/index.ts (1)

12-18: Verify the intended behavior for the string "NaN".

The updated logic converts the literal string "NaN" to the numeric NaN value. When s === "NaN":

  • Number("NaN") returns numeric NaN
  • The condition Number.isNaN(n) && s !== "NaN" evaluates to false
  • Therefore, the function returns numeric NaN

This is a functional change from the previous behavior where "NaN" would have been returned as-is. Please confirm this is the intended behavior for your coercion use cases, as numeric NaN can cause unexpected issues in downstream comparisons (NaN !== NaN).

apps/www/source.config.ts (1)

48-52: LGTM!

The Twoslash compiler options correctly configure module resolution for arkenv and @repo/* internal packages. This enables proper type inference and hover information in documentation code examples.

apps/www/content/docs/arkenv/meta.json (2)

12-12: LGTM!

The rename from morphs to coercion correctly reflects the terminology change across the documentation.


17-17: LGTM!

Removing the [New] prefix from the Standard Schema link is appropriate as the feature is now established.

packages/arkenv/src/create-env.test.ts (1)

97-139: Excellent test coverage for numeric keyword coercion.

The new test suite comprehensively validates coercion behavior for various numeric ArkType keywords (number, number.Infinity, number.NegativeInfinity, number.epoch, number.integer, number.safe). The tests are well-structured and follow Vitest patterns correctly.

The TODO comment for NaN coercion (lines 108-112) appropriately acknowledges incomplete functionality. As noted in the coerce.ts review, ensure this TODO is addressed before the NaN guard removal in the implementation is finalized.

apps/playgrounds/node/index.ts (1)

7-7: LGTM! Environment variable renaming is consistent.

The rename from DEBUG to DEBUGGING and the default value change from true to false align with the broader PR changes. The usage is correctly updated throughout the file.

Also applies to: 16-16

packages/arkenv/README.md (2)

44-47: Schema updates align with educational and documentation goals.

The changes from built-in validators (string.host, number.port) to explicit ArkType syntax ("string.ip | 'localhost'", "0 <= number.integer <= 65535") effectively showcase ArkType's type system capabilities. The DEBUG to DEBUGGING rename and addition of default values are consistent with changes throughout the PR.

Based on learnings: In examples, use explicit ArkType syntax to showcase capabilities for educational purposes.

Also applies to: 54-54


74-74: Feature list accurately reflects new coercion capability.

The addition of "coerced" to the features list ("Validated, defaultable, coerced, typesafe environment variables") correctly highlights the automatic type coercion functionality that is central to this PR's documentation updates.

- Handle NaN during numeric parsing
- Ensure correct type parsing for env vars
- Update documentation for coercion system
- Renamed DEBUGGING to debugging in two files
- Consistent naming for environment variables
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 0

🧹 Nitpick comments (1)
.changeset/cyan-loops-hear.md (1)

5-16: Excellent changelog—breaking changes clearly communicated.

The entry effectively documents the coercion feature transition, with the breaking changes section providing sufficient detail for users to assess impact. The reassurance note at line 16 is particularly helpful for users following official patterns. Documentation reference is provided. The terminology shift from "morphs" to "coercion" is consistent with the PR objectives.

Optional refinement: Line 14 uses "outside of," which is idiomatic; "outside" alone would also be valid. LanguageTool flagged this as redundant, but either phrasing works fine here. If you prefer stricter brevity in changelog copy, consider the alternative—otherwise, no change needed.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b9d989 and fabd8f9.

📒 Files selected for processing (3)
  • .changeset/cyan-loops-hear.md
  • apps/playgrounds/node/index.ts
  • examples/basic/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/basic/index.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

**/*.{ts,tsx}: Prefer type over interface for type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverage const type parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypes error)
Use as const where appropriate for immutable values (useAsConstAssertion error)
Don't reassign function parameters (noParameterAssign error)
Place default parameters last in function signatures (useDefaultParameterLast error)
Always initialize enum values (useEnumInitializers error)
Declare one variable per statement (useSingleVarDeclarator error)
Avoid unnecessary template literals (noUnusedTemplateLiteral error)
Prefer Number.parseInt over global parseInt (useNumberNamespace error)
Use kebab-case for TypeScript filenames (e.g., create-env.ts)
Use camelCase for function names (e.g., createEnv)
Use PascalCase for type names (e.g., ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
Use ArkEnvError for environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type

**/*.{ts,tsx}: Use createEnv(schema) as the main function for validated environment objects, available as the default export
Use built-in validators (host, port, url, email) from src/types.ts when available instead of custom validation
Use ArkEnvError for environment variable errors, not generic errors
Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern
Use logical grouping for related environment variables in schemas
Use descriptive env...

Files:

  • apps/playgrounds/node/index.ts
**/index.ts

📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)

Use barrel exports (index.ts) for package entry points

Files:

  • apps/playgrounds/node/index.ts
**/*.{ts,tsx,json,md}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Biome for linting and formatting instead of ESLint and Prettier

Files:

  • apps/playgrounds/node/index.ts
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use descriptive environment variable names that indicate purpose and format

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use UPPER_SNAKE_CASE for environment variables and constants

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use logical grouping for related environment variables in schemas

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax

Applied to files:

  • apps/playgrounds/node/index.ts
  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` as the main function for validated environment objects, available as the default export

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use camelCase for function names (e.g., `createEnv`)

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-24T16:04:58.629Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: apps/playgrounds/bun/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-11-24T16:04:58.629Z
Learning: Applies to apps/playgrounds/bun/**/*.{ts,js} : Use `bun <file>` instead of `node <file>` or `ts-node <file>` for running scripts

Applied to files:

  • apps/playgrounds/node/index.ts
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable errors, not generic errors

Applied to files:

  • apps/playgrounds/node/index.ts
  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Leverage ArkType's built-in types (e.g., `string.host`, `number.port`) where possible in environment schemas

Applied to files:

  • apps/playgrounds/node/index.ts
  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use ArkType's `type()` function to define schemas in environment variable definitions

Applied to files:

  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions

Applied to files:

  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors

Applied to files:

  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-29T22:11:39.931Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T22:11:39.931Z
Learning: Applies to **/*.{ts,tsx} : Environment schema definitions should use built-in validators, ArkType string literals, and support default values in the schema pattern

Applied to files:

  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-12-22T19:44:07.593Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:07.593Z
Learning: In examples/basic/index.ts: Use explicit ArkType syntax (e.g., "string.ip | 'localhost'", "0 <= number.integer <= 65535") instead of built-in validators (string.host, number.port) to showcase ArkType's type system capabilities for educational purposes.

Applied to files:

  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-09-10T19:35:18.179Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 136
File: .changeset/vast-bananas-win.md:2-3
Timestamp: 2025-09-10T19:35:18.179Z
Learning: The arkenv package is currently in v0.x.x (pre-1.0) development phase, where breaking changes are acceptable in minor version bumps according to semantic versioning conventions.

Applied to files:

  • .changeset/cyan-loops-hear.md
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type

Applied to files:

  • .changeset/cyan-loops-hear.md
🪛 LanguageTool
.changeset/cyan-loops-hear.md

[style] ~14-~14: This phrase is redundant. Consider using “outside”.
Context: ... no longer parses strings automatically outside of createEnv / arkenv. If your only u...

(OUTSIDE_OF)

🔇 Additional comments (2)
apps/playgrounds/node/index.ts (2)

16-16: LGTM!

The console output property name correctly reflects the renamed environment variable and follows camelCase convention.


7-7: The rename from DEBUG to DEBUGGING and default value change in this file are complete with no orphaned references.

@yamcodes yamcodes merged commit 84c1145 into coercion Dec 22, 2025
7 checks passed
@yamcodes yamcodes deleted the 567-coercion-documentation branch December 22, 2025 21:57
@yamcodes yamcodes mentioned this pull request Dec 22, 2025
@yamcodes yamcodes linked an issue Dec 22, 2025 that may be closed by this pull request
This was referenced Dec 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arkenv Changes to the `arkenv` npm package. docs Improvements or additions to documentation example Issues or Pull Requests concerning at least one ArkEnv example. (Found in the `examples/` directory) 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.

Coercion Documentation

1 participant