What does the TSX to JSX converter strip?
It removes the TypeScript-only syntax that has no JavaScript runtime equivalent: parameter and variable type annotations (foo: string), return type annotations on functions (): Promise<X>, generic parameters on declarations and call sites (<T extends ...>), interface blocks, type aliases, enum declarations, as Type / as const assertions, the non-null ! operator, optional ? markers on parameters and properties, public/private/protected/readonly/override modifiers on class members, declare statements, and import type / export type lines. JSX syntax, runtime imports, and JavaScript expressions are preserved verbatim.
Is this a complete TypeScript-to-JavaScript compiler?
No. This is a regex-based stripper, not a parser. For a fully correct conversion that handles every edge case — nested generics, type predicates, satisfies, assertion functions, decorators, namespace blocks — use the official TypeScript compiler with isolatedModules: true and emitDeclarationOnly: false, or use Babel with @babel/preset-typescript and the onlyRemoveTypeImports flag. This tool is for quick one-off downgrades of a snippet, not for production transpilation pipelines.
Why would I need to convert TSX back to JSX?
Several real reasons: posting a minimal-repro to a JS-only sandbox like CodePen or JSFiddle that does not support TypeScript; sharing code in a tutorial aimed at JavaScript-only readers; downgrading a contribution to a project that still uses plain JavaScript; pasting an example into Stack Overflow under the [reactjs] tag where TypeScript would be off-topic; and forking a TypeScript example to wire into a JavaScript-only build pipeline you do not control.
Will the output run as-is?
Usually yes for straightforward components — props, state, event handlers, conditional rendering, and lists all survive the conversion. Watch for: complex generic constraints that the regex over-strips, type predicates (foo is Bar) that leave syntactic fragments, satisfies clauses, and conditional types in expression position. Run the output through a JSX-only linter or a quick Node REPL of the file before relying on it.
Does it preserve comments and import order?
Yes. JSDoc /** */ blocks, single-line // comments, and block /* */ comments are passed through untouched. Runtime imports (import React from "react") stay in place. Only `import type { X } from "..."` lines are removed because they have no JavaScript counterpart — if you used a default-import bundle (`import { type X, foo } from "..."`), the inline `type` keyword is dropped but the runtime import is preserved.
How are generics in JSX handled?
Generic parameters on function CALLS — foo<T>(arg) — are stripped to foo(arg) when followed by an opening parenthesis. JSX tags — <Component prop="..."/> — are preserved because the regex requires a `(` immediately after the closing `>`, which JSX does not have. Edge cases like <T,>(x) => ... in arrow function generics are handled by a dedicated rule that matches the arrow-fn ambiguous-paren pattern.
What about React.FC and component type annotations?
A signature like `const Card: React.FC<CardProps> = (props) => ...` becomes `const Card = (props) => ...` — the `: React.FC<CardProps>` annotation matches the variable-type rule and is dropped. The accompanying `interface CardProps { ... }` declaration is removed by the interface rule. The result is plain JSX with the same runtime behaviour minus the type-checking layer.
Is the code I paste sent to your servers?
No. Conversion runs entirely in JavaScript on your machine. Components containing API keys, proprietary types, internal naming, or unreleased features never leave your browser. Open DevTools → Network and click Convert to confirm — no requests are made.