blitz-js/blitz
⚡️ The Missing Fullstack Toolkit for Next.js
Provides fullstack abstractions and tooling that extend Next.js with authentication, database integration, and RPC calls
Data flows through multiple independent pipelines. Authentication starts with login credentials, creates encrypted sessions stored in cookies, and provides session data to React hooks. RPC calls originate from React components, get serialized to HTTP requests, execute server resolvers with authentication context, and return typed results. Code generation takes CLI arguments and templates, processes them with variable substitution, and outputs complete application scaffolding. All flows integrate through shared session management and Next.js routing.
Under the hood, the system uses 4 feedback loops, 4 data pools, 4 control points to manage its runtime behavior.
A 8-component fullstack. 669 files analyzed. Data flows through 6 distinct pipeline stages.
How Data Flows Through the System
Data flows through multiple independent pipelines. Authentication starts with login credentials, creates encrypted sessions stored in cookies, and provides session data to React hooks. RPC calls originate from React components, get serialized to HTTP requests, execute server resolvers with authentication context, and return typed results. Code generation takes CLI arguments and templates, processes them with variable substitution, and outputs complete application scaffolding. All flows integrate through shared session management and Next.js routing.
- CLI Command Processing — The BlitzCliRouter in packages/blitz/src/cli/index.ts parses command-line arguments, resolves aliases (g->generate, d->dev), and dynamically imports the appropriate command handler [CLI Arguments → Command Execution]
- Authentication Flow — SessionManager processes login credentials, creates encrypted session tokens with CSRF protection, stores them in httpOnly cookies, and the PublicDataStore makes session data available to React components via useCurrentUser hook [Login Credentials → AuthenticatedClientSession]
- RPC Invocation — RpcClient transforms function calls like invoke(getUser, {id: 1}) into HTTP POST requests to /api/rpc/getUser with serialized parameters, authentication headers, and CSRF tokens [RpcInvoke → HTTP Requests]
- Server Resolver Execution — Server receives RPC requests, validates authentication and CSRF tokens, calls the resolver function with user context, and serializes the result back to the client [HTTP Requests → Typed Results]
- Code Generation — CodeGenerator takes CLI generate commands, prompts for model details, processes template files with variable substitution using field names and types, and writes complete CRUD scaffolding including pages, queries, and mutations [Generator Config → Generated Code Files]
- Error Boundary Processing — ErrorBoundary catches RedirectError exceptions from server code, extracts the redirect URL, and triggers client-side navigation using Next.js router [Component Errors → Route Navigation]
Data Models
The data structures that flow between stages — the contracts that hold the system together.
packages/blitz-auth/src/shared/index.tsobject with userId: string | null, role: string | null, plus any additional fields applications define
Created on login, stored in encrypted cookies and localStorage, accessed by useCurrentUser hook, cleared on logout
packages/blitz-auth/src/shared/index.tsobject with publicData: PublicData (where userId is not null), plus session management methods
Created when PublicData contains valid userId, used throughout authenticated user flows
packages/blitz-next/src/types.tsNext.js Page component extended with authenticate: {redirectTo?: string} and getLayout?: function properties
Defined by developers on page components, processed by Blitz router to enforce authentication requirements
packages/blitz-rpc/src/client/invoke.tsfunction call with resolver: Function, params: any[], context?: Ctx returning Promise<T>
Created on client RPC invocation, serialized over HTTP, executed on server with context, result serialized back
packages/generator/src/generator.tsobject with templatePath: string, targetPath: string, templateValues: Record<string, any>
Built from CLI args and prompts, used to transform templates with variable substitution, generates final code files
Hidden Assumptions
Things this code relies on but never validates. These are the things that cause silent failures when the system changes.
enhancePrisma() returns a constructor that can be called with `new` to create a Prisma client instance, but no validation exists that PrismaClient is actually a constructable class
If this fails: If PrismaClient is undefined, null, or not a constructor, the `new EnhancedPrisma()` call will throw a runtime error that crashes the application on database access
apps/toolkit-app/db/index.ts:enhancePrisma
localStorage exists and is writable when `typeof window !== 'undefined'` is true, but no error handling exists for localStorage access failures
If this fails: In environments where localStorage is disabled (private browsing, storage quota exceeded), authentication state synchronization fails silently across browser tabs, causing inconsistent login states
packages/blitz-auth/src/client/index.tsx:PublicDataStore.constructor
The base64-decoded token contains valid JSON with userId and role properties, but only validates that JSON.parse succeeds
If this fails: If the token contains valid JSON but missing userId/role fields, components using useCurrentUser will receive malformed user data and may crash when accessing expected properties
packages/blitz-auth/src/client/index.tsx:parsePublicDataToken
The 100ms setTimeout delay is sufficient for Next.js routing to complete before clearing React Query cache, but this timing is hardcoded without considering slow devices or heavy page loads
If this fails: On slow devices or complex pages, authentication queries may start before the cache is cleared, leading to stale authentication data being displayed or authorization errors on protected pages
packages/blitz-rpc/src/query/react-query/index.ts:resetQueryClient
Dynamic import promises will always resolve to modules with the expected export names (dev, build, generate, etc.), but no validation exists for the imported module structure
If this fails: If a command module is corrupted or renamed its exports, CLI commands fail with confusing 'not a function' errors instead of clear 'command not found' messages
packages/blitz/src/cli/index.ts:commands[blitzCommand]
If tsconfig.json exists, it contains valid JSON with properly structured compilerOptions.paths, but only checks file existence
If this fails: Malformed tsconfig.json files cause Jest setup to fail with obscure JSON parsing errors, making it unclear that the TypeScript configuration is the root cause
packages/blitz-next/jest/index.js:tsConfigPath
Canceling and resetting all React Query queries will complete within reasonable time, but no timeout or error handling exists for stuck queries
If this fails: If some queries become stuck or unresponsive, the cache reset operation hangs indefinitely, preventing users from logging out completely and leaving the app in an inconsistent state
packages/blitz-rpc/src/query/react-query/index.ts:queryClient.resetQueries
The BadBehavior observable pattern can handle unlimited subscribers across multiple browser tabs without memory leaks, but no cleanup or subscription limits exist
If this fails: Applications with many tabs or long-lived sessions may accumulate memory leaks from uncleaned observable subscriptions, eventually degrading browser performance
packages/blitz-auth/src/client/index.tsx:BadBehavior.observable
Next.js router context is available and stable during error boundary rendering, but no validation exists that router object contains expected properties
If this fails: During navigation errors or router resets, the error boundary may try to access undefined router properties, causing additional errors that mask the original problem
packages/blitz-next/src/error-boundary.tsx:withRouter
The currentUser object returned by useCurrentUser hook always has string-type id and role properties when user is authenticated, but the component directly renders these without type checking
If this fails: If the authentication system returns user objects with numeric IDs or null roles, the JSX will display '[object Object]' or empty values, confusing users about their login status
apps/toolkit-app/src/pages/index.tsx:currentUser.id
System Behavior
How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.
Data Pools
Encrypted cookies containing session tokens and public data, shared across requests
Client-side cache for RPC query results with automatic invalidation on session changes
Browser localStorage used as message bus for session updates across tabs
File system accumulation of generated pages, queries, mutations from CLI commands
Feedback Loops
- Session Sync Loop (polling, balancing) — Trigger: localStorage storage events. Action: PublicDataStore updates observable state and notifies all subscribers. Exit: component unmount.
- React Query Retry (retry, balancing) — Trigger: network request failure. Action: exponential backoff retry up to 3 times for network errors only. Exit: success or max retries reached.
- Cache Invalidation Cycle (cache-invalidation, balancing) — Trigger: session creation or logout events. Action: clear all React Query caches and cancel running queries. Exit: cache cleared.
- Error Recovery Loop (circuit-breaker, balancing) — Trigger: RedirectError or authentication failure. Action: ErrorBoundary catches error, triggers navigation, resets component tree. Exit: successful navigation.
Delays
- Cache Reset Delay (async-processing, ~100ms) — prevents stale authentication queries from running after logout
- Dynamic Import Loading (compilation, ~variable) — CLI commands load lazily, first execution slower but reduces startup time
- Template Processing (compilation, ~variable) — code generation processes templates synchronously, blocking CLI until complete
Control Points
- NODE_ENV (env-var) — Controls: React Query retry behavior - disabled in development, enabled in production
- Debug Flags (env-var) — Controls: authentication debug logging via debug('blitz:auth-client')
- Query DefaultOptions (runtime-toggle) — Controls: React Query caching strategy, retry logic, and SSR behavior. Default: cacheTime: 0 on server
- Template Variables (runtime-toggle) — Controls: code generation output by substituting model names, field types, and validation rules into templates
Technology Stack
provides the underlying React framework and routing that Blitz extends with fullstack capabilities
handles client-side caching and synchronization for RPC calls, with custom Blitz integration
database ORM enhanced by Blitz with additional utilities and type generation
provides end-to-end type safety from database models through RPC calls to React components
powers AST-based code transformations for upgrade codemods and potentially generators
monorepo build orchestration with dependency-aware task execution
testing framework with custom Blitz configuration for client/server test separation
schema validation for authentication forms and API inputs
Key Components
- BlitzCliRouter (orchestrator) — Routes CLI commands to appropriate handlers (dev, build, generate, etc.) and manages command aliases
packages/blitz/src/cli/index.ts - PublicDataStore (store) — Manages user session state across browser tabs using localStorage events and BadBehavior observable pattern
packages/blitz-auth/src/client/index.tsx - SessionManager (processor) — Handles server-side session creation, validation, and cleanup with encrypted cookie management
packages/blitz-auth/src/server/index.ts - RpcClient (adapter) — Transforms function calls into HTTP requests and handles serialization/deserialization of parameters and results
packages/blitz-rpc/src/client/rpc.ts - BlitzRpcPlugin (factory) — Creates and configures React Query integration with retry logic and cache invalidation strategies
packages/blitz-rpc/src/query/react-query/index.ts - ErrorBoundary (processor) — Catches RedirectError and other exceptions, handles client-side navigation and error recovery
packages/blitz-next/src/error-boundary.tsx - CodeGenerator (processor) — Processes template files with variable substitution and generates code scaffolding for pages, queries, mutations
packages/generator/src/generator.ts - BlitzCodemod (transformer) — Performs AST-based code transformations for upgrading Blitz applications between versions
packages/codemod/src/index.ts
Package Structure
Core CLI that orchestrates development commands and provides Next.js extensions
Authentication system with session management, CSRF protection, and Passport.js integration
Type-safe RPC layer that lets React components call backend functions directly
Next.js integration layer with error boundaries, routing extensions, and Jest configuration
Code generation system that creates pages, queries, mutations, and complete CRUD scaffolding
AST-based code transformation tool for upgrading Blitz applications between versions
Shared ESLint configuration for Blitz projects
Reference implementation of a Blitz app with authentication and database integration
Reference implementation using Passport.js for authentication instead of built-in auth
Example app demonstrating Blitz authentication with Next.js 13 features
Documentation and marketing website for Blitz.js
Explore the interactive analysis
See the full architecture map, data flow, and code patterns visualization.
Analyze on CodeSeaRelated Fullstack Repositories
Frequently Asked Questions
What is blitz used for?
Provides fullstack abstractions and tooling that extend Next.js with authentication, database integration, and RPC calls blitz-js/blitz is a 8-component fullstack written in TypeScript. Data flows through 6 distinct pipeline stages. The codebase contains 669 files.
How is blitz architected?
blitz is organized into 4 architecture layers: Core Packages, Development Tools, Example Applications, Integration Tests. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.
How does data flow through blitz?
Data moves through 6 stages: CLI Command Processing → Authentication Flow → RPC Invocation → Server Resolver Execution → Code Generation → .... Data flows through multiple independent pipelines. Authentication starts with login credentials, creates encrypted sessions stored in cookies, and provides session data to React hooks. RPC calls originate from React components, get serialized to HTTP requests, execute server resolvers with authentication context, and return typed results. Code generation takes CLI arguments and templates, processes them with variable substitution, and outputs complete application scaffolding. All flows integrate through shared session management and Next.js routing. This pipeline design reflects a complex multi-stage processing system.
What technologies does blitz use?
The core stack includes Next.js (provides the underlying React framework and routing that Blitz extends with fullstack capabilities), React Query (handles client-side caching and synchronization for RPC calls, with custom Blitz integration), Prisma (database ORM enhanced by Blitz with additional utilities and type generation), TypeScript (provides end-to-end type safety from database models through RPC calls to React components), jscodeshift (powers AST-based code transformations for upgrade codemods and potentially generators), Turbo (monorepo build orchestration with dependency-aware task execution), and 2 more. A focused set of dependencies that keeps the build manageable.
What system dynamics does blitz have?
blitz exhibits 4 data pools (Session Cookie Store, React Query Cache), 4 feedback loops, 4 control points, 3 delays. The feedback loops handle polling and retry. These runtime behaviors shape how the system responds to load, failures, and configuration changes.
What design patterns does blitz use?
5 design patterns detected: Plugin Architecture, Observable State Management, Command Pattern, Template Method, Error Boundary with Recovery.
Analyzed on April 20, 2026 by CodeSea. Written by Karolina Sarna.