Understanding .ts and .tsx File Extensions in TypeScript

Master the distinction between pure TypeScript files and TypeScript with JSX for building robust React applications

What Is the .ts File Extension?

The .ts extension stands for TypeScript, representing pure TypeScript files that contain type annotations, interfaces, classes, and other TypeScript-specific features without any JSX syntax. These files are used for utility functions, type definitions, data models, and any other TypeScript code that doesn't involve UI rendering.

Use Cases for .ts Files

Pure TypeScript files (.ts) serve as the backbone for well-organized applications. They excel at organizing type definitions and interfaces that describe data structures across your entire application. When building API clients and service layers that handle HTTP requests, data transformation, and external integrations, .ts files provide the ideal separation of concerns. Utility functions for data manipulation, string formatting, date handling, and validation logic belong in .ts files where they can be imported and reused throughout your project. Custom hooks that don't involve JSX rendering--such as logic for local storage, window resizing, or API state management--also benefit from the clean separation that .ts files provide.

By keeping business logic, type definitions, and utilities in .ts files, you create a clear boundary between your application's logic layer and its UI rendering layer. This separation improves maintainability, makes testing easier, and keeps your React components focused on what they do best: rendering user interfaces. To understand how npm scripts and package execution fits into this workflow, explore our guide on npm vs npx.

Example .ts File with Interfaces and Utility Functions
1// types/user.ts2export interface User {3 id: string;4 name: string;5 email: string;6 createdAt: Date;7}8 9export function createUser(name: string, email: string): User {10 return {11 id: crypto.randomUUID(),12 name,13 email,14 createdAt: new Date(),15 };16}17 18// utils/format.ts19export function formatDate(date: Date): string {20 return date.toLocaleDateString('en-US', {21 year: 'numeric',22 month: 'long',23 day: 'numeric',24 });25}26 27export function validateEmail(email: string): boolean {28 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;29 return emailRegex.test(email);30}

What Is the .tsx File Extension?

The .tsx extension combines TypeScript with JSX (JavaScript XML), where the "X" specifically denotes JSX support. This extension is required when you want to use JSX syntax within TypeScript files--typically when writing React components or any UI-related code that includes JSX elements. According to React's official documentation, every file containing JSX must use the .tsx file extension, as it tells TypeScript that the file contains JSX that needs transformation.

Why .tsx Exists

The .tsx extension exists because TypeScript needs to parse JSX syntax differently than regular JavaScript. When you write JSX like <div>Hello</div> or <Button variant="primary">, TypeScript must transform this syntax into valid JavaScript function calls. The "X" in .tsx signals to the TypeScript compiler that JSX transformation rules should be applied to this file.

Without the .tsx extension, TypeScript would not recognize JSX syntax and would throw compilation errors. The extension also helps development tools like editors and IDEs provide appropriate syntax highlighting, type checking, and auto-completion for JSX elements. This clear distinction between .ts and .tsx files ensures that your development environment can accurately interpret and validate your code.

Example .tsx File with React Component
1// components/Button.tsx2interface ButtonProps {3 label: string;4 onClick: () => void;5 variant?: 'primary' | 'secondary';6}7 8export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {9 return (10 <button className={`btn btn-${variant}`} onClick={onClick}>11 {label}12 </button>13 );14}15 16// components/UserProfile.tsx17import { User } from '../types/user';18import { formatDate } from '../utils/format';19 20interface UserProfileProps {21 user: User;22}23 24export function UserProfile({ user }: UserProfileProps) {25 return (26 <div className="user-profile">27 <h2>{user.name}</h2>28 <p>Member since {formatDate(user.createdAt)}</p>29 <a href={`mailto:${user.email}`}>{user.email}</a>30 </div>31 );32}

The Technical Reason Behind Different Extensions

How TypeScript Handles JSX

The distinction between .ts and .tsx files stems from a fundamental parsing challenge: both use angle brackets < > for different purposes. In pure TypeScript, angle brackets create type assertions like <Type>value or generic type parameters like Array<string>. In React, angle brackets create JSX elements like <div> or <Component>. Without separate extensions, TypeScript's parser would be ambiguous about how to interpret these syntax elements.

When TypeScript processes a .tsx file, it applies JSX transformation rules and interprets <Component> as JSX elements that need to be compiled into React.createElement() calls. When processing a .ts file, the parser treats <Type> as type assertions or generic syntax. This separation allows TypeScript to accurately parse and compile your code without confusion between type-level and runtime-level syntax.

The TypeScript Handbook documents this behavior extensively, explaining how the compiler configuration and file extension work together to determine the correct parsing strategy for each file.

TypeScript Configuration for JSX Support
1// tsconfig.json2{3 "compilerOptions": {4 "target": "ES2020",5 "lib": ["DOM", "DOM.Iterable", "ESNext"],6 "module": "ESNext",7 "moduleResolution": "bundler",8 "jsx": "react-jsx",9 "strict": true,10 "esModuleInterop": true,11 "skipLibCheck": true12 },13 "include": ["src"]14}
When to Use .ts vs .tsx

Choose the right file extension for your code

Use .ts for Pure TypeScript

Utility functions, type definitions, data models, API clients, and custom hooks without JSX elements

Use .tsx for React Components

Any file containing JSX syntax, React components, or UI-related code that returns JSX elements

Use .ts for Business Logic

Extract complex logic into .ts files and import them into your .tsx components for better organization

Use .tsx for UI Rendering

Keep UI rendering logic in .tsx files while separating type definitions and utilities into .ts files

Best Practices for Organizing TypeScript and React Projects

Recommended Project Structure

A well-organized TypeScript and React project separates concerns effectively. Keep your types and interfaces in a dedicated types/ directory where they can be imported across your application. Place React components in a components/ folder, using .tsx extensions for files containing JSX. Organize utilities and helper functions in a utils/ directory, keeping them in .ts files for clean separation.

For larger applications, consider a feature-based folder structure where related components, hooks, types, and utilities are grouped together. This approach makes it easier to navigate your codebase and understand how different parts of your application connect. Using index files (index.ts) for clean barrel exports simplifies imports and keeps your component files focused on their primary responsibility.

The project structure also supports better testing practices. When business logic resides in separate .ts files, you can unit test that logic without rendering React components, leading to faster and more reliable tests. This separation also improves type checking performance, as TypeScript can process .ts files independently of your component tree. For comprehensive build setup guidance, see our guide on using Webpack with TypeScript.

Recommended Project Structure
1src/2├── components/3│ ├── Button/4│ │ ├── Button.tsx5│ │ ├── Button.types.ts6│ │ └── index.ts7│ ├── UserProfile/8│ │ ├── UserProfile.tsx9│ │ └── UserProfile.test.tsx10│ └── Card/11│ ├── Card.tsx12│ └── Card.styles.ts13├── hooks/14│ ├── useAuth.ts15│ ├── useLocalStorage.ts16│ └── useFetch.ts17├── types/18│ ├── user.ts19│ ├── common.ts20│ └── api.ts21├── utils/22│ ├── format.ts23│ ├── validation.ts24│ └── helpers.ts25├── services/26│ ├── api-client.ts27│ └── auth-service.ts28└── App.tsx

Common Questions About .ts and .tsx Extensions

Can I use .ts file for React components?

No, if a React component file contains JSX syntax (like <div>, <Component>, etc.), it must use the .tsx extension. Using .ts will result in compilation errors when JSX is encountered.

Do I need to install anything special for .tsx support?

You need to have TypeScript installed and properly configured. In your tsconfig.json, set "jsx": "react-jsx" or another valid JSX option. Install @types/react and @types/react-dom for type definitions.

Can I have a .tsx file without any JSX?

Yes, technically you can, but it's not recommended. The .tsx extension signals that JSX may be present. If you're writing pure TypeScript in a React project, use .ts to maintain clarity.

What happens if I use .ts instead of .tsx?

TypeScript will not recognize JSX syntax in .ts files. You'll get compilation errors like 'Unexpected token <' when the parser encounters JSX elements.

Conclusion

The distinction between .ts and .tsx file extensions in TypeScript is fundamental to working effectively with React and JSX. The .ts extension is used for pure TypeScript code without JSX, while .tsx is required when incorporating JSX syntax. This separation ensures proper parsing and compilation of your code, enables correct type checking, and helps maintain organized, scalable codebases.

As you build React applications with TypeScript, choosing the appropriate extension becomes second nature--but understanding the technical reasoning behind this convention strengthens your foundation as a developer. Following the patterns and best practices outlined in this guide will help you create maintainable, well-organized TypeScript projects that scale effectively. For maintaining code quality across your project, also explore our guide on linting TypeScript with ESLint and Prettier.

To learn more about building robust frontend applications, explore our React development services and TypeScript consulting offerings.

Sources

  1. TypeScript Handbook - JSX - Official documentation for JSX support in TypeScript, compiler options, and file extension requirements.
  2. React.dev - Using TypeScript - Official React guide for TypeScript integration, including TypeScript with React components.
  3. LogRocket - What is the difference between a .ts and .tsx file extension? - Practical developer guide with code examples showing when to use .ts vs .tsx.

Ready to Master TypeScript and React?

Build scalable, type-safe applications with our expert frontend development services.