Imagine catching API integration errors before they hit production, having perfect autocompletion for your backend endpoints, and never having to manually update API types again. This isn't just a dream - it's possible with end-to-end type safety. In this post, I'll show you how I built a fully type-safe system that bridges Python and TypeScript, making full-stack development a breeze.
Why This Matters: Real-World Impact
Before we dive into the implementation, let's look at how this setup transforms your development experience:
1. Catch Errors Early
2. Perfect Autocompletion
Your IDE instantly shows you:
- All available API endpoints
- Required parameters and their types
- Response data structure
- Validation rules from your Python models
3. Automatic Updates
When you modify your FastAPI models:
The TypeScript types automatically update:
4. Developer Experience
- No more API documentation hunting
- Instant feedback on invalid API usage
- Confident refactoring across the stack
- Seamless team collaboration between frontend and backend
The Challenge
When building full-stack applications with different languages (Python for backend and TypeScript for frontend), maintaining type safety across the boundary can be challenging. Common issues include:
- Manually keeping types in sync
- Runtime type errors from API responses
- Inconsistent API documentation
- Time-consuming SDK maintenance
The Solution: Our Tech Stack
We'll use:
Here are the key technologies we'll be using:
- FastAPI - Modern Python web framework
- Next.js - React framework for production
- hey API - SDK generator from OpenAPI specs
- Turborepo - High-performance build system
- pnpm - Fast, disk space efficient package manager
- React - UI library
- Expo - React Native platform
- OpenAPI - API specification standard
- Pydantic - Data validation using Python type annotations
- Axios - Promise based HTTP client
- TanStack Query - Powerful data synchronization for React
Setting Up the Project Structure
You have two options for organizing your codebase:
Option 1: Monorepo Structure (Recommended)
Option 2: Separate Repositories
The beauty of this setup is that it doesn't matter where your FastAPI backend lives - all we need is access to its OpenAPI specification URL. This flexibility allows you to:
- Keep the backend in the same monorepo for tighter integration
- Maintain it in a separate repository for independent scaling
- Even use an existing FastAPI service - as long as you have access to its OpenAPI spec
The SDK generation process remains the same regardless of where your FastAPI backend is hosted. This is particularly useful when:
- Working with existing backend services
- Different teams manage frontend and backend
- You need different deployment cycles for frontend and backend
- The backend needs to be used by multiple frontend applications
Backend: FastAPI with Type Definitions
In our FastAPI application, we define our models using Pydantic:
FastAPI automatically generates an OpenAPI specification from our code:
Generating the SDK with hey API
hey API makes it easy to generate a type-safe SDK from our OpenAPI spec. Here's our configuration:
We also need to set up our SDK package configuration:
Important: After setting up the SDK configuration, you need to generate the SDK by running:
This command will fetch the OpenAPI spec from your FastAPI backend and generate the type-safe SDK. Remember to run this command whenever you make changes to your API endpoints or models.
Next.js Configuration
For the types to be properly recognized in your Next.js application, you need to add the SDK package to the transpilePackages
configuration in your next.config.js
:
This ensures that Next.js correctly processes and recognizes the types from your SDK package.
SDK Initialization and Configuration
Before we can use the SDK, we need to add it as a dependency in our client application's package.json
. We'll use pnpm for package management:
The workspace:*
syntax tells pnpm to use the local workspace version of the SDK, which is essential for monorepo setups.
Now we can set up our SDK with interceptors for authentication and error handling:
This setup provides:
- Automatic authentication token injection
- Global error handling
- Environment-based API URL configuration
- Type-safe request and response handling
Using the Generated SDK in Next.js
Now we can use our type-safe SDK in our Next.js application. The method names in the SDK are automatically derived from the operation IDs defined in our FastAPI backend:
The SDK methods are organized by resource (like users
, posts
, etc.) and the method names are derived from the operation IDs in your FastAPI routes. For example:
This naming convention ensures consistent and predictable API method names across your entire application.
Automating SDK Generation
We can automate SDK generation in our Turborepo pipeline:
Benefits of This Approach
- Type Safety: Complete type safety from backend to frontend
- Developer Experience: Autocomplete and type checking in your IDE
- Maintainability: Single source of truth for API types
- Productivity: Automated SDK generation saves development time
- Documentation: OpenAPI spec serves as living documentation
Common Pitfalls and Solutions
-
Version Mismatches
- Use workspace dependencies in package.json
- Implement version checking in CI/CD
-
Development Workflow
- Run backend in watch mode using uvicorn
- Automate SDK generation on schema changes
-
Error Handling
- Define error types in FastAPI
- Generate corresponding error types in SDK
Conclusion
This isn't just about clean code - it's about building better products faster. With this setup:
🚀 Development Speed
- 50% faster API integration - No more back-and-forth with API docs
- 90% fewer runtime errors - Catch type mismatches before they hit production
- Instant refactoring - Change API structures with confidence
💡 Developer Experience
- Write code with confidence, knowing TypeScript has your back
- Get instant feedback when you make a mistake
- Focus on building features instead of debugging type issues
🤝 Team Collaboration
- Backend changes automatically propagate to frontend
- Clear contracts between services
- Easier onboarding for new team members
📈 Business Impact
- Faster time to market
- Fewer production bugs
- Lower maintenance costs
- Better code quality
The combination of FastAPI's automatic OpenAPI generation, hey API's SDK generation, and Turborepo's monorepo management creates a development experience that's not just type-safe, but genuinely enjoyable.
Ready to transform your development workflow? Check out the complete code on my GitHub and start building with confidence!
Have questions or want to share your experience? Feel free to reach out on Twitter or LinkedIn - I'd love to hear how you're using these tools in your projects.