Skip to content

feat(types)!: remove TypeBox schema type inference support#179

Merged
halvaradop merged 8 commits into
masterfrom
perf/optimize-type-inference
Jun 5, 2026
Merged

feat(types)!: remove TypeBox schema type inference support#179
halvaradop merged 8 commits into
masterfrom
perf/optimize-type-inference

Conversation

@halvaradop
Copy link
Copy Markdown
Member

@halvaradop halvaradop commented Jun 4, 2026

Description

This pull request optimizes type inference by reducing TypeBox Static usage, lowering TypeScript instantiations from 1,323,740 to 158,861. The excessive number of instantiations was caused by deeply nested type operations generated by TypeBox's type system.

This investigation started after identifying performance bottlenecks in @aura-stack/router, primarily caused by TypeBox's Static type, which is used to infer the types of searchParams, params, and body. The issue was initially addressed in aura-stack-ts/router#51 and aura-stack-ts/router#52. However, after running diagnostics on Aura Auth, I found that the same type inference patterns were still generating a significant number of TypeScript instantiations.

tsc --extendedDiagnostics --generateTrace ./trace
npx @typescript/analyze-trace ./trace > hot-spots.txt

The analysis showed that the primary hotspot was src/client/client.ts. The reason is that, in the previously mentioned Aura Router pull requests, some TypeBox-based inference remained because it did not have a measurable impact on the diagnostics at the time and was therefore not removed.

Trace analysis:

  • hot-spots.txt
    To validate the impact, I excluded client.ts from the diagnostics. This reduced the total number of TypeScript instantiations from 1,323,740 to 144,130, confirming that the remaining TypeBox inference in this file was responsible for most of the overhead.

Diagnostics:

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Jun 4, 2026

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

Project Deployment Actions Updated (UTC)
auth Ready Ready Preview, Comment Jun 5, 2026 4:24pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

Warning

Review limit reached

@halvaradop, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 53 minutes and 14 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: abb3f2fe-3606-4ef8-ad1b-9f83731e3034

📥 Commits

Reviewing files that changed from the base of the PR and between 2a57dd3 and 737a777.

📒 Files selected for processing (1)
  • docs/src/content/docs/(core)/guides/schema-validation.mdx
📝 Walkthrough

Walkthrough

Adds an exported EditableUser type, simplifies TypeBox shape-to-object typings, integrates EditableUser into identity conditional types, tightens TypeBox-related tests, expands schema-validation docs for multiple libraries, and updates workspace catalogs plus a router dependency bump.

Changes

EditableUser Type System Refinement

Layer / File(s) Summary
Workspace catalogs and dependency updates
package.json, packages/core/package.json
Root package.json adds valibot and testing-library version catalogs; packages/core/package.json bumps @aura-stack/router to ^0.7.2.
EditableUser type and TypeBox type simplification
packages/core/src/@types/utility.ts
Convert TypeBox imports to import type, add export type EditableUser = { [K in keyof User]: any }, make TypeboxShapeToObject<S> = Wrap<Merge<S, User>>, and adjust the FromShapeToObject conditional tail.
Identity union integration for EditableUser
packages/core/src/shared/identity.ts
Add EditableUser to the multi-line import type and include it in the Identities union; update ReturnShapeType<T> with a T extends EditableUser branch returning z.ZodObject<T>.
Type test updates for TypeBox optional representation
packages/core/test/identity.test.ts, packages/core/test/types.test-d.ts
Rewrite TypeBox auth typing test to assert Static<typeof Schema> directly; tighten expected TypeBox role type to Typebox.TOptional<Typebox.TString> in signJWS and getSession type assertions.
Schema validation docs (multi-library)
docs/src/content/docs/(core)/guides/schema-validation.mdx
Expand guide from Zod-only to tabbed examples for zod, valibot, arktype, and typebox; add library-specific inference notes and a TypeBox Static workaround example.

Possibly Related PRs

  • aura-stack-ts/auth#163: Directly related—modifies TypeBox-related typing helpers in packages/core/src/@types/utility.ts.
  • aura-stack-ts/auth#161: Overlaps on identity/type conditional changes touching ReturnShapeType and identity integration.

Suggested Labels

feature, refactor

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble types with gentle care,
EditableUser hops into the air,
TypeBox relaxed, docs in tabs shine bright,
Tests tuned up, dependencies set right —
A little rabbit dance, and code feels light.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately reflects the primary change: removing TypeBox schema type inference support to reduce TypeScript compilation overhead, as confirmed by the substantial instantiation reduction (1,323,740 to 144,130) and the detailed performance investigation described in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/optimize-type-inference

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.

Copy link
Copy Markdown

@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: 6

🧹 Nitpick comments (1)
packages/core/src/@types/utility.ts (1)

39-41: 💤 Low value

Consider the safety implications of mapping all User keys to any.

The EditableUser type maps every key of User to any, which completely removes type safety for all user fields. This permissive approach could lead to runtime errors if field types are misused.

While this may be intentional for maximum flexibility in custom identity configurations, consider whether a more constrained approach (e.g., unknown instead of any, or preserving some base field types) would better balance flexibility and safety.

Alternative: Use `unknown` for better type safety
 export type EditableUser = {
-    [K in keyof User]: any
+    [K in keyof User]: unknown
 }

This would require explicit type assertions, providing a bit more safety than any.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/`@types/utility.ts around lines 39 - 41, EditableUser
currently maps every property of User to any (export type EditableUser = { [K in
keyof User]: any }), which removes type safety; change the mapped type to be
safer—e.g., use unknown instead of any (export type EditableUser = { [K in keyof
User]: unknown }) or selectively preserve core field types (keep explicit types
for critical keys and map the rest to unknown) so callers must assert/validate
values; update references to EditableUser accordingly to handle the stricter
type.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/`@types/utility.ts:
- Line 58: The TypeboxShapeToObject type is incorrectly merging a TypeBox schema
S with the runtime User type (via Wrap<Merge<S, User>}) instead of converting
the schema to its inferred runtime shape; update TypeboxShapeToObject to use
TypeBox's Static<TObject<S>> (or equivalent Static conversion) for S before
merging with User so schema definitions like TOptional<TString> become runtime
types (e.g., string | undefined). Locate the TypeboxShapeToObject alias and
replace the Merge<S, User> usage with Merge<Static<TObject<S>>, User> (or the
project's alias for Static/TObject) so tests expecting role?: string are
restored while keeping Wrap and Merge intact.
- Line 2: The TypeBox runtime type inference was broken by removing Static;
re-add Static to the import list and update the
TypeboxShapeToObject/FromShapeToObject type aliases to return Static applied to
the TypeBox schema (use Static<TSchema> / Static<TObject<...>> or
Static<TProperties<...>> as appropriate) so that TypeboxShapeToObject and any
usages (TypeboxShapeToObject, FromShapeToObject, TProperties, TObject, TSchema)
resolve to actual runtime value types (e.g., string) instead of schema objects;
ensure the restored import includes Static from "typebox" and adjust the type
alias at the previous TypeboxShapeToObject definition to wrap the schema with
Static.
- Around line 79-81: Add a focused compile-time type test that forces the
`FromShapeToObject` branch `S extends User ? S : never` to be exercised: in
`packages/core/test/types.test-d.ts` add a d.ts-only test that creates an
identity/schema which resolves to `User` (or calls `createAuth`/uses
`FromShapeToObject` with `User`-shaped `Identity`) and asserts assignability or
equality (e.g., via a type-level `Expect<Equal<...>>` or by assigning the result
to a `User`-typed variable) so the compiler must pick the `S extends User`
branch; alternatively if you cannot produce such a test, remove the fallback
case in `FromShapeToObject` or add a brief comment documenting why the `S
extends User` branch is required.

In `@packages/core/src/shared/identity.ts`:
- Line 72: ReturnShapeType currently lacks a branch for EditableUser so
ReturnShapeType<EditableUser> resolves to never; update the ReturnShapeType<T>
conditional type to include an EditableUser => <appropriate return shape> branch
(matching how other identity variants are handled) so createIdentity can accept
and return the correct type for EditableUser; adjust the conditional chain in
ReturnShapeType to include the EditableUser case and ensure any related
overloads or usages of Identities and createIdentity align with that return
shape.

In `@packages/core/test/identity.test.ts`:
- Around line 191-195: The test failure is caused by Typebox type inference
being broken after removing Static from TypeboxShapeToObject in utility.ts;
restore Static usage in TypeboxShapeToObject so TypeBox schemas map to their
Static types, allowing createAuth to infer the identity type from Schema
(removing the need for the explicit <ExpectedIdentity> generic and the schema as
any cast). Update the TypeboxShapeToObject type alias/utility to reintroduce
Static (importing it from `@sinclair/typebox` if necessary), ensure any dependent
helpers/types reference the corrected TypeboxShapeToObject, and run the
identity.test.ts to confirm Schema is inferred correctly by createAuth without
casts.

In `@packages/core/test/types.test-d.ts`:
- Line 146: The tests are asserting schema descriptors instead of runtime value
types because TypeboxShapeToObject lost the Static mapping; restore the runtime
mapping by reintroducing TypeBox's Static when converting shapes (e.g., update
TypeboxShapeToObject/FromShapeToObject to wrap the TypeBox schema types with
Static) so inferred types become runtime types (string | undefined) and update
the failing assertions in packages/core/test/types.test-d.ts (e.g., change role:
Typebox.TOptional<Typebox.TString> expectations to role?: string | undefined) to
reflect the corrected runtime types.

---

Nitpick comments:
In `@packages/core/src/`@types/utility.ts:
- Around line 39-41: EditableUser currently maps every property of User to any
(export type EditableUser = { [K in keyof User]: any }), which removes type
safety; change the mapped type to be safer—e.g., use unknown instead of any
(export type EditableUser = { [K in keyof User]: unknown }) or selectively
preserve core field types (keep explicit types for critical keys and map the
rest to unknown) so callers must assert/validate values; update references to
EditableUser accordingly to handle the stricter type.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b2644399-081f-49b9-9a0d-93ddcb4b165f

📥 Commits

Reviewing files that changed from the base of the PR and between 50a0781 and fb30b53.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • package.json
  • packages/core/package.json
  • packages/core/src/@types/utility.ts
  • packages/core/src/shared/identity.ts
  • packages/core/test/identity.test.ts
  • packages/core/test/types.test-d.ts

Comment thread packages/core/src/@types/utility.ts
Comment thread packages/core/src/@types/utility.ts
Comment thread packages/core/src/@types/utility.ts
Comment thread packages/core/src/shared/identity.ts
Comment thread packages/core/test/identity.test.ts Outdated
Comment thread packages/core/test/types.test-d.ts Outdated
@halvaradop halvaradop changed the title perf(core): optimize type inference by reducing TypeBox Static usage perf(core): optimize type inference by reducing TypeBox Jun 5, 2026
@halvaradop halvaradop changed the title perf(core): optimize type inference by reducing TypeBox feat(types)!: remove TypeBox schema type inference support Jun 5, 2026
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/src/content/docs/`(core)/guides/schema-validation.mdx:
- Line 10: Fix the grammar and clarity in the schema-validation copy: replace
"its provided the default `Identity` schemas" with "each library provides the
default `Identity` schemas" (or "it provides" depending on context), change
"They schemas contains" to "These schemas contain", and correct any occurrence
of "limitation by the expensive nature" to "limited by their expensive nature"
(or "limited due to their expensive nature"); update the same phrasing
occurrences mentioned around lines 188-190 and ensure the sentence about default
fields reads "The schemas contain `sub`, `name`, `email`, and `image` by
default, but you can extend them with additional fields."
- Line 10: The paragraph incorrectly claims all listed libraries support
built-in type inference; update the text that describes the default Identity
schema so it only claims validation and type inference for libraries that
actually support it and explicitly exclude TypeBox (referencing the Identity
schema and TypeBox) — rephrase to something like: the default Identity schema
(sub, name, email, image) can be extended and will leverage built-in validation
and type inference in supported libraries, while noting that TypeBox does not
support direct inference here. Ensure the Identity reference remains and fix the
grammar ("They schemas contains" → correct wording).
- Line 113: The import statement duplicates the type names; update the import so
each symbol appears only once and use the TypeScript type import form for the
types referenced — e.g., keep UserIdentity and import UserFrom and SessionFrom
as types by changing the import that currently lists UserFrom and SessionFrom
twice to a single clause that reads UserIdentity and type UserFrom, type
SessionFrom (referencing the existing import statement and symbols UserIdentity,
UserFrom, SessionFrom).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d79dd04-7c30-47e9-a075-c444a316f62d

📥 Commits

Reviewing files that changed from the base of the PR and between fb30b53 and 2a57dd3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • docs/src/content/docs/(core)/guides/schema-validation.mdx
  • packages/core/package.json
  • packages/core/src/shared/identity.ts
  • packages/core/test/identity.test.ts
  • packages/core/test/types.test-d.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/core/test/types.test-d.ts

Comment thread docs/src/content/docs/(core)/guides/schema-validation.mdx Outdated
Comment thread docs/src/content/docs/(core)/guides/schema-validation.mdx Outdated
@halvaradop halvaradop merged commit 4df3a3e into master Jun 5, 2026
4 of 6 checks passed
@halvaradop halvaradop deleted the perf/optimize-type-inference branch June 5, 2026 16:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant