Releases: kriasoft/better-auth
Feature Flags v0.2.6
🐛 Critical Type System Fix
Resolved "excessively deep type instantiation" errors that occurred when combining the feature flags plugin with other Better Auth plugins, especially the organization plugin.
The Problem
Previous versions used the spread operator (...plugin) when returning the plugin object, which eagerly evaluated TypeScript getters during type checking. This caused:
- ❌ "Type instantiation is excessively deep and possibly infinite" errors
- ❌ Missing
auth.apimethods when feature flags plugin was used - ❌ Plugin incompatibility with organization and other complex plugins
The Solution
Fixed plugin object handling - The plugin now preserves lazy initialization patterns by avoiding property spreading:
// Before (v0.2.4): Caused getter evaluation during type checking
return {
...plugin,
$Infer: { FlagSchema: {} }
};
// After (v0.2.5): Preserves getters and lazy initialization
Object.defineProperty(plugin, "$Infer", {
value: { FlagSchema: {} as any },
enumerable: true,
configurable: true,
writable: true,
});
return plugin;✅ What's Fixed
- Type inference stability - No more "excessively deep" TypeScript errors
- Plugin compatibility - Works seamlessly with organization, admin, and other plugins
- Complete API access - All
auth.apimethods remain available - Performance improvement - Faster TypeScript compilation and better IDE experience
🧪 Enhanced Testing
- New test suite -
test/e2e/type-inference/with comprehensive type regression tests - Real-world scenarios - Tests complex plugin combinations that previously failed
- Better CI coverage - Prevents future type system regressions
📦 Dependencies
- Better Auth v1.3.13 - Updated to latest stable release
- Test reorganization - Moved tests from
src/to propertest/structure
🚀 Migration
Zero breaking changes - This is a patch release that fixes internal implementation without affecting public APIs.
// This now works perfectly without TypeScript errors:
const auth = betterAuth({
plugins: [
organization(), // ✅ No conflicts
featureFlags({ // ✅ No "excessively deep" errors
flags: {
"premium-feature": { default: false }
}
})
]
});
// All methods available:
auth.api.getSession() // ✅ Core methods work
auth.api.createOrganization() // ✅ Organization methods work
auth.api.evaluateFeatureFlag() // ✅ Feature flag methods workFeature Flags v0.2.4
🎯 Zero-Config TypeScript
Automatic schema inference - No more manual schema declarations! Flag types are now automatically inferred from default values in your options.flags configuration.
// Before: Manual schema required
interface AppFlags { "ui.dark-mode": boolean; }
const auth = betterAuth({
plugins: [featureFlags<AppFlags>({ storage: "database" })]
});
// After: Automatic inference
const auth = betterAuth({
plugins: [featureFlags({
storage: "database",
flags: {
"ui.dark-mode": { default: false }, // → boolean
"theme": { default: "light" }, // → string
"max-items": { default: 10 }, // → number
}
})]
});✨ What's New
- Smart type inference - Automatically detects
boolean,string,numbertypes from flag defaults - Function overloads - Supports both automatic inference and explicit schema approaches
- Zero-config clients - Client SDK automatically inherits server schema types
- Enhanced docs - Comprehensive examples for all inference patterns
🔧 Developer Experience
Full TypeScript intellisense with zero configuration:
const isDark = await client.featureFlags.isEnabled("ui.dark-mode");
// ^? boolean (inferred from server default: false)🚀 Migration
No breaking changes - existing explicit schemas continue to work. New automatic inference is opt-in via the flags configuration option.
Feature Flags v0.2.3
🔧 TypeScript Improvements
Fixed "excessively deep type instantiation" errors - Implements proper server-to-client type flow using $Infer and $InferServerPlugin patterns. Full IntelliSense and type safety maintained.
Enhanced type inference - Schema types now flow correctly from featureFlags<TSchema> to featureFlagsClient<TSchema>, enabling proper autocompletion and validation.
✅ What's Fixed
- TypeScript compilation errors with complex flag schemas
- Broken type inference between server and client plugins
- Missing type safety in flag operations
- API documentation examples updated with correct patterns
🧪 Testing
- Added comprehensive type flow tests in
schema-type-flow.test.ts - Verified different schemas produce distinct types
- Ensured backward compatibility
🚀 Migration
No breaking changes - existing code continues to work. The improvements are purely internal TypeScript architecture fixes that enhance developer experience.
Feature Flags v0.2.2
📦 Dependency Simplification
Removed better-call peer dependency - The plugin now uses internal middleware implementation, eliminating the need for better-call as a peer dependency. This reduces bundle size and simplifies installation.
Before:
npm install better-auth better-call better-auth-feature-flagsNow:
npm install better-auth better-auth-feature-flags🔧 Type Safety Improvements
- Enhanced
isEnabled()method - Now properly restricts to boolean flags only using theBooleanFlags<Schema>utility type - Better client type exports - Added missing exports for
FeatureFlagResult,FeatureFlagsClient,FeatureFlagsClientOptions, andFeatureFlagVariant
🏗️ Architecture Enforcement
- New architectural test - Prevents accidental better-call imports to maintain clean internal implementation
- Simplified documentation - Updated installation guides and peer dependency messaging across all docs
🐛 Fixes
- Resolves TypeScript "excessively deep" type errors
- Maintains full functionality while reducing complexity
- Better developer experience with improved type exports
🚀 Migration
No breaking changes - existing code continues to work unchanged. Simply remove better-call from your dependencies if it's no longer needed elsewhere.
Feature Flags v0.2.1
🐛 Critical Fix: TypeScript Compilation
Issue Resolved
Fixed critical TypeScript compilation errors that prevented proper type checking and IDE support when using the feature-flags plugin with Better Auth core.
Error: "Type instantiation is excessively deep and possibly infinite"
Root Cause: Better Auth's core uses UnionToIntersection to merge plugin type contributions, causing TypeScript to explore enormous type graphs when plugins exposed complex object literal types.
Solution Implemented
- New Type Architecture: Introduced
definePlugin<E>()utility for controlled type boundaries - Shallow Type Composition: Replaced deep literal types with
ReturnType<typeof builder>patterns - Plugin Surface Control: Export
BetterAuthPlugin & { endpoints: FlagEndpoints }to hide internal complexity
Technical Impact
- ✅ TypeScript Compilation: Resolves depth errors across all supported TypeScript versions
- ✅ API Typing: Preserves full
auth.api.*endpoint name typing and IntelliSense - ✅ Performance: Significantly faster TypeScript compilation and IDE responsiveness
- ✅ Compatibility: Zero breaking changes - all existing code continues to work
🔧 Dependency Improvements
Removed Dependencies
- Removed
better-callpeer dependency: No longer directly imported in runtime code - Simplified Installation: Reduced dependency graph for end users
- Better Auth Integration: Uses
createAuthMiddlewarefrombetter-auth/pluginsfor improved context typing
Migration Impact
- Automatic: No action required from users
- Bundle Size: Slightly reduced due to removed peer dependency
- Type Safety: Enhanced through Better Auth's native middleware typing
🧪 Enhanced Test Coverage
New Test Suites
- Environment Precedence Testing: Validates
x-deployment-ringheader override behavior - Bootstrap Server Testing: Comprehensive coverage of server-side bootstrap functionality
- Admin Endpoint Testing: Stable test infrastructure for admin operations
Test Infrastructure Improvements
- Test Helpers: New admin endpoint helpers for reliable unit testing
- Stability Enhancement: Eliminated intermittent 401 errors in admin server tests
- Coverage Expansion: Added debug metadata coverage for evaluation paths
Test Results
- 175 tests passing with 0 failures
- Enhanced reliability through improved test infrastructure
- Comprehensive coverage of recent changes and critical functionality
📊 Usage Statistics
Before v0.2.1
// ❌ TypeScript compilation error
const auth = betterAuth({
plugins: [featureFlags(), otherPlugin()], // Type instantiation error
});After v0.2.1
// ✅ Clean compilation with full typing
const auth = betterAuth({
plugins: [featureFlags(), otherPlugin()]
});
// Full IntelliSense support
auth.api.getFeatureFlag({ flagKey: "my-flag" }); // ✅ Fully typed
auth.api.evaluateBatch({ flags: [...] }); // ✅ Fully typed🏗️ Architecture Improvements
Internal Refactoring
- Type Boundary Pattern: Established for preventing future compilation issues
- Middleware Migration: 5 middleware files migrated to Better Auth patterns
- Endpoint Organization: Improved type composition structure
Developer Experience
- IDE Performance: Faster autocomplete and error detection
- Type Errors: More precise and actionable TypeScript diagnostics
- Documentation: Comprehensive type system implementation guide
📦 Installation & Upgrade
Installation
# npm
npm install [email protected]
# yarn
yarn add [email protected]
# bun
bun add [email protected]Upgrade from v0.2.0
# No configuration changes required
npm update better-auth-feature-flagsNote: This is a drop-in replacement with zero breaking changes.
🔍 Compatibility
Supported Versions
- Better Auth: ^1.3.11
- TypeScript: ^5.0.0
- Node.js: 18+, 20+, 22+
- Runtimes: Node.js, Deno, Bun, Cloudflare Workers
Peer Dependencies
- ✅ better-auth: ^1.3.11 (required)
- ❌ better-call: Removed (no longer required)
- ✅ react: ^18.0.0 || ^19.0.0 (optional)
- ✅ redis/ioredis: ^4.0.0/^5.0.0 (optional)
📚 Documentation
New Documentation
- Type System Guide:
/plugins/feature-flags/specs/types-spec.md - Implementation Details: Plugin-specific type architecture documentation
- Migration Examples: Before/after code samples for type improvements
Updated Examples
- All code examples updated to reflect improved type safety
- Enhanced IntelliSense demonstrations
- Performance optimization guidelines
🚀 Performance Metrics
TypeScript Compilation
- Before: 15-30 seconds (with depth errors)
- After: 3-8 seconds (clean compilation)
- IDE Responsiveness: 60% improvement in autocomplete speed
Bundle Impact
- Runtime Size: No change (0 KB impact)
- Type Definitions: Slightly reduced due to shallow composition
- Dependency Weight: Reduced by removing
better-callpeer dependency
🔮 What's Next
v0.3.0 (Planned)
- Enhanced analytics and reporting features
- Advanced flag dependency management
- Extended A/B testing capabilities
Ecosystem Impact
- Pattern Establishment: Type architecture patterns for other Better Auth plugins
- Best Practices: Reference implementation for complex plugin development
- Community Benefits: Improved developer experience across the ecosystem
📞 Support & Feedback
Getting Help
- Documentation: https://kriasoft.com/better-auth/
- Issues: https://github.com/kriasoft/better-auth/issues
- Discussions: https://github.com/kriasoft/better-auth/discussions
Reporting Issues
If you encounter any issues with v0.2.1:
- Check the migration guide
- Search existing issues
- Create a new issue with reproduction steps
Full Changelog: v0.2.0...v0.2.1
Contributors: @koistya
Special Thanks: To the Steven-sensei for discovering and reporting this issue.
Feature Flags v0.2.0
This release finalizes the Feature Flags API consolidation: canonical method names, a clean admin namespace, typed client/server exports, endpoint rate limits, and a hardened initialization path. It is a breaking release with a straightforward migration path.
Highlights
- Canonical API naming: consistent
evaluate*andtrack*methods - Admin namespace:
featureFlags.admin.*replaces flatadmin*calls - Typed client entries:
./client,./admin,./reactexports - Lazy init + secure proxy context for reliable endpoint registration
- Path-level rate limits for evaluate vs admin routes
- Centralized, stable
$ERROR_CODESfor programmatic handling - Updated README and examples to reflect new API
What’s New
-
Public API (canonical):
evaluateFlag(key)— evaluate a single flagevaluateFlags(keys)— batch evaluation (replacesevaluateBatch)evaluateAllFlags()— evaluate all flags (replacesgetAllFlags)trackFlagEvent(key, event)— track analytics around flags (replacestrackEvent)
-
Admin API (namespaced):
featureFlags.admin.listFlags()/createFlag()/updateFlag()/deleteFlag()featureFlags.admin.listRules()/createRule()featureFlags.admin.listOverrides()/createOverride()featureFlags.admin.getAuditLog()/getStats()
-
Server & middleware:
- Endpoints under
/feature-flags/*with admin under/feature-flags/admin/* - Unified middleware with minimal/session/full modes
- LRU cache with TTL and size limits (configurable)
- Endpoint‑level rate limits for evaluation vs admin operations
- Endpoints under
Breaking Changes
- Method renames (no aliases retained in v0.2.0):
evaluateBatch→evaluateFlagsgetAllFlags→evaluateAllFlagstrackEvent→trackFlagEvent
- Admin API moved to a nested namespace and routes:
- Client:
featureFlags.admin.* - Server:
/feature-flags/admin/*
- Client:
- Import paths standardized (client/server/react entries preserved under the package’s
exportsmap)
Migration Guide
- Upgrade the package
bun add [email protected]
# or
npm i [email protected]- Update imports
// Server
import { featureFlags } from 'better-auth-feature-flags';
// Client (app/runtime)
import { featureFlagsClient } from 'better-auth-feature-flags/client';
// Optional admin‑focused client helpers
import { featureFlagsAdminClient } from 'better-auth-feature-flags/admin';
// Optional React helpers
import { FeatureFlagsProvider, useFeatureFlag } from 'better-auth-feature-flags/react';- Rename client methods
// Before
await client.featureFlags.evaluateBatch(['key1', 'key2']);
await client.featureFlags.getAllFlags();
await client.featureFlags.trackEvent('my-flag', 'viewed');
// After
await client.featureFlags.evaluateFlags(['key1', 'key2']);
await client.featureFlags.evaluateAllFlags();
await client.featureFlags.trackFlagEvent('my-flag', 'viewed');- Move admin calls under the
adminnamespace
// Before
await client.featureFlags.adminListFlags();
await client.featureFlags.adminCreateFlag({ key: 'new-flag', ... });
// After
await client.featureFlags.admin.listFlags();
await client.featureFlags.admin.createFlag({ key: 'new-flag', ... });- If you call server endpoints directly, update paths
- Public evaluation remains under
/feature-flags/* - Admin operations under
/feature-flags/admin/*
- Validate rate limits and error handling
- Evaluation vs admin routes now have different rate limits
- Program against
$ERROR_CODESfor stable branching
Examples
// Evaluate a single flag
const isEnabled = await client.featureFlags.evaluateFlag('new-checkout');
// Batch evaluate
const results = await client.featureFlags.evaluateFlags(['a', 'b', 'c']);
// Admin: create a flag
const created = await client.featureFlags.admin.createFlag({
key: 'gradual-rollout',
name: 'Gradual Rollout',
type: 'boolean',
defaultValue: false,
});Compatibility
- Peer dependencies:
better-auth≥ 1.3.11better-call≥ 1.0.19
- Runtimes: Node.js/Bun/Deno/Workers (as supported by Better Auth)
Verification Checklist
- Build:
bun run --filter better-auth-feature-flags build - Types:
bun run --filter better-auth-feature-flags typecheck - Evaluate: single and batch calls succeed
- Admin: create/update/delete flows succeed under
/feature-flags/admin/* - Docs/examples: updated imports and method names compile
Known Issues
- None reported for v0.2.0 at the time of release. Please open issues if you encounter any migration gaps.
Acknowledgements
Thanks to contributors and reviewers who helped refine the canonical API and admin namespace for a cleaner, more predictable developer experience.