Skip to content

Conversation

@yamcodes
Copy link
Owner

@yamcodes yamcodes commented Jan 6, 2026

Closes #705

Summary by CodeRabbit

  • New Features

    • Support for Standard Schema validators (e.g. Zod) alongside ArkType, including mixed validator mappings
    • Runtime routing so validation works with or without ArkType installed
  • Bug Fixes

    • Unified, clearer validation error formatting across validator types
  • Tests

    • Expanded tests and fixtures for Standard Schema, hybrid flows, and missing-ArkType scenarios
  • Examples

    • New example demonstrating usage without ArkType
  • Chores

    • Updated dev tooling, package metadata, and type definitions to enable these flows

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

- Normalize ArkEnvError constructor input
- Add public issues property to ArkEnvError
- Deprecate and refactor formatErrors function
@changeset-bot
Copy link

changeset-bot bot commented Jan 6, 2026

⚠️ No Changeset found

Latest commit: da5ca1f

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 no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

Walkthrough

createEnv now detects validator types at runtime (lazy-loading ArkType if present) and routes validation/coercion for ArkType vs Standard Schema validators, normalizing errors to EnvIssue, updating coercion and type inference, adding lazy scope/keywords, tests, fixtures, and examples for non-ArkType usage.

Changes

Cohort / File(s) Summary
Core runtime & API
packages/arkenv/src/create-env.ts, packages/arkenv/src/create-env.test.ts, packages/arkenv/src/standard-schema.test.ts
Runtime routing between ArkType and Standard Schema validators; new ArkEnvConfig shape (env, coerce options, onUndeclaredKey, arrayFormat); validation helpers/type guards; updated overloads and tests for mixed flows.
Error formatting
packages/arkenv/src/errors.ts
Added EnvIssue type; formatErrors and ArkEnvError accept `ArkErrors
Coercion utilities
packages/arkenv/src/utils/coerce.ts
Rewrote coercion to runtime-driven engine with CoerceConfig, coerce(schema, env, config) and coerceValue; removed old path-finding API; supports object/array/number/boolean parsing and arrayFormat.
Type wrapper & lazy scope
packages/arkenv/src/type.ts, packages/internal/scope/src/lazy-type.ts, packages/internal/scope/src/index.ts, packages/internal/scope/src/scope-def.ts, packages/internal/scope/tsconfig.json
type and $ replaced with Proxy/lazy loaders (lazyType, lazy scope); arktype loaded on demand; added scope types and reset utilities.
Internal types & inference
packages/internal/types/src/standard-schema.ts, packages/internal/types/src/infer-type.ts, packages/internal/types/src/schema.ts, packages/internal/types/src/filter-by-prefix.ts, packages/internal/types/src/index.ts
Introduced StandardSchemaV1 types; extended InferType to include Standard Schema; SchemaShape became TS alias; widened EnvSchemaWithType; adjusted FilterByPrefix constraint.
Plugins & tests
packages/vite-plugin/src/index.ts, packages/vite-plugin/src/index.test.ts, packages/vite-plugin/src/types.ts, packages/vite-plugin/src/__fixtures__/standard-schema/*, packages/bun-plugin/src/index.ts, packages/bun-plugin/src/index.test.ts
Plugin callsites cast options to avoid deep generics; added Zod-based fixtures/tests and Bun plugin test exercising Standard Schema path; typing overloads updated.
Keywords & scope internals
packages/internal/keywords/src/index.ts, packages/internal/keywords/package.json, packages/internal/keywords/tsdown.config.ts, packages/internal/scope/src/keywords.ts
Extracted keyword morphs into scope package, added maybeNumber/Boolean/Json, port, host, re-export via @repo/scope.
Packaging / build configs
packages/arkenv/package.json, packages/vite-plugin/package.json, packages/internal/scope/package.json, packages/arkenv/tsdown.config.ts, packages/internal/keywords/tsdown.config.ts
Added zod devDeps, @types/node devDep, marked arktype optional via peerDependenciesMeta, updated tsdown externals/noExternal and dts.resolve, adjusted size-limit ignore.
Examples & workspace
examples/without-arktype/*, arkenv.code-workspace, examples/README.md
Added example project demonstrating usage without ArkType, workspace entry, and README update.
Misc test infra
packages/vite-plugin/src/index.test.ts.tmp, packages/arkenv/src/arktype-optional.integration.test.ts, packages/arkenv/src/create-env.test.ts
Added integration and unit tests covering lazy-loading, optional ArkType, Standard Schema paths, and test scaffolding/mocks.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client Code
    participant createEnv as createEnv
    participant Detector as Validator Detector
    participant ArkType as ArkType (runtime)
    participant Standard as Standard Schema Validator
    participant Error as ErrorHandler

    Client->>createEnv: call createEnv(def, config)
    createEnv->>Detector: inspect def

    alt def is ArkType (compiled)
        Detector->>ArkType: require('arktype') & validate/coerce
        ArkType-->>createEnv: validated/coerced result
    else def is mapping of Standard Schema validators
        Detector->>Standard: invoke each validator.validate/coerce
        Standard-->>createEnv: validation results
    else def is top-level Standard Schema (unsupported)
        Detector->>Error: prepare unsupported top-level schema error
        Error-->>createEnv: throw ArkEnvError
    end

    alt success
        createEnv-->>Client: return distilled values (InferType<T>)
    else failure
        Error->>createEnv: format ArkErrors or EnvIssue[]
        createEnv-->>Client: throw ArkEnvError
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • yamcodes/arkenv#713 — shares targets (EnvIssue, lazy arktype loader, runtime coercion refactor); this PR implements overlapping refactors and error-shape changes.

Possibly related PRs

  • #572 — touches the same coercion implementation and signatures.
  • #382 — overlaps with createEnv runtime detection and ArkType handling.
  • #139 — related to type export/alias changes and DX around public type exposure.

Poem

🐰
I nibbled bytes beneath the moon so bright,
Let Zod and ArkType share the same light.
Lazy hops, light loads, validators play,
Env keys settle snug at end of day.
Hop on—envs are freer, soft and light. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and concisely summarizes the main changes: making ArkType optional and adding Standard Schema support.
Linked Issues check ✅ Passed The PR implements all major coding requirements from issue #705: ArkType is now optional, Standard Schema validators are supported, mixing both is allowed, coercion remains ArkType-specific, and error handling is normalized.
Out of Scope Changes check ✅ Passed The PR includes necessary infrastructure changes (workspace config, tsdown config, type system updates) that directly support the main objectives of making ArkType optional and adding Standard Schema support.

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

✨ Finishing touches
  • 📝 Generate docstrings

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 arkenv Changes to the `arkenv` npm package. tests This issue or PR is about adding, removing or changing tests labels Jan 6, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 6, 2026

Open in StackBlitz

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

commit: da5ca1f

@arkenv-bot
Copy link
Contributor

arkenv-bot bot commented Jan 6, 2026

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

Project Deployment Review Updated (Asia/Almaty)
arkenv Ready Ready Preview, Comment Jan 13 2026, 11:01 PM (Asia/Almaty)

@github-actions github-actions bot added the @arkenv/vite-plugin Issues or Pull Requests involving the Vite plugin for ArkEnv label Jan 6, 2026
@yamcodes
Copy link
Owner Author

yamcodes commented Jan 6, 2026

  • 1. Remove or reject arkenv(z.object(...))
  • * Only allow Standard Schema inside object mappings
  • * This preserves ArkEnv’s identity and migration story
  • 2. Keep one public API
  • * arkenv(...)
  • * Everything else internal or deprecated-for-real
  • 3. Reframe Standard Schema as support, not replacement
  • * Migration tool, not an alternative product direction

@yamcodes yamcodes changed the title Make ArkEnv optional Make ArkType optional and support Standard Schema directly Jan 6, 2026
- `arkenv()` now strictly expects a schema mapping object
- No longer accepts top-level compiled ArkType or Zod
@github-actions github-actions bot added docs Improvements or additions to documentation www Improvements or additions to arkenv.js.org labels Jan 8, 2026
- Allow compiled ArkType schemas as top-level arg
- Support standard Zod schemas as top-level arg
- Remove invalid schema argument error
- Update Bun and Vite plugins to support new schema types
- Remove deprecated formatErrors function.
- Update tests to use formatIssues directly.
- Simplify error formatting logic.
@arkenv-bot
Copy link
Contributor

arkenv-bot bot commented Jan 10, 2026

📦 Bundle Size Report

Package Size Limit Diff Status
@arkenv/vite-plugin 3.08 kB 1.95 kB +72.1%
arkenv 2.92 kB 1.95 kB +75.9%
@arkenv/bun-plugin 3.55 kB 2.44 kB +55.0%

Size limits exceeded! Please review the changes above.

@yamcodes yamcodes marked this pull request as ready for review January 12, 2026 17:16
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/arkenv/package.json (1)

42-57: Move @standard-schema/spec from devDependencies to dependencies.

The package is imported in create-env.ts as a type-only import for StandardSchemaV1, which is used to detect and handle Standard Schema validators at runtime. TypeScript consumers will encounter "Cannot find module '@standard-schema/spec'" errors during type checking because the type is part of the public API surface, even though the actual object instantiation happens at runtime. Since there is currently no dependencies section, create one and add @standard-schema/spec: "1.0.0".

🤖 Fix all issues with AI agents
In @packages/arkenv/package.json:
- Around line 66-76: The package is using runtime imports from @repo/scope
(e.g., $.type used via Reflect.get/apply in type.ts and $.type() call in
create-env.ts) but @repo/scope is not declared in packages/arkenv/package.json
and is only listed in the size-limit ignore; either add a real dependency entry
for @repo/scope in package.json (using the appropriate version or workspace:* if
you intend a workspace link) so consumers get it at install time, or refactor
type.ts and create-env.ts to remove the runtime use of $/$.type (replace with a
local implementation or an explicit dependency already allowed) and then remove
@repo/scope from the size-limit ignore list.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c6e05d and ecce88e.

📒 Files selected for processing (2)
  • packages/arkenv/package.json
  • packages/vite-plugin/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/vite-plugin/package.json
🧰 Additional context used
📓 Path-based instructions (3)
packages/*/package.json

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

Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions

Files:

  • packages/arkenv/package.json
**/package.json

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

Use workspace:* protocol for workspace dependencies between packages

Files:

  • packages/arkenv/package.json
{packages,apps,tooling}/**/package.json

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

When referencing workspace packages in dependencies, use the workspace:* protocol instead of version numbers

Files:

  • packages/arkenv/package.json
🧠 Learnings (13)
📓 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 : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
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: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
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
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
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
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
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types
📚 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/package.json
📚 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:

  • packages/arkenv/package.json
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to packages/*/package.json : Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions

Applied to files:

  • packages/arkenv/package.json
📚 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/package.json
📚 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/package.json
📚 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/package.json
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to package.json : Configure only built dependencies (native modules) in `pnpm.onlyBuiltDependencies`, including: biomejs/biome, sentry/cli, swc/core, tailwindcss/oxide, vercel/speed-insights, esbuild, and sharp

Applied to files:

  • packages/arkenv/package.json
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to tooling/*/package.json : Tooling in tooling/ directory contains development and testing tools that are not published to npm and excluded from changesets

Applied to files:

  • packages/arkenv/package.json
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: packages/arkenv should not depend on other workspace packages; packages/vite-plugin depends on arkenv; apps/www may depend on workspace packages

Applied to files:

  • packages/arkenv/package.json
📚 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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/arkenv/package.json
📚 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:

  • packages/arkenv/package.json
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")

Applied to files:

  • packages/arkenv/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Deploy-Preview
  • GitHub Check: test-e2e (a11y)
  • GitHub Check: test-e2e (e2e)
🔇 Additional comments (2)
packages/arkenv/package.json (2)

61-65: Add a changeset for the arkenv published package.

This PR makes ArkType an optional peer dependency and adds Standard Schema support in a published package. Per repo guidelines, published packages in packages/ require a .changeset/*.md file for version tracking and changelog generation. Run pnpm changeset and select the appropriate bump type (likely minor for new Standard Schema support).


58-65: Optional peer dependency for arktype is correctly configured.

The ^2.1.22 minimum version is appropriate. Review of the arkenv source confirms only fundamental arktype APIs are used: type() function, .onUndeclaredKey(), schema invocation, type.errors, and .toJsonSchema(). These are core features available in 2.1.22 and later. The monorepo currently uses 2.1.29, and no CHANGELOG entries indicate API breaking changes in the patch range.

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

🤖 Fix all issues with AI agents
In @packages/arkenv/package.json:
- Around line 54-64: Update the arkenv package.json to bump the peerDependencies
entry "arktype" from "^2.1.22" to "^2.1.28" (edit the peerDependencies.arktype
field) and add a changeset for packages/arkenv describing this dependency bump
(create a new changeset markdown/yaml file in packages/arkenv/.changeset per the
monorepo guidelines indicating a patch/minor release and the change to arkenv).

In @packages/arkenv/src/create-env.ts:
- Around line 71-129: The code currently requires "arktype" unconditionally
inside validateArkType, forcing consumers to install ArkType even when using
only Standard Schema validators like Zod; fix by changing createEnv to detect
whether ArkType is available first (try/catch dynamic require or a helper like
isArktypeAvailable) and route accordingly: if available, call validateArkType
(keep its current logic but remove unconditional require at top—lazy-require
only inside the ArkType path); if not available, implement and call
validateStandardSchemaMapping (a new function that mirrors validation/coercion
for Standard Schema mappings using detectValidatorType to distinguish
Zod/standard validators, apply coerce/arrayFormat behavior as needed, and
produce the same { success, value } | { success: false, issues } shape); also
ensure detectValidatorType is used to error when a mapping actually uses
ArkType-specific compiled Types while ArkType is absent, returning a clear
message rather than triggering MODULE_NOT_FOUND.

In @packages/internal/types/src/infer-type.ts:
- Around line 10-13: InferType currently captures the Input from
StandardSchemaV1, causing wrong types when validators coerce/transform; update
the conditional on StandardSchemaV1 in InferType to infer both generic params
and return the Output type (e.g., infer _In and infer Out then use Out), and
keep the existing branch for Type<...> (returning its inferred output) and a
sensible fallback for other T.

In @packages/internal/types/src/standard-schema.ts:
- Around line 1-5: Add the required MIT copyright attribution block at the top
of this copied file by inserting a comment containing the existing @see line
plus the "Copied from standard-schema (MIT License)" and "Copyright (c) 2024
Colin McDannell" lines before the biome-ignore-all comment; ensure the new
comment preserves the @see URL and places the copyright and permission notice
immediately above the biome-ignore comment so the file clearly includes the
original repository attribution.
🧹 Nitpick comments (4)
packages/arkenv/package.json (1)

8-8: Minor: package description/keywords still ArkType-only

Given Standard Schema support, consider updating the description/keywords so Zod-only users don’t assume ArkType is required.

Also applies to: 54-56

packages/arkenv/src/create-env.ts (3)

46-69: detectValidatorType: heuristic seems fine, but the “isStandard” check only inspects the top-level

This won’t help you decide whether a mapping can be validated without ArkType (you’d need to inspect the mapping’s values for ~standard vs ArkType DSL).


116-128: MODULE_NOT_FOUND detection is brittle across Node versions

e.message.includes("'arktype'") (Line 121) varies; consider using require.resolve("arktype") (or checking e.message.includes("arktype")) to avoid false negatives.


156-163: Guardrail message mentions arkenv() but this is createEnv()

Probably fine if arkenv is the default wrapper, but consider ensuring the thrown message matches the actual entrypoint users see in stack traces (or mention both).

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ecce88e and da6b3f8.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • packages/arkenv/package.json
  • packages/arkenv/src/create-env.ts
  • packages/internal/types/src/index.ts
  • packages/internal/types/src/infer-type.ts
  • packages/internal/types/src/schema.ts
  • packages/internal/types/src/standard-schema.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/internal/types/src/schema.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{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) function (or default import as arkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...

Files:

  • packages/internal/types/src/index.ts
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/types/src/standard-schema.ts
**/index.ts

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

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

Files:

  • packages/internal/types/src/index.ts
packages/*/package.json

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

Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions

Files:

  • packages/arkenv/package.json
**/package.json

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

Use workspace:* protocol for workspace dependencies between packages

Files:

  • packages/arkenv/package.json
{packages,apps,tooling}/**/package.json

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

When referencing workspace packages in dependencies, use the workspace:* protocol instead of version numbers

Files:

  • packages/arkenv/package.json
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.ts
🧠 Learnings (26)
📓 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 : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
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: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
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
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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.
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
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
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
📚 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:

  • packages/internal/types/src/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:

  • packages/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/types/src/standard-schema.ts
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to packages/*/package.json : Packages in packages/ directory must be published to npm and require changesets for versioning, proper exports, and type definitions

Applied to files:

  • packages/internal/types/src/index.ts
  • packages/arkenv/package.json
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript

Applied to files:

  • packages/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/arkenv/src/create-env.ts
  • packages/internal/types/src/standard-schema.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/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/types/src/standard-schema.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")

Applied to files:

  • packages/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/arkenv/src/create-env.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/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.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/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-05T20:33:10.676Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition

Applied to files:

  • packages/internal/types/src/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: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition

Applied to files:

  • packages/internal/types/src/index.ts
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas

Applied to files:

  • packages/internal/types/src/index.ts
  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
📚 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:

  • packages/arkenv/package.json
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to package.json : Configure only built dependencies (native modules) in `pnpm.onlyBuiltDependencies`, including: biomejs/biome, sentry/cli, swc/core, tailwindcss/oxide, vercel/speed-insights, esbuild, and sharp

Applied to files:

  • packages/arkenv/package.json
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to tooling/*/package.json : Tooling in tooling/ directory contains development and testing tools that are not published to npm and excluded from changesets

Applied to files:

  • packages/arkenv/package.json
📚 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:

  • packages/arkenv/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: packages/arkenv should not depend on other workspace packages; packages/vite-plugin depends on arkenv; apps/www may depend on workspace packages

Applied to files:

  • packages/arkenv/package.json
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to {packages,apps,tooling}/**/package.json : When referencing workspace packages in dependencies, use the `workspace:*` protocol instead of version numbers

Applied to files:

  • packages/arkenv/package.json
📚 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/package.json
  • packages/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-22T19:44:11.474Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.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/internal/types/src/infer-type.ts
  • packages/arkenv/src/create-env.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.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types

Applied to files:

  • packages/arkenv/src/create-env.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} : Provide clear, actionable error messages that include the variable name and expected type

Applied to files:

  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')

Applied to files:

  • packages/arkenv/src/create-env.ts
🧬 Code graph analysis (1)
packages/internal/types/src/infer-type.ts (2)
packages/internal/types/src/standard-schema.ts (1)
  • StandardSchemaV1 (52-55)
packages/arkenv/src/type.ts (1)
  • type (7-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: test-e2e (e2e)
  • GitHub Check: test-e2e (a11y)
  • GitHub Check: Deploy-Preview
  • GitHub Check: test-build (latest)
  • GitHub Check: test-build (lts/*)
  • GitHub Check: test-typesafety
🔇 Additional comments (4)
packages/arkenv/package.json (1)

65-74: Size-limit ignore: sanity-check ignoring @repo/scope

Ignoring @repo/scope in size-limit (Line 72) is fine if it’s intentionally excluded from bundle accounting; just confirm it won’t mask accidental bundling/regressions.

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

8-14: Re-exporting standard-schema from the internal barrel looks right

Keeps the typing surface discoverable via the internal entrypoint.

packages/internal/types/src/standard-schema.ts (1)

11-181: Spec typings look consistent with the Standard Schema v1 shape

The ~standard property model + validate/result/issue typing and JSON Schema converter surface seem aligned with the intended interop.

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

3-16: The EnvSchema type exports create a hidden dependency on arktype for typechecking, even when using Standard Schema validators.

Line 15 exports export type EnvSchema<def> = at.validate<def, $>; which depends on arktype's type system. Although arktype is an optional peer dependency, this public type definition requires arktype to be resolvable during TypeScript typechecking—not just at runtime.

This becomes problematic for downstream consumers:

  • vite-plugin and bun-plugin use EnvSchema<T> in their public function signatures
  • Any TypeScript project using these plugins must have arktype installed, even if they only use Standard Schema validators (Zod, Valibot, etc.)
  • This contradicts the library's positioning that arktype is optional

Consider refactoring EnvSchema to not reference arktype's types in its definition, or marking it as internal-only while using EnvSchemaWithType | StandardSchemaV1 in public APIs instead.

⛔ Skipped due to 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 : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
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
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: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across 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 : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
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
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

Comment on lines +54 to +64
"vitest": "catalog:",
"zod": "catalog:"
},
"peerDependencies": {
"arktype": "^2.1.22"
},
"peerDependenciesMeta": {
"arktype": {
"optional": true
}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

ArkType 2.1.28 Standard Schema specification support minimum version

💡 Result:

ArkType 2.1.28 supports Standard Schema version 1 (StandardSchemaV1 / @standard-schema/spec v1.0.0). [1][2]

Sources:
[1] standard-schema spec (StandardSchemaV1 / @standard-schema/spec). [2] ArkType discussion noting Standard Schema acceptance in v2.1.28.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check for changesets in .changeset directory
echo "=== Changesets in .changeset directory ==="
find .changeset -type f -name "*.md" 2>/dev/null | head -20 || echo "No changesets found or directory missing"

# Also check the content of recent changesets to see if arkenv is mentioned
echo ""
echo "=== Checking for arkenv-related changesets ==="
find .changeset -type f -name "*.md" -exec grep -l "arkenv" {} \; 2>/dev/null || echo "No arkenv changesets found"

Repository: yamcodes/arkenv

Length of output: 170


Bump ArkType peerDependency version and add changeset for arkenv

The peerDependencies.arktype version ^2.1.22 is insufficient; ArkType 2.1.28+ is required for Standard Schema support. Update to ^2.1.28.

Additionally, no changeset exists for this publishable package change. Please add a changeset to packages/arkenv/ per the monorepo versioning guidelines.

Required version update
  "peerDependencies": {
-   "arktype": "^2.1.22"
+   "arktype": "^2.1.28"
  },
🤖 Prompt for AI Agents
In @packages/arkenv/package.json around lines 54 - 64, Update the arkenv
package.json to bump the peerDependencies entry "arktype" from "^2.1.22" to
"^2.1.28" (edit the peerDependencies.arktype field) and add a changeset for
packages/arkenv describing this dependency bump (create a new changeset
markdown/yaml file in packages/arkenv/.changeset per the monorepo guidelines
indicating a patch/minor release and the change to arkenv).

Comment on lines +10 to +13
export type InferType<T> =
T extends StandardSchemaV1<infer U>
? U
: never;
: T extends Type<infer U, unknown>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Bug: InferType<StandardSchemaV1> should infer Output, not Input

StandardSchemaV1<Input, Output>: the current infer U captures Input. If a validator’s output differs (coercion/transform), you’ll expose the wrong type.

Proposed fix
 export type InferType<T> =
-	T extends StandardSchemaV1<infer U>
-		? U
+	T extends StandardSchemaV1<infer _Input, infer Output>
+		? Output
 		: T extends Type<infer U, unknown>
 			? distill.Out<U>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type InferType<T> =
T extends StandardSchemaV1<infer U>
? U
: never;
: T extends Type<infer U, unknown>
export type InferType<T> =
T extends StandardSchemaV1<infer _Input, infer Output>
? Output
: T extends Type<infer U, unknown>
🤖 Prompt for AI Agents
In @packages/internal/types/src/infer-type.ts around lines 10 - 13, InferType
currently captures the Input from StandardSchemaV1, causing wrong types when
validators coerce/transform; update the conditional on StandardSchemaV1 in
InferType to infer both generic params and return the Output type (e.g., infer
_In and infer Out then use Out), and keep the existing branch for Type<...>
(returning its inferred output) and a sensible fallback for other T.

Comment on lines +1 to +5
/**
* @see https://github.com/standard-schema/standard-schema/tree/3130ce43fdd848d9ab49dbb0458d04f18459961c/packages/spec
*/

// biome-ignore-all lint/style/useConsistentTypeDefinitions: this file is copied from the standard-schema repo
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

standard-schema repository license requirements attribution

💡 Result:

  • The standard-schema GitHub repository is licensed MIT — you must include the repository's copyright and permission notice (the MIT license text) in all copies or substantial portions of the software. [1]

  • Individual packages in the monorepo may carry their own licenses:

    • @standard-schema/spec (npm) is MIT. [2]
    • The standardschema package on npm is listed as Apache‑2.0. Check each package's package.json / LICENSE file before reuse. [3]

If you plan to redistribute or embed code, include the exact license text and copyright notice from the relevant package(s) (MIT requires the copyright/permission notice; Apache‑2.0 adds its NOTICE/attribution requirements). Check the LICENSE file in each package for the authoritative terms. [1][2][3]


🏁 Script executed:

# Check the full content of the file to see if there's a license header
head -20 packages/internal/types/src/standard-schema.ts

# Also check if there's a LICENSE file in the standard-schema source directory
find . -name "LICENSE*" -path "*/standard-schema*" | head -10

Repository: yamcodes/arkenv

Length of output: 829


🏁 Script executed:

# Search for the actual standard-schema spec license header online context
# Check if there are other similar files in the repo that might show the pattern for license headers
find . -path "*standard*" -name "*.ts" -o -name "*.tsx" | xargs grep -l "MIT\|license\|Copyright" 2>/dev/null | head -5

# Also check if there's any LICENSE file at repo root
ls -la LICENSE* 2>/dev/null || echo "No LICENSE file found at root"

# Check package.json to see declared license
cat package.json | grep -A 2 -B 2 "license" 2>/dev/null

Repository: yamcodes/arkenv

Length of output: 200


🏁 Script executed:

# Check the LICENSE file to understand the project's license
cat LICENSE

# Check the actual standard-schema spec file from their repo to see if they include license headers
# We can search for common patterns in standard-schema files
curl -s "https://raw.githubusercontent.com/standard-schema/standard-schema/main/packages/spec/src/index.ts" | head -20

Repository: yamcodes/arkenv

Length of output: 1963


🏁 Script executed:

# Check if there's a specific LICENSE or NOTICE requirement in the standard-schema spec package
curl -s "https://raw.githubusercontent.com/standard-schema/standard-schema/main/packages/spec/LICENSE" | head -20

# Also check their README for any attribution requirements
curl -s "https://raw.githubusercontent.com/standard-schema/standard-schema/main/packages/spec/README.md" | head -40

Repository: yamcodes/arkenv

Length of output: 2976


🏁 Script executed:

# Let's check how other projects handle this - look for examples of copied code with license attribution
# Check if there are any other files in the repo that copy from external sources
rg "copied from\|based on\|source:\|@see" --type ts --type tsx -B 2 -A 2 | head -50

# Also verify the exact MIT requirement - check if arkenv's LICENSE alone is sufficient
# or if individual files need attribution

Repository: yamcodes/arkenv

Length of output: 86


🏁 Script executed:

# Fix the command - rg doesn't use tsx as a type, use ts
rg "copied from|based on|source:|@see" -t ts -B 2 -A 2 | head -80

Repository: yamcodes/arkenv

Length of output: 5223


Add standard-schema copyright attribution to comply with MIT license

The standard-schema package is MIT licensed (Copyright 2024 Colin McDannell) and requires that copyright and permission notices be included in copies. While the @see reference and "copied from" comment document the source, add a copyright attribution comment at the top of the file to satisfy MIT license requirements:

/**
 * @see https://github.com/standard-schema/standard-schema/tree/3130ce43fdd848d9ab49dbb0458d04f18459961c/packages/spec
 * 
 * Copied from standard-schema (MIT License)
 * Copyright (c) 2024 Colin McDannell
 */
🤖 Prompt for AI Agents
In @packages/internal/types/src/standard-schema.ts around lines 1 - 5, Add the
required MIT copyright attribution block at the top of this copied file by
inserting a comment containing the existing @see line plus the "Copied from
standard-schema (MIT License)" and "Copyright (c) 2024 Colin McDannell" lines
before the biome-ignore-all comment; ensure the new comment preserves the @see
URL and places the copyright and permission notice immediately above the
biome-ignore comment so the file clearly includes the original repository
attribution.

- New playground for string schemas
- Does not require ArkType dependency
- Clarify coerce and arrayFormat JSDoc
- Add new `without-arktype` example
- Demonstrate using ArkEnv with Zod
- Update workspace config and README
- Defer ArkType import until validator is used
- Make ArkType an optional peer dependency
- Refactor keywords to use lazyType from scope
-
@github-actions github-actions bot added docs Improvements or additions to documentation example Issues or Pull Requests concerning at least one ArkEnv example. (Found in the `examples/` directory) labels Jan 12, 2026
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: 3

🤖 Fix all issues with AI agents
In @examples/without-arktype/src/index.ts:
- Line 2: The import "z" from Zod is unused; remove the unused import statement
(the import line that reads import z from "zod") or, if you intend to keep the
commented example, move or reintroduce a real usage of z in active code (e.g.,
reference z in a function or un-comment the example) so the linter stops
flagging it; update the import accordingly to either delete the import line or
ensure z is referenced by a symbol such as z in the current module.

In @packages/internal/scope/src/lazy-type.ts:
- Around line 94-103: The get handler on lazyType eagerly calls
require("arktype") on every static property access, defeating lazy loading;
modify it to defer and cache the require by introducing a local loader (e.g., a
loadArkType function with a cached variable) and call that in get so ArkType is
only required once and only when a static property is actually accessed, or
alternatively return a nested Proxy for prop that lazily resolves members;
update the get handler to use the new loader/cached value instead of calling
require directly each time.
🧹 Nitpick comments (3)
examples/without-arktype/tsconfig.json (1)

35-42: Configuration looks solid.

The strict TypeScript settings are appropriate. Minor observation: jsx: "react-jsx" is included but the example doesn't use React/JSX. This is harmless but could be removed for a cleaner config.

packages/arkenv/src/create-env.ts (2)

121-133: Error message string matching is fragile.

Checking e.message.includes("'arktype'") to detect missing arktype depends on Node.js error message format, which could change.

A more robust approach:

♻️ Suggested improvement
-	} catch (e: unknown) {
-		if (
-			e instanceof Error &&
-			"code" in e &&
-			e.code === "MODULE_NOT_FOUND" &&
-			e.message.includes("'arktype'")
-		) {
+	} catch (e: unknown) {
+		if (
+			e instanceof Error &&
+			"code" in e &&
+			(e as NodeJS.ErrnoException).code === "MODULE_NOT_FOUND"
+		) {
+			// Verify it's specifically arktype that's missing
+			try {
+				require.resolve("arktype");
+			} catch {

Alternatively, keep the current approach but add a comment noting this assumption.


51-74: Duck-typing for ArkType detection could be more explicitly documented.

The function detects ArkType Types by checking the .infer property (which is documented as the standard way to extract TypeScript types from ArkType), followed by a defensive fallback checking multiple properties. While the combination of checks reduces false positives, this detection strategy lacks inline documentation explaining why these specific properties are reliable indicators.

Consider adding a comment explaining that ArkType Type objects expose .infer as metadata and that the fallback checks defend against compiled or variant ArkType schemas. This would clarify the intent and make future maintenance easier if ArkType's internal structure evolves.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da6b3f8 and a8f67ad.

⛔ Files ignored due to path filters (1)
  • examples/without-arktype/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • arkenv.code-workspace
  • examples/README.md
  • examples/without-arktype/package.json
  • examples/without-arktype/src/index.ts
  • examples/without-arktype/tsconfig.json
  • packages/arkenv/src/create-env.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/keywords/src/index.ts
  • packages/internal/keywords/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/types/src/schema.ts
✅ Files skipped from review due to trivial changes (1)
  • examples/without-arktype/package.json
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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) function (or default import as arkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...

Files:

  • packages/internal/keywords/tsdown.config.ts
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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/without-arktype/src/index.ts
**/index.ts

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

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

Files:

  • examples/without-arktype/src/index.ts
  • packages/internal/keywords/src/index.ts
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/tsdown.config.ts
  • packages/arkenv/src/create-env.ts
🧠 Learnings (36)
📓 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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType 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 : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
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
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
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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.
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition
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
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
📚 Learning: 2025-11-24T16:05:35.714Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2025-11-24T16:05:35.714Z
Learning: Use ADDED for new standalone capabilities, MODIFIED for changed behavior with full requirement content, and RENAMED for name-only changes

Applied to files:

  • examples/README.md
📚 Learning: 2025-09-09T17:37:19.650Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 132
File: packages/arkenv/README.md:13-14
Timestamp: 2025-09-09T17:37:19.650Z
Learning: For yamcodes/arkenv project: Runtime support documentation should link to specific examples: Node.js (examples/basic), Bun (examples/with-bun), Vite (examples/with-vite-react-ts).

Applied to files:

  • examples/README.md
  • arkenv.code-workspace
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript

Applied to files:

  • examples/README.md
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/internal/scope/src/lazy-type.ts
  • examples/without-arktype/tsconfig.json
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-22T19:44:11.474Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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:

  • examples/README.md
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • examples/without-arktype/tsconfig.json
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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:

  • examples/README.md
  • packages/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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:

  • examples/README.md
  • packages/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • examples/without-arktype/tsconfig.json
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-11-29T07:55:19.147Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 457
File: examples/basic-js/package.json:15-15
Timestamp: 2025-11-29T07:55:19.147Z
Learning: Examples in the examples/ directory are standalone projects and can use their own package managers (npm, bun, etc.) instead of being required to use pnpm.

Applied to files:

  • examples/README.md
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')

Applied to files:

  • examples/README.md
  • packages/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • packages/arkenv/tsdown.config.ts
  • examples/without-arktype/tsconfig.json
  • packages/arkenv/src/create-env.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:

  • examples/README.md
  • examples/without-arktype/src/index.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")

Applied to files:

  • examples/README.md
  • packages/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • examples/without-arktype/tsconfig.json
  • packages/arkenv/src/create-env.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:

  • examples/README.md
  • packages/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • examples/without-arktype/tsconfig.json
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • examples/without-arktype/tsconfig.json
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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:

  • packages/internal/keywords/tsdown.config.ts
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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:

  • packages/internal/keywords/tsdown.config.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types

Applied to files:

  • packages/internal/keywords/tsdown.config.ts
  • examples/without-arktype/src/index.ts
  • packages/arkenv/tsdown.config.ts
  • packages/arkenv/src/create-env.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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/internal/keywords/tsdown.config.ts
  • arkenv.code-workspace
  • packages/internal/types/src/schema.ts
  • packages/arkenv/tsdown.config.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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/internal/keywords/tsdown.config.ts
  • examples/without-arktype/src/index.ts
  • packages/internal/types/src/schema.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas

Applied to files:

  • examples/without-arktype/src/index.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.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:

  • examples/without-arktype/src/index.ts
  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-05T20:33:10.676Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition

Applied to files:

  • packages/internal/types/src/schema.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: Prefer tree-shakeable exports for better bundling

Applied to files:

  • packages/arkenv/tsdown.config.ts
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: packages/arkenv should not depend on other workspace packages; packages/vite-plugin depends on arkenv; apps/www may depend on workspace packages

Applied to files:

  • packages/arkenv/tsdown.config.ts
📚 Learning: 2025-11-29T08:00:08.044Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/pnpm.mdc:0-0
Timestamp: 2025-11-29T08:00:08.044Z
Learning: Applies to package.json : Configure only built dependencies (native modules) in `pnpm.onlyBuiltDependencies`, including: biomejs/biome, sentry/cli, swc/core, tailwindcss/oxide, vercel/speed-insights, esbuild, and sharp

Applied to files:

  • packages/arkenv/tsdown.config.ts
📚 Learning: 2025-11-24T16:04:11.901Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-11-24T16:04:11.901Z
Learning: Applies to tooling/*/package.json : Tooling in tooling/ directory contains development and testing tools that are not published to npm and excluded from changesets

Applied to files:

  • packages/arkenv/tsdown.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:

  • examples/without-arktype/tsconfig.json
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.test.{ts,tsx} : Create unit tests with `.test.ts` or `.test.tsx` suffix located alongside source files, testing individual functions and components in isolation with mocked dependencies

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 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} : Include examples in JSDoc comments when helpful for public APIs

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 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} : Leverage `const` type parameters for better inference in TypeScript

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 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} : Avoid unnecessary template literals (`noUnusedTemplateLiteral` error)

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 Learning: 2025-11-24T16:04:47.583Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: apps/playgrounds/bun-react/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-11-24T16:04:47.583Z
Learning: Applies to apps/playgrounds/bun-react/**/*.ts : Use `bun --hot` to run TypeScript entry files with hot module reloading enabled

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 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} : Avoid explicit types when TypeScript can infer them (`noInferrableTypes` error)

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 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 JSDoc comments for public APIs

Applied to files:

  • examples/without-arktype/tsconfig.json
📚 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/internal/keywords/src/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} : Provide clear, actionable error messages that include the variable name and expected type

Applied to files:

  • packages/arkenv/src/create-env.ts
🧬 Code graph analysis (3)
packages/internal/types/src/schema.ts (2)
packages/internal/scope/src/index.ts (2)
  • $ (20-49)
  • $ (51-51)
packages/internal/types/src/standard-schema.ts (1)
  • StandardSchemaV1 (52-55)
packages/internal/scope/src/lazy-type.ts (1)
packages/arkenv/src/type.ts (1)
  • type (7-14)
packages/internal/keywords/src/index.ts (1)
packages/arkenv/src/type.ts (1)
  • type (7-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: test-e2e (a11y)
  • GitHub Check: test-e2e (e2e)
  • GitHub Check: Deploy-Preview
🔇 Additional comments (15)
arkenv.code-workspace (1)

132-135: LGTM!

The new workspace folder entry for without-arktype follows the established naming convention and path structure used by other examples. This aligns well with the PR objective to demonstrate ArkEnv usage without ArkType.

examples/README.md (1)

11-11: LGTM!

The new without-arktype example entry is well-documented and follows the existing table format. The description clearly communicates the purpose of demonstrating ArkEnv with Zod instead of ArkType.

packages/internal/keywords/tsdown.config.ts (1)

10-10: LGTM!

Externalizing arktype is the correct approach for making it an optional peer dependency. This ensures the bundle doesn't include ArkType code that would fail at runtime when ArkType isn't installed.

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

1-1: Good refactor for lazy loading.

Switching to lazyType from @repo/scope enables deferred ArkType loading, supporting the PR objective of making ArkType optional.


12-31: Clean extraction of transformer functions.

Extracting maybeNumberFn as a standalone function improves testability and enables the lazy-loading pattern via .pipe(). The JSDoc appropriately marks it as internal use.


42-57: Consistent pattern applied to boolean coercion.

Same clean extraction pattern for maybeBooleanFn. The implementation is correct and maintains backward compatibility.


78-99: JSON coercion follows the established pattern.

maybeJsonFn extraction is consistent with the other transformers. The defensive checks (type guard, trim, prefix check) are preserved correctly.

packages/internal/scope/src/lazy-type.ts (2)

57-73: Good error handling for missing ArkType.

The error message is clear and actionable, guiding users to either install ArkType or use Standard Schema validators. The specific check for MODULE_NOT_FOUND with 'arktype' in the message ensures other errors propagate correctly.


23-46: Lazy proxy pattern is well-implemented.

The proxy correctly defers ArkType loading by:

  • Accumulating .pipe() morphs without realization
  • Only realizing on actual property access or invocation

The apply handler properly realizes and invokes the type as a validator.

packages/arkenv/tsdown.config.ts (1)

7-12: Bundling configuration correctly handles optional ArkType.

The configuration properly:

  • Externalizes arktype so it's not bundled (optional peer dep)
  • Forces bundling of workspace packages via noExternal
  • Resolves type declarations for all internal packages

This ensures the published package works both with and without ArkType installed.

packages/internal/types/src/schema.ts (2)

1-9: LGTM!

The type-only imports ensure no runtime ArkType dependency at this layer, aligning with the PR goal of making ArkType optional. The SchemaShape type and its JSDoc are clear and accurate.


11-16: LGTM!

The union type correctly enables both ArkType and Standard Schema validators while leveraging ArkType's scoped type system ($). This supports the PR objective of allowing mixed validator usage.

packages/arkenv/src/create-env.ts (3)

1-14: LGTM!

The createRequire approach is the correct pattern for enabling dynamic require() in ESM modules, supporting the lazy ArkType loading strategy.


17-49: LGTM!

The ArkEnvConfig type is well-documented with clear JSDoc comments. The note about coercion being ArkType-specific aligns with the PR objective to keep coercion ArkType-only.


145-177: LGTM!

The createEnv implementation correctly:

  • Provides clear overloads for both schema shapes and pre-compiled types
  • Enforces the guardrail against top-level Standard Schema (per PR objectives)
  • Uses ArkEnvError for validation failures (per coding guidelines)
  • Provides an actionable error message guiding users to the correct usage pattern

- Implement validation for standard schema definitions
- Allow `createEnv` to use standard schemas directly
- Lazily load Ark
- Move arktype keywords to internal scope package
- Lazily load arktype keywords within arkenv
- Update arktype
- Extract ArkType module loading logic
- Cache ArkType module for single load
- Improve performance by avoiding re-requires
- Consolidate module not found error handling
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: 2

🤖 Fix all issues with AI agents
In @packages/arkenv/src/create-env.ts:
- Around line 120-132: In the catch (e: unknown) block remove the unreachable
branch that checks e instanceof Error && "code" in e && e.code ===
"MODULE_NOT_FOUND" && e.message.includes("'arktype'") and the subsequent throw
of a new Error; instead simply rethrow the caught error (throw e) for all cases
so the existing upstream error messages from scope/coerce are preserved.
🧹 Nitpick comments (3)
packages/internal/scope/src/keywords.ts (1)

24-28: Consider trimming input for robustness.

The function only matches exact "true"/"false" strings. Environment variables with accidental whitespace (e.g., "true ") won't be coerced. This is likely intentional, but trimming would add resilience.

🔧 Optional: Add trimming for whitespace tolerance
 export const maybeBooleanFn = (s: unknown) => {
-	if (s === "true") return true;
-	if (s === "false") return false;
+	if (typeof s !== "string") return s;
+	const trimmed = s.trim();
+	if (trimmed === "true") return true;
+	if (trimmed === "false") return false;
 	return s;
 };
packages/arkenv/src/create-env.ts (2)

1-13: Unused require variable is dead code.

createRequire is imported and require is assigned at line 13, but this variable is never used in the file. The coerce utility has its own internal require("arktype") call.

🧹 Remove unused import and variable
-import { createRequire } from "node:module";
 import { $ } from "@repo/scope";
 import type {
 	EnvSchemaWithType,
 	InferType,
 	SchemaShape,
 	StandardSchemaV1,
 } from "@repo/types";
 import type { type as at, Type } from "arktype";
 import { ArkEnvError, type EnvIssue } from "./errors";
 import { coerce } from "./utils/coerce";
-
-const require = createRequire(import.meta.url);

135-187: LGTM with minor suggestion.

The Standard Schema validation path is well-structured with proper error aggregation. The async validation guard at lines 162-168 is appropriate since environment validation should be synchronous.

Consider enhancing the error message to be more actionable for users who encounter this:

💡 Optional: More actionable async error message
 if (validationResult instanceof Promise) {
     issues.push({
         path: [key],
-        message: `Async validation is not supported for ${key}`,
+        message: `Async validation is not supported for ${key}. Use a synchronous validator or ensure .validate() returns synchronously.`,
     });
     continue;
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b201bcc and c59a4af.

⛔ Files ignored due to path filters (1)
  • examples/without-arktype/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • examples/without-arktype/package.json
  • examples/without-arktype/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/keywords/src/index.ts
  • packages/internal/scope/src/index.ts
  • packages/internal/scope/src/keywords.ts
  • packages/internal/scope/src/lazy-type.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • examples/without-arktype/package.json
  • examples/without-arktype/src/index.ts
  • packages/internal/scope/src/lazy-type.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) function (or default import as arkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...

Files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/keywords.ts
  • packages/internal/scope/src/index.ts
**/index.ts

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

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

Files:

  • packages/internal/keywords/src/index.ts
  • packages/internal/scope/src/index.ts
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.ts
🧠 Learnings (19)
📓 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
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
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType 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 : Leverage ArkType's type inference for TypeScript types instead of manual type definitions
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition
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
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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.
📚 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:

  • packages/internal/keywords/src/index.ts
📚 Learning: 2025-12-22T19:44:11.474Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/keywords.ts
  • packages/internal/scope/src/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/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/keywords.ts
  • packages/internal/scope/src/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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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 : Use the scoped `$` type system for custom types defined in `scope.ts`

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/keywords.ts
  • packages/internal/scope/src/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 : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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 : Use ArkType's `type()` function to define schemas in environment variable definitions

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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 type inference for TypeScript types instead of manual type definitions

Applied to files:

  • packages/internal/keywords/src/index.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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 : 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.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript

Applied to files:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition

Applied to files:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/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 `ArkEnvError` for environment variable validation errors

Applied to files:

  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types

Applied to files:

  • packages/arkenv/src/create-env.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} : Provide clear, actionable error messages that include the variable name and expected type

Applied to files:

  • packages/arkenv/src/create-env.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')

Applied to files:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/index.ts
🧬 Code graph analysis (3)
packages/arkenv/src/create-env.ts (8)
packages/internal/types/src/standard-schema.ts (1)
  • StandardSchemaV1 (52-55)
packages/vite-plugin/src/index.ts (1)
  • config (54-88)
packages/arkenv/src/errors.ts (2)
  • EnvIssue (7-10)
  • ArkEnvError (54-62)
packages/internal/scope/src/index.ts (2)
  • $ (20-51)
  • $ (53-53)
packages/arkenv/src/utils/coerce.ts (1)
  • coerce (296-344)
packages/internal/types/src/schema.ts (1)
  • SchemaShape (9-9)
packages/arkenv/src/index.ts (2)
  • createEnv (13-13)
  • ArkEnvError (14-14)
packages/internal/types/src/infer-type.ts (1)
  • InferType (10-27)
packages/internal/scope/src/keywords.ts (1)
packages/arkenv/src/type.ts (1)
  • type (7-14)
packages/internal/scope/src/index.ts (2)
packages/internal/scope/src/scope-def.ts (1)
  • ArkEnvScope (19-19)
packages/arkenv/src/type.ts (1)
  • type (7-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: test-e2e (a11y)
  • GitHub Check: test-e2e (e2e)
  • GitHub Check: Deploy-Preview
  • GitHub Check: test-build (lts/*)
  • GitHub Check: test-build (latest)
🔇 Additional comments (12)
packages/internal/keywords/src/index.ts (1)

1-1: LGTM! Clean barrel export consolidation.

This refactor correctly centralizes keyword implementations in @repo/scope, supporting the PR objective of making ArkType optional through lazy loading. Based on coding guidelines, this follows the barrel export pattern for package entry points.

packages/internal/scope/src/keywords.ts (3)

6-14: LGTM! Correct loose number coercion logic.

The function properly handles edge cases: preserves non-strings, handles empty strings, explicit "NaN" string conversion, and correctly uses Number.isNaN to detect failed conversions.


38-47: LGTM! Safe JSON parsing with appropriate scope.

The function correctly limits parsing to object/array JSON (starting with { or [), which is appropriate for environment variables containing structured data. The try/catch ensures graceful fallback on malformed JSON.


54-62: LGTM! Well-defined port and host validators.

The explicit ArkType syntax correctly constrains port to valid TCP/UDP range and host to IP addresses or localhost. This aligns with the project's approach of using ArkType's type system for educational value. Based on learnings, this showcases ArkType's capabilities.

packages/internal/scope/src/index.ts (3)

1-5: LGTM! Correct type-only import pattern for optional dependency.

Using import type ensures no runtime dependency on arktype at module load time, enabling the lazy loading pattern that makes ArkType optional.


53-53: LGTM! Clean type alias export.

The type alias $ provides access to the inferred types from the scope, enabling type inference for consumers without requiring runtime access to ArkType. Based on learnings, this leverages ArkType's type inference as recommended.


20-51: The Proxy implementation is complete for current usage patterns.

The get trap is sufficient. Searches across the codebase confirm that $ is only accessed via property access patterns (e.g., $.type, $.module). No code attempts to inspect object properties, iterate over keys, or invoke $ directly, so additional traps are unnecessary.

packages/arkenv/src/create-env.ts (5)

17-49: LGTM!

The ArkEnvConfig type is well-documented with clear JSDoc comments explaining each option, defaults, and the ArkType-specific coercion note.


51-68: LGTM!

The duck-typing approach for detecting ArkType schemas is appropriate here since ArkType cannot be imported directly. The null/undefined guards are correctly placed.


70-75: LGTM!

Simple detection helper. The fact that both isStandard and isArkCompiled can be true for ArkType types (since ArkType 2.1.28+ implements Standard Schema per learnings) is correctly handled in the routing logic downstream.


189-217: LGTM!

The routing logic correctly handles the fact that ArkType 2.1.28+ implements Standard Schema by prioritizing ArkType detection. The comments at lines 209-210 clearly explain why this check is necessary.


228-265: LGTM!

The createEnv implementation correctly:

  • Provides overloads for both SchemaShape and EnvSchemaWithType
  • Blocks top-level Standard Schema with a clear, actionable error message (lines 247-250)
  • Routes validation to the appropriate path based on validator types
  • Throws ArkEnvError on validation failure as per coding guidelines

The guardrail at lines 246-251 aligns with the PR objective to reject arkenv(z.object(...)) while supporting Standard Schema validators inside mappings.

- Implement lazy loading for ArkType
- Introduce `arktypeLoader` and `lazyType` proxy
- Refactor core `createEnv
- Change ArkEnvConfig to type alias
- Use const for schema variable
- Reorder exports for consistency
- Introduce onUndeclaredKey config for schema behavior
- Add arrayFormat option for parsing array strings
- Refactor coercion
- Add maintainer notes to key internal functions
- Refine ArkType lazy proxy type assertion
- Correct internal import path for keywords
- Enhance `createEnv` return type with `InferType<T>`
- Broaden `SchemaShape` to allow more schema definitions
-
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 (1)
packages/arkenv/src/create-env.ts (1)

94-100: Consider documenting default undeclared key behavior.

The default onUndeclaredKey: "delete" for non-compiled types (raw mappings) silently strips extra environment variables. While this is sensible for security, it could surprise users who expect unknown keys to pass through.

Consider adding a JSDoc note or console warning for this behavior.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c59a4af and da5ca1f.

📒 Files selected for processing (11)
  • .gitignore
  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/arkenv/src/index.ts
  • packages/arkenv/src/type.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/bun-plugin/src/index.ts
  • packages/internal/scope/src/index.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/scope/src/scope-def.ts
  • packages/vite-plugin/src/index.ts
💤 Files with no reviewable changes (1)
  • packages/arkenv/src/index.ts
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/internal/scope/src/scope-def.ts
  • packages/bun-plugin/src/index.ts
🧰 Additional context used
📓 Path-based instructions (6)
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/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/arkenv/src/type.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) function (or default import as arkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...

Files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.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}: 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)

Create unit tests with .test.ts or .test.tsx suffix located alongside source files, testing individual functions and components in isolation with mocked dependencies

Files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
**/*.integration.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/test-patterns.mdc)

**/*.integration.test.{ts,tsx}: Test how multiple units (components, hooks, functions) work together without mocking their interactions in integration tests
Integration tests should focus on component and hook interactions, function composition and data flow, real dependencies between units, and state synchronization across boundaries
Integration tests should execute between 100ms - 2000ms per test
Use *.integration.test.ts suffix to distinguish integration tests from unit tests

Create integration tests with .integration.test.ts or .integration.test.tsx suffix, testing how multiple units work together without mocking their interactions (except external APIs)

Files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
**/*.{test,integration.test}.{ts,tsx}

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

**/*.{test,integration.test}.{ts,tsx}: Use Vitest's describe/it structure for all test files
Test both success and failure cases in unit and integration tests
Mock process.env in unit tests to test different environment variable scenarios

Files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
**/index.ts

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

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

Files:

  • packages/internal/scope/src/index.ts
  • packages/vite-plugin/src/index.ts
🧠 Learnings (25)
📓 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
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
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
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
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
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 498
File: apps/playgrounds/node/index.ts:2-2
Timestamp: 2025-12-05T20:33:10.676Z
Learning: ArkType 2.1.28+ supports Standard Schema specification, allowing interoperability with other Standard Schema-compliant validation libraries (e.g., Zod, Valibot) within the same schema definition
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
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types
📚 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/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/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:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-22T19:44:11.474Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 596
File: examples/basic/index.ts:4-5
Timestamp: 2025-12-22T19:44:11.474Z
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/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/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 : Use union types for enums in ArkType schemas (e.g., `"'dev' | 'prod'"`) instead of separate enum definitions

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.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 **/*.integration.test.{ts,tsx} : Test how multiple units (components, hooks, functions) work together without mocking their interactions in integration tests

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.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 : Convert ArkType validation errors to `ArkEnvError` for user-friendly error messages that include variable name and expected type

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.integration.test.{ts,tsx} : Create integration tests with `.integration.test.ts` or `.integration.test.tsx` suffix, testing how multiple units work together without mocking their interactions (except external APIs)

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{test,integration.test}.{ts,tsx} : Mock `process.env` in unit tests to test different environment variable scenarios

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.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: ArkType validates environment variables at runtime and TypeScript types are inferred from the schema definition

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/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 : Use ArkType's `type()` function to define schemas in environment variable definitions

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/arkenv/src/type.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/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 `ArkEnvError` for environment variable validation errors

Applied to files:

  • packages/arkenv/src/arktype-optional.integration.test.ts
  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/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 type inference for TypeScript types instead of manual type definitions

Applied to files:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/index.ts
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use ArkEnvError for environment variable errors instead of generic Error types

Applied to files:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.ts
  • packages/vite-plugin/src/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/scope.ts : Define custom types in `scope.ts` using ArkType's scoped type system for reusability across schemas

Applied to files:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.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} : Provide clear, actionable error messages that include the variable name and expected type

Applied to files:

  • packages/arkenv/src/create-env.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:

  • packages/arkenv/src/create-env.ts
  • packages/internal/scope/src/lazy-type.ts
  • packages/arkenv/src/type.ts
  • packages/internal/scope/src/index.ts
  • packages/arkenv/src/utils/coerce.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} : Avoid unnecessary template literals (`noUnusedTemplateLiteral` error)

Applied to files:

  • packages/arkenv/src/create-env.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:

  • packages/internal/scope/src/index.ts
📚 Learning: 2025-12-26T19:27:11.710Z
Learnt from: danciudev
Repo: yamcodes/arkenv PR: 614
File: packages/vite-plugin/src/index.test.ts:641-654
Timestamp: 2025-12-26T19:27:11.710Z
Learning: In packages/vite-plugin/src/**/*.test.ts: The test suite uses `env.test` files (without leading dot) as test fixtures that are manually read by the `readTestConfig` helper function and stubbed into process.env with `vi.stubEnv`, not as files to be read by Vite's loadEnv during tests.

Applied to files:

  • packages/vite-plugin/src/index.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 packages/vite-plugin/src/**/*.test.ts : Use fixture-based testing pattern for Vite plugin tests by placing fixtures in __fixtures__ directory

Applied to files:

  • packages/vite-plugin/src/index.ts
🧬 Code graph analysis (6)
packages/arkenv/src/arktype-optional.integration.test.ts (2)
packages/arkenv/src/create-env.ts (1)
  • createEnv (216-251)
packages/arkenv/src/type.ts (1)
  • type (7-27)
packages/internal/scope/src/lazy-type.ts (2)
packages/internal/scope/src/index.ts (2)
  • arktypeLoader (5-5)
  • lazyType (5-5)
packages/arkenv/src/type.ts (1)
  • type (7-27)
packages/arkenv/src/type.ts (1)
packages/internal/scope/src/index.ts (2)
  • $ (33-54)
  • $ (56-56)
packages/internal/scope/src/index.ts (3)
packages/internal/scope/src/lazy-type.ts (1)
  • arktypeLoader (50-50)
packages/internal/scope/src/scope-def.ts (1)
  • ArkEnvScope (19-19)
packages/arkenv/src/type.ts (1)
  • type (7-27)
packages/arkenv/src/utils/coerce.ts (4)
packages/internal/scope/src/keywords.ts (3)
  • maybeJsonFn (38-47)
  • maybeNumberFn (6-14)
  • maybeBooleanFn (24-28)
packages/arkenv/src/type.ts (1)
  • type (7-27)
packages/internal/scope/src/lazy-type.ts (1)
  • arktypeLoader (50-50)
packages/internal/scope/src/index.ts (1)
  • arktypeLoader (5-5)
packages/vite-plugin/src/index.ts (2)
packages/internal/types/src/schema.ts (2)
  • SchemaShape (9-9)
  • EnvSchemaWithType (14-16)
packages/arkenv/src/create-env.ts (1)
  • createEnv (216-251)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: test-e2e (a11y)
  • GitHub Check: test-e2e (e2e)
  • GitHub Check: size-limit
  • GitHub Check: test-typesafety
  • GitHub Check: test-build (lts/*)
  • GitHub Check: test-build (latest)
  • GitHub Check: Deploy-Preview
🔇 Additional comments (18)
packages/arkenv/src/type.ts (2)

3-27: LGTM! Well-designed lazy proxy for ArkType detection.

The Proxy implementation correctly:

  1. Returns true for isArktype property access to enable runtime detection.
  2. Forwards all other property access to $.type via Reflect.get.
  3. Handles thisArg binding correctly in the apply trap.
  4. Marks returned objects/functions with isArktype for downstream detection in create-env.ts.

This aligns with the PR objective of making ArkType optional while preserving detection capabilities.


29-29: Type-only export provides DX compatibility.

The at type alias re-export enables consumers to reference ArkType's type system without runtime dependency.

packages/internal/scope/src/lazy-type.ts (2)

114-124: LGTM! Clean public API for lazy type loading.

The lazyType export correctly:

  1. Returns a lazy proxy when invoked with a definition.
  2. Forwards property access to the loaded ArkType (triggering load on first access).
  3. Is typed as typeof ArkType for full DX compatibility.

The maintainer note about resetScope() requirement in tests is helpful.


30-40: The error handling logic is correct and intentionally specific.

The catch block at lines 31-36 uses e.message.includes("'arktype'") as a deliberate filter, not an oversight. If arktype itself is missing, the MODULE_NOT_FOUND error message will include 'arktype' and gets wrapped with the user-friendly MISSING_ERROR. If a transitive dependency of arktype is missing, the error message will reference that dependency name (not 'arktype'), so it correctly gets re-thrown as-is. This distinction prevents masking real errors from missing transitive dependencies while providing helpful feedback when arktype is actually missing.

Likely an incorrect or invalid review comment.

packages/internal/scope/src/index.ts (2)

17-20: LGTM! Test-friendly reset mechanism.

The resetScope() function properly clears both the scope cache and the loader state, enabling clean test isolation. This addresses the maintainer note in lazy-type.ts about calling reset in beforeEach/afterEach.


33-54: LGTM! Lazy-loaded ArkEnv scope.

The Proxy pattern correctly:

  1. Defers ArkType loading until first property access.
  2. Caches the realized scope for subsequent accesses.
  3. Extends ArkType's keywords with ArkEnv-specific types (string.host, number.port).

The as any cast on line 54 is necessary given TypeScript's limitations with Proxy typing.

packages/arkenv/src/utils/coerce.ts (4)

5-17: LGTM! Clear configuration type and sensible defaults.

The CoerceConfig type provides fine-grained control over coercion behavior, and the defaults enable all coercion types with comma-separated array format, which aligns with common environment variable conventions.


331-353: LGTM! Single value coercion with Standard Schema bypass.

The coerceValue function correctly:

  1. Returns non-string values unchanged.
  2. Bypasses coercion for Standard Schema validators (they handle their own coercion).
  3. Falls back to simple coercion when JSON schema is unavailable.

This aligns with the PR objective of keeping coercion ArkType-specific.


158-176: Verify array format behavior with mixed JSON/comma content.

When arrayFormat is "comma" but the string starts with [, the code attempts JSON parsing first (line 164-165). If parsing fails (e.g., "[invalid"), it falls through to comma splitting, which would produce ["[invalid"]. This may be intentional but could be surprising.


117-134: Edge case: Empty string key with dot-notation handling.

If a key is an empty string "", parts would be [""] after split, making parts[parts.length - 1] equal to "". While this is an unlikely edge case, the code would set current[""] = value, which may cause unexpected behavior.

🔧 Optional defensive guard
 } else if (
 	typeof key === "string" &&
 	key.includes(".") &&
+	key !== "" &&
 	config.objects
 ) {

Likely an incorrect or invalid review comment.

packages/arkenv/src/create-env.ts (3)

48-71: LGTM! Robust ArkType detection with multiple fallback heuristics.

The detection logic correctly identifies ArkType validators via:

  1. Explicit isArktype marker (from the lazy proxy).
  2. ArkType 2.0 arkKind markers.
  3. Internal ArkType methods (traverseApply, traverseAllows, json).

The maintainer note appropriately warns against treating this as public contract.


149-181: LGTM! Clean Standard Schema validation with proper error aggregation.

The function correctly:

  1. Validates each key independently against its validator.
  2. Rejects async validation with a clear error message.
  3. Aggregates issues with proper path augmentation.
  4. Returns either a success value map or aggregated issues.

This aligns with the PR objective of supporting Standard Schema validators directly.


232-236: LGTM! Clear rejection of top-level Standard Schema.

The error message is actionable and guides users toward the correct usage pattern. This aligns with the PR objective to preserve arkenv({ ... }) as the entry point with object mappings.

packages/arkenv/src/arktype-optional.integration.test.ts (3)

4-22: LGTM! Thorough cleanup ensures test isolation.

The afterEach hook correctly:

  1. Clears Vitest mocks.
  2. Resets the ArkType loader via global Symbol.
  3. Resets the scope cache via global Symbol.
  4. Cleans up the ARKENV_FORCE_MISSING env var.

This enables reliable testing of the optional ArkType scenarios.


54-101: LGTM! Comprehensive Standard Schema fallback testing.

The tests correctly verify:

  1. Zod validators work when ArkType is unavailable (lines 55-75).
  2. Error messages don't leak ArkType-specific terminology (lines 77-101).

This aligns with the PR objective of supporting Zod-only users.


104-125: LGTM! Clear error messaging when ArkType is required but missing.

The test verifies that using ArkType string DSL without ArkType installed produces an actionable error message. The unique definition ("number.port > 0") helps avoid caching issues.

packages/vite-plugin/src/index.ts (2)

33-36: LGTM! Updated overloads align with createEnv changes.

The new generic overload arkenv<const T extends SchemaShape>(options: T): Plugin correctly supports the updated type system where raw object mappings are passed directly.


49-54: Type assertion workaround is documented.

The options as any cast addresses the TypeScript depth issue noted in the TODO. While not ideal, the comment explains the rationale, and the functionality is tested via the plugin test suite.

Comment on lines +65 to +82
function createLazyProxy(state: LazyTypeProxy): any {
return new Proxy(() => {}, {
get(_, prop) {
if (prop === "isArktype") return true;
if (prop === "pipe") {
return (morph: (value: unknown) => unknown) => {
state.morphs.push(morph);
return createLazyProxy(state);
};
}
return realizeType(state)[prop];
},
apply(_, __, args) {
const realized = realizeType(state);
return realized(...args);
},
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential issue: pipe() calls after realization are silently ignored.

Once realizeType is called (via property access or invocation), state._realized is cached, and subsequent pipe() calls will add morphs to state.morphs but they won't be applied since realizeType returns the cached result.

This could lead to subtle bugs if consumers expect chained pipe() calls to work after accessing any property on the lazy proxy.

🔧 Suggested fix

Consider either:

  1. Throwing an error if pipe() is called after realization:
 if (prop === "pipe") {
 	return (morph: (value: unknown) => unknown) => {
+		if (state._realized) {
+			throw new Error("Cannot pipe after the lazy type has been realized");
+		}
 		state.morphs.push(morph);
 		return createLazyProxy(state);
 	};
 }
  1. Or documenting this limitation in the maintainer note.

@yamcodes yamcodes closed this Jan 13, 2026
@yamcodes yamcodes deleted the optional-arkenv branch January 13, 2026 18:03
yamcodes added a commit that referenced this pull request Jan 13, 2026
Closes #705, continuation of #704

## TODO

- [x] 1. Manual review (ignoring type widening)
- [ ] 2. Add changeset (skippable)
- [ ] 3. Address size limits or raise them (skippable)
- [ ] 4. Clarify top-level Standard Schema support model (doc note)
(skippable)
- [ ] 5. Document ArkType optionality boundaries and expectations (doc
note) (skippable)
- [x] 6. Merge

Anything skipped should be brought over to the
[`optional-arkenv`](https://github.com/yamcodes/arkenv/tree/optional-arkenv)
branch's PR TODO.

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

* **New Features**
* Support for Standard Schema validators (e.g., Zod) alongside ArkType;
ArkType can be lazy-loaded/optional.
  * New built-in port and host validators.

* **Examples**
  * Added a "without-arktype" example showing Zod-based env validation.

* **Improvements**
  * Simplified createEnv API and nested coercion options under coerce.
  * Improved error formatting for validation issues.

* **Chores**
* Removed legacy internal keywords package and related utilities;
tests/configs updated.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[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/vite-plugin Issues or Pull Requests involving the Vite plugin for ArkEnv 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make ArkType optional and support Standard Schema directly (core)

1 participant