Skip to content

feat: add official TanStack CLI add-on for ArkEnv - #1811

Open
yamcodes wants to merge 7 commits into
v1from
add_arkenv_tanstack_addon
Open

feat: add official TanStack CLI add-on for ArkEnv#1811
yamcodes wants to merge 7 commits into
v1from
add_arkenv_tanstack_addon

Conversation

@yamcodes

@yamcodes yamcodes commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Important

Blocked by #1812: To ensure the canonical URL https://arkenv.js.org/tanstack/info.json resolves in the documentation quickstart commands, #1812 must be merged into dev and synced to main (gh workflow run sync-main.yml --ref dev) so production proxies /tanstack/* to https://arkenv-v1.vercel.app/tanstack/*.

Summary

This PR adds the official TanStack CLI add-on for ArkEnv (@arkenv/tanstack-addon), enabling developers to scaffold typesafe environment variable validation in TanStack Start applications via tanstack create my-app --add-ons https://arkenv.js.org/tanstack/info.json or tanstack add ....

Key Features

  • Package Scaffolding (packages/tanstack-addon):
    • Authoring metadata in .add-on/info.json prompting for validator choice:
      • ArkType (default, via @arkenv/core and arktype)
      • Zod (via @arkenv/standard and zod)
      • Valibot (via @arkenv/standard and valibot)
    • Dynamic package.json.ejs injecting validator runtime dependencies and @arkenv/vite-plugin devDependencies aligned with RELEASE_CONFIG.
    • src/env.ts.ejs template with fallback matching for remote add-on option IDs (addOnOption[url] vs addOnOption['arkenv']).
    • Interactive demo route at src/routes/demo/arkenv.tsx showcasing server-only variable protection in createServerFn, inlined public VITE_ variables on the client, and an interactive leak button triggering ArkEnv's throwing getter boundary error.
    • .env.example pre-populated with declared schema keys.
  • Standalone Build & Distribution (scripts/build.ts):
    • Compiles asset templates into standalone schema-valid JSON bundles (dist/info.json and dist/add-on.json) conforming to @tanstack/create's AddOnCompiledSchema.
    • Automatically mirrors compiled outputs and raw assets to apps/www/public/tanstack/ for CDN distribution at https://arkenv.js.org/tanstack/info.json.
  • Documentation & Changeset:
    • Updated apps/www/content/docs/frameworks/tanstack-start.mdx with quickstart instructions using TanStack CLI.
    • Added changeset .changeset/tanstack-addon.md with a minor bump for @arkenv/tanstack-addon.

Verification

  • Automated Tests:
    • packages/tanstack-addon/tests/compile.test.ts: validated bundle against @tanstack/create's AddOnCompiledSchema.
    • packages/tanstack-addon/tests/templates.test.ts: 10 test cases verifying EJS rendering for ArkType, Zod, Valibot, and URL-based option keys.
    • apps/www/lib/package-install-fences.test.ts: verified remark-npm package-install compliance.
  • Workspace Checks:
    • pnpm biome check packages/tanstack-addon: clean (0 errors, 0 warnings).
    • pnpm run check:mdx: 132 files checked, 0 errors.
    • pnpm manypkg check: workspaces valid.
    • pnpm typecheck: 32/32 Turbo tasks passed.
    • pnpm test -- --run: 161/161 test files passed (1,359 tests passed).
    • pnpm --filter www build: Next.js production build succeeded (108 static pages generated).

@changeset-bot

changeset-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 09a270b

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

This PR includes changesets to release 1 package
Name Type
@arkenv/tanstack-addon Minor

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

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

@github-actions github-actions Bot added docs Adds or changes documentation, or acts as documentation in and of itself www Improvements or additions to arkenv.js.org tests This issue or PR is about adding, removing or changing tests labels Sep 5, 2026
@pkg-pr-new

pkg-pr-new Bot commented Sep 5, 2026

Copy link
Copy Markdown

Open in StackBlitz

@arkenv/agent-plugin

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/agent-plugin@1811

arkenv

npm i https://pkg.pr.new/yamcodes/arkenv@1811

@arkenv/build

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/build@1811

@arkenv/bun-plugin

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

@arkenv/core

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/core@1811

@arkenv/fumadocs-ui

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

@arkenv/nextjs

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

@arkenv/nuxt

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/nuxt@1811

@arkenv/rsbuild-plugin

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/rsbuild-plugin@1811

@arkenv/standard

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/standard@1811

@arkenv/tanstack-addon

npm i https://pkg.pr.new/yamcodes/arkenv/@arkenv/tanstack-addon@1811

@arkenv/vite-plugin

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

commit: 09a270b

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Two things need attention before merge. First, the docs and changeset advertise an interactive "choose your validation engine" prompt, but tanstack create --add-ons <url> runs non-interactively in the CLI versions this ships against (@tanstack/create@0.70.0 / @tanstack/cli@0.71.0), so every scaffold silently gets ArkType and the Zod/Valibot branches are unreachable through any documented path. Second, the headline URL https://arkenv.js.org/tanstack/info.json 404s today (verified) — arkenv.js.org serves main/v0 and the next.config.ts proxy rewrite this PR's own design doc picked (B1a) is not part of this PR, so the documented command won't work until a separate main change lands.

Reviewed changes

  • Add-on authoring package (packages/tanstack-addon): .add-on/info.json metadata with a validator select (arktype/zod/valibot), package.json.ejs, src/env.ts.ejs, a demo route template, and .env.example.
  • Build & distribution (scripts/build.ts): compiles raw assets into a schema-valid AddOnCompiledSchema bundle (dist/info.json + dist/add-on.json) and mirrors it plus raw assets into apps/www/public/tanstack/ for CDN hosting.
  • Tests: compile.test.ts validates the bundle against AddOnCompiledSchema; templates.test.ts exercises EJS rendering across all three validators and URL-keyed option IDs; package-install-fences passes for the new MDX fences.
  • Docs: tanstack-start.mdx quickstart with npx @tanstack/cli create my-app --add-ons … and a tanstack add callout; apps/www/tsconfig.json excludes public.
  • Design note + changeset: docs/design/tanstack-cli-addon.md (living note, stack A1 + B1a + C2 + D2 + E1) and a minor-bump changeset.

I verified the add-on's generated code against the real package contracts: @arkenv/vite-plugin's default export is the plugin (arkenv() is valid; arkenvVitePlugin exists as a named alias), number.port is a real ArkEnv keyword, @arkenv/standard's root arkenv works with Zod zero-config and coerces the Valibot branch via the inline v.transform(Number), and the EJS addOnOption contract (variable name, URL keying for remote add-ons) matches what @tanstack/create@0.70.0 passes at render time.

⚠️ The advertised https://arkenv.js.org/tanstack/info.json 404s at merge time

The docs, changeset, and README all make https://arkenv.js.org/tanstack/info.json the install URL, but this PR only ships the bundle to the v1 deployment (apps/www/public/tanstack/). arkenv.js.org currently serves main (v0), and there is no next.config.ts rewrite (/tanstack/:path* → v1 preview) — the design doc's own chosen B1a — anywhere in this diff. I fetched the URL live and got a 404; until that rewrite lands on main (or the docs point at https://arkenv-v1.vercel.app/tanstack/info.json per the B1b fallback), anyone following the documented command gets a 404.

Technical details
# arkenv.js.org/tanstack/info.json is dead on merge

## Affected sites
- apps/www/content/docs/frameworks/tanstack-start.mdx:31, 51 — both `package-install` fences hardcode `https://arkenv.js.org/tanstack/info.json`
- .changeset/tanstack-addon.md:18, 24 — same URL in the release notes
- packages/tanstack-addon/README.md:10, 16 — same URL in package docs
- apps/www/next.config.ts — no `/tanstack/:path*` rewrite exists (this PR does not touch it)

## Required outcome
- The command users are told to run must resolve on the day the docs/changeset go live. Either (a) land the B1a proxy rewrite on `main` (3-line Next.js rewrite to the v1 preview) so the stable URL works from day one, or (b) advertise the currently-live v1 host (`arkenv-v1.vercel.app/tanstack/info.json`) for the alpha phase and migrate at GA — exactly the B1b fallback the design doc already scopes.
- Confirm the sequencing before merge; a 404 in the flagship command is a bad first-run experience for a brand-new feature.

⚠️ The validator prompt the docs promise doesn't fire — the multi-validator feature is unreachable

packages/tanstack-addon/.add-on/info.json's validator select is the C2 centerpiece ("Multi-validator selection during scaffolding"), and tanstack-start.mdx tells users "The CLI prompts you to choose your preferred validation engine". Against the pinned @tanstack/create@0.70.0 (and current @tanstack/cli@0.71.0), this does not happen: passing --add-ons <url> short-circuits the interactive flow, and add-on option values come from defaults only (populateAddOnOptionsDefaults), so every scaffold gets ArkType. The interactive add-on picker excludes remote-URL add-ons, and tanstack add <url> reads options from the persisted .cta.json (no URL key, so no choice can reach the render either). Zod/Valibot are only reachable through the undocumented --add-on-config flag. In other words: the EJS branches are correct and the addOnOption lookup works for the shipped URL (I traced the exact render contract), but the user-facing promise of choice is not backed by the CLI behavior.

Technical details
# Documented validator choice is not reachable in the pinned CLI versions

## Affected sites
- apps/www/content/docs/frameworks/tanstack-start.mdx:34-39 — "The CLI prompts you to choose your preferred validation engine: ArkType (default) / Zod / Valibot"
- .changeset/tanstack-addon.md:10 — "Multi-validator selection during scaffolding (ArkType, Zod, or Valibot)"
- packages/tanstack-addon/README.md:21 — "Choose between ArkType, Zod, or Valibot"

## Evidence (traced from @tanstack/create@0.70.0 tarball + @tanstack/cli@0.71.0 dist)
- packages/create/src/package-json.ts:120,126 — render var is `addOnOption` (= `options.addOnOptions`), passed to `ejs.render`
- packages/create/src/custom-add-ons/add-on.ts:297 — remote add-on `id` is overwritten with the URL
- @tanstack/cli dist/options.js:149-152 — `--add-ons <url>` path uses `populateAddOnOptionsDefaults` (defaults only, no prompt)
- @tanstack/cli dist/ui-prompts.js:105 — interactive add-on picker lists built-in add-ons only; remote add-ons can't be selected there
- packages/create/src/add-to-app.ts:93-118 — `tanstack add <url>` `createOptions()` comes from persisted `.cta.json`; `addOnOptions` is never recomputed for the newly added remote add-on

## Required outcome
- The docs/changeset must describe actual CLI behavior for the shipped versions: ArkType is installed by default, and Zod/Valibot require the (currently undocumented) `--add-on-config` JSON flag keyed by URL. Either document that escape hatch, adjust the copy, or hold the multi-validator claim until an interactive option path exists.
- The template lookup itself is fine and needs no change; the `addOnOption['arkenv']` branch is just dead code for remote installs.

## Open questions for the human
- Is an interactive remote-add-on option prompt planned upstream? If the CLI changes before merge, re-verify rather than trusting this finding.

ℹ️ Hardcoded 1.0.0-alpha.1 diverges from the design doc's chosen E1 strategy

package.json.ejs and info.json hardcode 1.0.0-alpha.1 in four places — the design doc rates exactly this (E2, "Hardcoded pinned alpha versions") as D-tier and picked E1 (versions synced from RELEASE_CONFIG). No breakage today (^1.0.0-alpha.1 keeps resolving new alphas), but the alpha→rc→GA transition means bumping the range in package.json.ejs, the info.json version field, the compiled bundles, and the affected test expectations by hand, when the build script is the natural place to inject apps/www/lib/config/release.ts. Worth wiring up now so the transition is a one-constant change.

ℹ️ Nitpicks

  • The rendered env.ts outputs (all three dialects) and the demo route are asserted only via string containment; they are never typechecked as real TS files (this package's tsconfig includes only scripts/tests, and www now excludes public). A small temp-project tsc over the rendered output would catch a syntax/type slip that currently ships to every scaffolded app.
  • tanstack-start.mdx:43 says the add-on "Configures arkenvVitePlugin() in vite.config.ts", but the integration actually injects arkenv(). Both names are valid exports of @arkenv/vite-plugin; align the docs with the generated code.
  • The Valibot branch uses the root @arkenv/standard plus an inline v.transform(Number), whereas arkenv init scaffolds @arkenv/standard/valibot with v.pipe(v.number(), v.integer(), v.minValue(1), v.maxValue(65535)). Functional as-is, but matching the dialect keeps the add-on consistent with the CLI's own output.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread apps/www/content/docs/frameworks/tanstack-start.mdx Outdated
Comment thread packages/tanstack-addon/package.json Outdated
Comment thread packages/tanstack-addon/tests/compile.test.ts Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ℹ️ Minor suggestions only — one edge in the new optional-demo-route feature; nothing blocking.

Reviewed changes (delta since the prior review at 01ef1bc)

  • Optional demo route (7d1579f5): adds a demo select ("true" default / "false") to .add-on/info.json, converts the demo route asset from arkenv.tsx to arkenv.tsx.ejs, and gates it on includeExamples + ignoreFile() — verified against @tanstack/create@0.70.0, these are real render-context members (template-file.ts:141-184, edge-render.ts:18,31) and exactly the pattern the built-in add-ons use (if (!includeExamples) { ignoreFile(); return; }), so the skip mechanism is correct. Compiled bundles and www/public/tanstack mirrors updated.
  • Docs: tanstack-start.mdx copy reworked to describe both "Validator Engine" and "Interactive Demo Route" choices; .env.example pre-population is now listed instead of the always-on demo bullet.
  • Build fix: scripts/build.ts now rmSyncs the mirrored assets/ dir before re-copying, so removed/renamed assets no longer linger in apps/www/public/tanstack/assets/.
  • Tests: templates.test.ts gains four demo-template cases (render-by-default, ignoreFile on demo:"false", on includeExamples:false, and via a URL keyed option); compile.test.ts asserts the .tsx.ejs key and demo default.

Status of the prior findings: the arkenv.js.org URL concern is now explicitly tracked ("Blocked by #1812" in the PR body, plus a sync-to-main plan) — good. The "prompts you with configuration choices" copy was softened, but the underlying behavior is unchanged: with @tanstack/create@0.70.0 / @tanstack/cli@0.71.0, --add-ons <url> still runs default-options-only and never prompts, so neither the validator nor the demo-route choice is user-selectable through the documented command — the prior inline comment on this stands.

⚠️ routes metadata still advertises /demo/arkenv when the demo file is skipped

info.json's routes entry is unconditional, but the newly-optional demo route now can be skipped (demo: "false"ignoreFile()), so the compiled add-on can hand the CLI a route whose file was never written. The routes array is passed into the framework templates (template-file.ts:104-109,147), which wire the demo-route nav pills, so a skip would leave the scaffold's home layout pointing at a nonexistent src/routes/demo/arkenv.tsx. It's latent today (unreachable via --add-ons <url>, needs --add-on-config), but the option and the metadata now disagree by design.

Technical details
# routes metadata is stale when demo route is skipped

## Affected sites
- packages/tanstack-addon/.add-on/info.json:49-56 — `routes` always lists `/demo/arkenv``src/routes/demo/arkenv.tsx`
- packages/tanstack-addon/.add-on/assets/src/routes/demo/arkenv.tsx.ejs:7-13 — skip via `ignoreFile()` / `includeExamples`
- apps/www/public/tanstack/{info,add-on}.json — same metadata in the compiled bundles

## Required outcome
- When the demo route is skipped, the scaffolded app must not reference the missing route (no dangling nav pill, no missing-route error). Decide how `routes` metadata should behave under `demo:"false"` — e.g. make the entry conditional in the build step, or document that `--add-on-config '{"<url>":{"demo":"false"}}'` currently leaves a stale nav entry.

## Open questions for the human
- Does `@tanstack/create` fail hard on a route whose file is absent, or just render a dead link?

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/tanstack-addon/.add-on/info.json
@pullfrog

pullfrog Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor
  • Inspect files: info.json, compile.test.ts, design doc, README
  • Remove unconditional routes metadata (root cause of stale nav pill)
  • Update compile.test.ts routes assertion
  • Regenerate compiled bundles via build script (info.json/add-on.json mirrors)
  • Update design doc / README if they reference the nav-pill wiring
  • Run tests + typecheck, review diff, commit, push
  • Reply + resolve thread, report progress

Pullfrog  | View workflow run | via Pullfrog | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

yamcodes added a commit that referenced this pull request Sep 5, 2026
### Summary
This PR adds a reverse proxy rewrite in `apps/www/next.config.ts`
routing `/tanstack/:path*` requests to
`https://arkenv-v1.vercel.app/tanstack/:path*`.

### Why
The official TanStack CLI add-on for ArkEnv is deployed on the `v1`
branch at `https://arkenv-v1.vercel.app/tanstack/info.json`. Because
production docs (`https://arkenv.js.org`) are deployed from `main`
(which flows from `dev`), this rewrite allows
`https://arkenv.js.org/tanstack/info.json` to resolve immediately during
the alpha prerelease phase without URL rot or waiting for the full v1
merge.

Once merged to `dev`, this change can be synced directly to `main` via
`sync-main.yml` (Category 1 doc/infra sync).

**Blocks / Relates to:** #1811 (feat: add official TanStack CLI add-on
for ArkEnv)

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
@yamcodes

yamcodes commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

Review Feedback Addressed

  1. Compilation Side-Effects & Drift Prevention:

    • Refactored scripts/build.ts into a pure compileAddon() function and a side-effectful writeAddon().
    • Updated compile.test.ts to call compileAddon() without mutating the working tree, and added a strict parity assertion ensuring that committed bundles in apps/www/public/tanstack/ match .add-on/ sources byte-for-byte.
  2. Clean Script Footgun:

    • Fixed clean script in packages/tanstack-addon/package.json to only remove dist and node_modules, preventing the deletion of tracked source file .add-on/info.json.
  3. Validator Prompt Copy & Options:

    • Updated apps/www/content/docs/frameworks/tanstack-start.mdx, README.md, and .changeset/tanstack-addon.md to accurately document that the add-on scaffolds with ArkType by default, and clarified add-on configuration options without promising an interactive prompt for remote URLs.
  4. Demo Route & Manifest Metadata:

    • Verified that @tanstack/create automatically strips demo routes from addOn.routes when --no-examples or the blank preset is used. Documented --no-examples as the canonical flag to exclude demo routes.

@yamcodes

yamcodes commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

@pullfrog review

@pullfrog

pullfrog Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor
  • Checkout PR 1811 and read full diff
  • Triage: understand PR scope and domain
  • Read related files and gather context
  • Dispatch specialists if unresolved questions
  • Aggregate findings and draft review
  • Submit review

Pullfrog  | View workflow run | via Pullfrog | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Adds or changes documentation, or acts as documentation in and of itself tests This issue or PR is about adding, removing or changing tests www Improvements or additions to arkenv.js.org

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant