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

  1. Open Window > Package Manager
  2. Click +Add package from git URL
  3. 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.git

Choose Your Workflow

OneJS provides two ways to run JavaScript:

JSRunnerJSPad
Best forProduction apps, team projectsQuick experiments, learning
Source codeExternal files (version-controllable)Inline in inspector
Live reloadYes (automatic on file save)No (manual Build)
SetupAuto-scaffolds on first PlayZero setup
Start with JSPad if you're exploring OneJS. Use JSRunner for real projects.

Option A: JSPad (Quick Experiments)

JSPad lets you write TSX directly in the inspector. No external files needed.

  1. Create a new GameObject
  2. Add the JSPad component
  3. You'll see starter code in the TextArea
  4. Click Build (installs dependencies on first run, then compiles)
  5. Enter Play Mode
That's it. Your UI appears in the Game view.

Edit and iterate

  1. Modify the code in the inspector
  2. Click Build again (or Build & Reload if already in Play Mode)
  3. Changes appear immediately
JSPad is self-contained—the built bundle is compressed and stored in the scene file. Great for demos, tests, and learning.

Option B: JSRunner (Production Apps)

JSRunner manages a proper project structure with external files—better for real development.

1. Add JSRunner to Your Scene

  1. Create a new GameObject (or use an existing one)
  2. Add the JSRunner component
  3. Enter Play Mode
On first Play mode, JSRunner auto-creates everything:
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 settings

The ~ 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 build

Tip: 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 watch

Now 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-react provides React components that map to UI Toolkit elements
  • useState is standard React—state works exactly like web React
  • render() mounts your component to __root, the root VisualElement
  • View, Label, Button create 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
No need to create separate PanelSettings assets or share them between instances.

Upgrading from V2?

V3 simplifies the workflow significantly:

V2V3
ScriptEngine prefab + Runner + BundlerSingle JSRunner component
Project-root App/ folderScene Folder convention (next to your scene)
Shared PanelSettingsPer-instance PanelSettings (auto-created)
npm run setup to initializeAuto-scaffolds on first Play
Multiple VSCode watch tasksSingle npm run watch
PreactReact 19
Separate Tailwind watcherBuilt-in (import "onejs:tailwind")
PuerTS backends (QuickJS/V8/Node)Native QuickJS (simpler, consistent)
The CS. namespace for C# interop works the same way.

Next Steps