Quick Start
Get OneJS running in under 5 minutes.
Requirements
- Unity 6.3 or later
- Node.js 18+ (for TypeScript compilation)
Install OneJS
Option 1: Unity Package Manager
- Open Window > Package Manager
- Click + → Add package from git URL
- Enter:
https://github.com/Singtaa/OneJS.git#onejs-v3
Option 2: Clone to Assets
cd YourProject/Assets
git clone -b onejs-v3 https://github.com/Singtaa/OneJS.gitChoose Your Workflow
OneJS provides two ways to run JavaScript:
| JSRunner | JSPad | |
|---|---|---|
| Best for | Production apps, team projects | Quick experiments, learning |
| Source code | External files (version-controllable) | Inline in inspector |
| Live reload | Yes (automatic on file save) | No (manual Build) |
| Setup | Auto-scaffolds on first Play | Zero setup |
Option A: JSPad (Quick Experiments)
JSPad lets you write TSX directly in the inspector. No external files needed.
- Create a new GameObject
- Add the JSPad component
- You'll see starter code in the TextArea
- Click Build (installs dependencies on first run, then compiles)
- Enter Play Mode
Edit and iterate
- Modify the code in the inspector
- Click Build again (or Build & Reload if already in Play Mode)
- Changes appear immediately
Option B: JSRunner (Production Apps)
JSRunner manages a proper project structure with external files—better for real development.
1. Add JSRunner to Your Scene
- Create a new GameObject (or use an existing one)
- Add the JSRunner component
- Enter Play Mode
Assets/Scenes/YourScene/
└── MainUI_abc123/ # Instance folder
├── MainUI~/ # Working directory (~ = Unity ignores)
│ ├── index.tsx # Your entry point
│ ├── package.json
│ ├── tsconfig.json
│ └── esbuild.config.mjs
├── app.js.txt # Built bundle (output from esbuild)
└── PanelSettings.asset # Auto-created UI settingsThe ~ suffix tells Unity to ignore the folder, so npm packages don't trigger asset imports. You should see "OneJS is good to go!" in the console.
2. Install Dependencies & Build
Exit Play Mode, then open a terminal:
cd Assets/Scenes/YourScene/MainUI_abc123/MainUI~
npm install
npm run buildTip: Use the Open Terminal button in the JSRunner inspector to quickly open a terminal at the correct path.
3. Run Your App
Enter Play Mode again. Your UI now renders from the built bundle.
4. Enable Live Reload
For rapid iteration, start watch mode in your terminal:
npm run watchNow when you edit index.tsx, esbuild rebuilds automatically. JSRunner detects the changed app.js.txt and hot-reloads—no need to exit Play Mode.
Your First UI
Replace the contents of your entry file (or JSPad code) with:
import { render, View, Label, Button } from "onejs-react"
import { useState } from "react"
function Counter() {
const [count, setCount] = useState(0)
return (
<View style={{ padding: 20, alignItems: "flex-start" }}>
<Label text={`Count: ${count}`} style={{ fontSize: 24, marginBottom: 10 }} />
<Button text="Increment" onClick={() => setCount(c => c + 1)} />
</View>
)
}
render(<Counter />, __root)Build (or click Build for JSPad, then enter Play Mode). Click the button. The count updates.
What Just Happened?
onejs-reactprovides React components that map to UI Toolkit elementsuseStateis standard React—state works exactly like web Reactrender()mounts your component to__root, the root VisualElementView,Label,Buttoncreate real UI Toolkit elements
Calling C# Code
Access any C# API through the CS global:
function DebugButton() {
const handleClick = () => {
CS.UnityEngine.Debug.Log("Button clicked!")
const time = CS.UnityEngine.Time.time
console.log(`Time: ${time}`)
}
return <Button text="Debug" onClick={handleClick} />
}The CS proxy gives you access to all Unity APIs, your game code, and third-party libraries.
Customizing Panel Settings
Both JSRunner and JSPad create their own PanelSettings automatically. You can tweak settings directly in the inspector:
- Scale Mode: How UI scales with screen size
- Reference Resolution: Design resolution for scaling
- Sort Order: Layer ordering for multiple UI panels
Upgrading from V2?
V3 simplifies the workflow significantly:
| V2 | V3 |
|---|---|
| ScriptEngine prefab + Runner + Bundler | Single JSRunner component |
Project-root App/ folder | Scene Folder convention (next to your scene) |
| Shared PanelSettings | Per-instance PanelSettings (auto-created) |
npm run setup to initialize | Auto-scaffolds on first Play |
| Multiple VSCode watch tasks | Single npm run watch |
| Preact | React 19 |
| Separate Tailwind watcher | Built-in (import "onejs:tailwind") |
| PuerTS backends (QuickJS/V8/Node) | Native QuickJS (simpler, consistent) |
CS. namespace for C# interop works the same way.
Next Steps
- C# Interop: Deep dive into calling C# code
- Styling: Learn the style system
- Components: Explore all available components