jsx-window
v0.3.2
Published
Run JSX and TSX files as native desktop windows on Windows.
Maintainers
Readme
jsxx
jsxx runs .jsx, .tsx, .js, and .ts files as native Windows windows.
It packages a small Go + WebView2 host that transpiles your entry file with esbuild, opens it in a desktop window, supports live reload for external files, and preserves common React state across reloads.
Install
npm i -g jsx-windowOr run it without a global install:
bunx jsx-window .\app.jsxRequirements
- Windows 11 or Windows 10 with the Microsoft Edge WebView2 runtime installed
- Node.js 18+
Usage
jsxx .\app.jsx
jsxx .\app.tsx
jsxx C:\path\to\widget.ts
jsxx --eval "<h1>Hello</h1>"
jsxx --eval "export default function App() { return <div>Hello</div> }"
jsxx --eval "export default function App() { return <div>Hello</div> }" --loader jsx
jsxx --serve .\app.jsx
jsxx --serve --port 3000 .\app.jsx
"<h1>Hello</h1>" | jsxx --loader jsx
"export default function App() { return <div>Hello</div> }" | jsxx
"export default function App() { return <div>Hello</div> }" | jsxx --loader jsx
bunx jsx-window .\app.jsx
bunx jsx-window --eval "<h1>Hello</h1>"
bunx jsx-window --serve .\app.jsxWhat The Entry File Should Look Like
The entry file should default-export a React component. jsxx mounts that component into the window root.
import { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
return (
<main
style={{
minHeight: "100vh",
margin: 0,
padding: 32,
background: "#111827",
color: "#f9fafb",
}}
>
<h1>Hello from jsxx</h1>
<p>Count: {count}</p>
<button onClick={() => setCount((value) => value + 1)}>
Increment
</button>
</main>
);
}Expectations
- Default-export a component:
export default function App() { ... } - React hooks such as
useStateanduseReducerwork, and their state is preserved across hot reloads in common cases - Relative imports work for
.js,.jsx,.ts,.tsx, and.json - The file is transpiled with esbuild, so TypeScript syntax is fine, but full
tsctype-checking is not run - Inline mode is available through
--eval/-e; it uses the current working directory as the base for relative imports - For
--evaland stdin, a bare JSX expression like<h1>Hello</h1>is automatically wrapped into a default component - Piped stdin is also supported; it is treated like inline source and also resolves relative imports from the current working directory
--servestarts a local HTTP server instead of opening a desktop window and prints the URL to stdout--portand--hostcan be used with--serve; by default it serves on127.0.0.1and picks an available port
Current Limitations
- External
.cssimports are not loaded as real stylesheets in the current host path, so prefer inline styles, CSS-in-JS, or self-contained component styling - The entry is treated as a React app root, so a plain script file with side effects but no exported component is not the intended shape
- Inline mode is not file-watched, since there is no source file to reload from
- Stdin mode is also not file-watched
--servehot-reloads by fetching the newest bundle into the page; it does not preserve React state the way the desktop host can
Host Integration
jsxx exposes a few host behaviors that your app can use:
document.documentElement.requestFullscreen()maps to native window fullscreenmeta[name="theme-color"],--window-caption,--window-border, and--window-textcan influence the native title bar colors- Manual reload and file-watcher reload fetch the latest bundled source from the host, rather than reusing stale startup code
File Association
Register a right-click action for .jsx files:
jsxx --registerMake jsxx the default handler for .jsx files under your user account:
jsxx --register --set-default-associationFeatures
- Runs
.js,.jsx,.ts, and.tsxentry files - Uses a native Windows GUI executable, so Explorer launches do not open a terminal
- Preserves common React
useStateanduseReducerstate across hot reloads - Supports DOM-triggered fullscreen in the host window
- Dynamically colors the native title bar from page theme data
Notes
- TypeScript support uses esbuild transpilation, not full
tsctype-checking .jsxis also used by Adobe ExtendScript, so default file association may conflict with existing workflows- This package is Windows-only
