What is a JSX file?
JSX (JavaScript XML) is a syntax extension for JavaScript that allows developers to write HTML-like markup directly within JavaScript code. Created by Facebook (now Meta) for React, JSX is not valid JavaScript by itself — it must be transpiled to regular JavaScript function calls by tools like Babel, SWC, or esbuild before browsers can run it. JSX provides a declarative, readable way to describe UI components and was a key innovation that made React’s component model so approachable.
React without JSX would require writing React.createElement('div', {className: 'box'}, children) for every element. JSX transforms this into the familiar <div className="box">{children}</div> syntax that most developers now consider natural.
How to open JSX files
- VS Code (Windows, macOS, Linux) — Syntax highlighting, Emmet, IntelliSense
- WebStorm (Windows, macOS, Linux) — Full React IDE support
- Vim/Neovim — With React/JSX plugins
- Any text editor — JSX files are plain UTF-8 text
Technical specifications
| Property | Value |
|---|---|
| Language | JavaScript + XML-like syntax extension |
| Transpiler | Babel, SWC, esbuild, Vite |
| Transpiles to | Plain JavaScript .js |
| Runtime | Browser (after bundling) or Node.js |
| Framework | React (primary), Preact, Solid.js |
| MIME type | text/jsx |
Common use cases
- React components: Building UI components for web applications
- React Native: Mobile app development for iOS and Android
- Server-side rendering: Next.js and Gatsby page components
- Component prototyping: Rapid UI development and iteration
- Static site generation: Frameworks like Astro (islands architecture)
JSX syntax example
function UserCard({ name, avatar, role }) {
return (
<div className="card">
<img src={avatar} alt={`${name}'s avatar`} />
<h2>{name}</h2>
<p>{role}</p>
{role === 'admin' && <span className="badge">Admin</span>}
</div>
);
}
// Usage
<UserCard name="Alice" avatar="/alice.png" role="admin" />
JSX rules: use className instead of class, htmlFor instead of for, all tags must be closed (<br /> not <br>), and expressions go in {curly braces}.
JSX vs TSX
.jsx uses plain JavaScript with no type checking. .tsx adds TypeScript’s static type system. For new projects, TypeScript (.tsx) is recommended — it catches prop type errors at compile time rather than at runtime. For rapid prototyping or smaller projects, .jsx has less boilerplate.
JSX transformation
Babel (or SWC) transforms JSX into JavaScript. With React 17’s automatic JSX transform, the output uses _jsx() from react/jsx-runtime instead of React.createElement(). This eliminates the need to import React from 'react' at the top of every file:
// Input JSX
const el = <h1 className="title">Hello</h1>;
// Compiled output (React 17+ automatic transform)
import { jsx as _jsx } from 'react/jsx-runtime';
const el = _jsx('h1', { className: 'title', children: 'Hello' });
React hooks in JSX files
import { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return (
<button onClick={() => setCount(c => c + 1)}>
Clicked {count} times
</button>
);
}
Hooks (useState, useEffect, useCallback, etc.) only work inside function components and must be called at the top level — never inside loops, conditions, or nested functions.
Linting and formatting
JSX projects typically use ESLint with eslint-plugin-react and eslint-plugin-react-hooks to catch common mistakes like missing dependency arrays in useEffect, or using array indexes as React key props. Prettier formats JSX with its standard JavaScript formatter and handles JSX-specific indentation correctly.