What is a TSX file?
TSX (TypeScript + JSX) files combine TypeScript’s static type system with JSX syntax for writing React components. TSX provides compile-time type checking for both component props and state, reducing runtime errors in React applications. It is the recommended format for React components in any TypeScript project. When the TypeScript compiler (tsc) or a bundler like Vite encounters a .tsx file, it validates types and transforms the JSX syntax into React.createElement() calls before producing runnable JavaScript.
The .tsx extension (rather than .ts) signals to the compiler that the file may contain JSX angle-bracket syntax, which would otherwise be ambiguous with TypeScript’s generic syntax.
How to open TSX files
- VS Code (Windows, macOS, Linux) — Built-in TypeScript + React support via the TypeScript language service
- WebStorm (Windows, macOS, Linux) — Full IDE with refactoring and type inspection
- Vim/Neovim — With rust-analyzer or tsserver via LSP
- Any text editor — TSX files are plain UTF-8 text
Technical specifications
| Property | Value |
|---|---|
| Language | TypeScript + JSX syntax |
| Compiler | tsc (TypeScript Compiler) or SWC / esbuild |
| Transpiles to | JavaScript .js (or .jsx) |
| Type system | Static, structural (duck typing) |
| Config file | tsconfig.json |
| React version | Works with React 17+ (auto JSX transform) |
Common use cases
- React components: Type-safe UI components with validated props
- Next.js pages: Server and client components in the App Router
- Component libraries: Typed, reusable packages (e.g., shadcn/ui, Radix)
- Full-stack TypeScript: Shared types between frontend and backend API
TSX component example
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
export function Button({ label, onClick, variant = 'primary', disabled = false }: ButtonProps) {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
disabled={disabled}
aria-disabled={disabled}
>
{label}
</button>
);
}
TypeScript enforces that all required props are provided and that their types match. Passing a number where a string is expected is a compile-time error, not a runtime bug.
TSX vs JSX
| Feature | TSX | JSX |
|---|---|---|
| Type checking | ✅ Compile-time | ❌ Runtime only |
| IDE autocompletion | ✅ Strongly typed | Partial |
| Refactoring | ✅ Safe renames | Manual |
| Build step | ✅ Required (tsc/SWC) | ✅ Required (Babel) |
| Learning curve | Higher | Lower |
For new projects, TSX is the standard choice. The upfront investment in typing pays off significantly in larger codebases where prop changes ripple through many components.
Tooling and configuration
A minimal tsconfig.json for React + TSX:
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM"],
"jsx": "react-jsx",
"strict": true,
"moduleResolution": "bundler"
}
}
The "jsx": "react-jsx" setting uses the React 17+ automatic JSX transform, which removes the need to import React from 'react' at the top of every file.
Common TypeScript patterns in React
React.FC<Props>or direct prop typing for function componentsuseState<Type>()for typed stateuseRef<HTMLDivElement>(null)for typed DOM refsReact.ReactNodefor children that can be any renderable contentReact.CSSPropertiesfor inline style objects