{"id":47992309,"url":"https://github.com/portwatcher/vue-godot","last_synced_at":"2026-04-04T11:49:46.498Z","repository":{"id":293441970,"uuid":"935854175","full_name":"portwatcher/vue-godot","owner":"portwatcher","description":"bridging Vue.js and Godot Engine for game UI and cross platform applications","archived":false,"fork":false,"pushed_at":"2026-02-25T10:29:57.000Z","size":4493,"stargazers_count":33,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2026-02-25T11:33:13.669Z","etag":null,"topics":["electron","flutter","godot","javascript","lynx","react-native","tauri","typescript","vue"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/portwatcher.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-20T06:00:20.000Z","updated_at":"2026-02-25T10:30:01.000Z","dependencies_parsed_at":"2025-05-15T11:34:42.152Z","dependency_job_id":null,"html_url":"https://github.com/portwatcher/vue-godot","commit_stats":null,"previous_names":["portwatcher/vue-godot"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/portwatcher/vue-godot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/portwatcher%2Fvue-godot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/portwatcher%2Fvue-godot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/portwatcher%2Fvue-godot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/portwatcher%2Fvue-godot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/portwatcher","download_url":"https://codeload.github.com/portwatcher/vue-godot/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/portwatcher%2Fvue-godot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31398770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electron","flutter","godot","javascript","lynx","react-native","tauri","typescript","vue"],"created_at":"2026-04-04T11:49:45.830Z","updated_at":"2026-04-04T11:49:46.475Z","avatar_url":"https://github.com/portwatcher.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vue Godot\n\nA small simple project that bridges Vue.js and Godot.\n\nThis project is for:\n\n- Write game UI using Vue.js\n- Write cross platform applications using Vue.js with Godot as the runtime\n\nThis project is far from production ready. follow me on [@juryxiong](https://x.com/juryxiong) for updates.\n\n```vue\n\u003ctemplate\u003e\n  \u003cHBoxContainer\u003e\n    \u003cButton :text=\"'Click me'\" @pressed=\"handleClick\"\u003e\u003c/Button\u003e\n    \u003cLabel :text=\"count\"\u003e\u003c/Label\u003e\n  \u003c/HBoxContainer\u003e\n\u003c/template\u003e\n\n\u003cscript setup lang=\"ts\"\u003e\n// Test.vue\nimport { ref } from 'vue'\n\nconst count = ref(1)\n\nconst handleClick = () =\u003e {\n  count.value = count.value + 1\n}\n\u003c/script\u003e\n```\n\n```ts\n// main.ts\nimport { createApp } from '@vue-godot/runtime-tscn'\nimport { Control } from 'godot'\nimport Test from './Test.vue'\n\nexport default class App extends Control {\n  _ready() {\n    const app = createApp(Test)\n    app.mount(this)\n  }\n}\n```\n\n![demo](./intro-medias/demo.gif)\n\n## How It Works\n\nvue-godot is a custom Vue renderer that targets Godot's scene tree instead of the DOM. The key pieces:\n\n- **`@vue-godot/runtime-tscn`** — A Vue custom renderer (`createRenderer` from `@vue/runtime-core`) that maps Vue operations to Godot node tree operations: `createElement` → `ClassDB.instantiate()`, `insert` → `add_child()`, `patchProp` → `el.set()` / signal `connect()`, etc.\n- **`@vue-godot/cli`** — A CLI tool (`vue-godot`) for vue-godot projects. Currently supports generating Vue `GlobalComponents` type augmentation from GodotJS typings so Volar provides autocomplete and type checking for Godot nodes in Vue templates.\n- **Vite** builds the Vue app as a CJS library (`dist/app.js`), with `godot` as an external. The Godot scene (`.tscn`) attaches this script to a `Control` node.\n- In the **Godot editor**, GodotJS runs `dist/app.js`. The `_ready()` method calls `createApp(Root).mount(this)`, and Vue takes over the subtree.\n\nUpper-cased tags in templates (e.g. `\u003cHBoxContainer\u003e`, `\u003cLabel\u003e`) are treated as custom elements and resolved at runtime via `ClassDB.instantiate(tag)`.\n\n## Repository Structure\n\n```\nvue-godot/\n├── packages/\n│   ├── runtime-tscn/       # Vue custom renderer for Godot\n│   └── cli/                # CLI tool: vue-godot gen-types, scaffolding, etc.\n├── apps/\n│   ├── v-model/             # Example: two-way binding with TextEdit\n│   ├── v-on/                # Example: event handling with @pressed\n│   └── template-ref/        # Example: template refs\n└── turbo.json               # Turborepo config\n```\n\nEach app has the following layout:\n\n```\napps/\u003cname\u003e/\n├── project.godot            # Godot project file\n├── app.tscn                 # Main scene — attaches dist/app.js to a Control node\n├── typings/                 # GodotJS-generated type declarations (godot*.gen.d.ts)\n│   └── godot.vue-components.gen.d.ts   # Generated by @vue-godot/cli\n├── vue/\n│   ├── vite.config.ts       # Vite config — builds vue/src/main.ts → dist/app.js\n│   ├── tsconfig.json        # Vue/Volar tsconfig (separate from Godot root tsconfig)\n│   └── src/\n│       ├── main.ts          # Entry: createApp(Root).mount(this)\n│       ├── *.vue            # Vue SFC components\n│       └── env.d.ts         # *.vue module declaration for TypeScript\n├── tsconfig.json            # Godot root tsconfig (excludes vue/)\n├── dist/                    # Build output (loaded by Godot at runtime)\n└── package.json\n```\n\n## Getting Started\n\n### Prerequisites\n\n- **Node.js** \u003e= 18\n- **GodotJS editor** — download from https://github.com/ialex32x/GodotJS-Build/releases\n\n\u003e **Note:** GodotJS 1.0.0-2 has a scene codegen bug where `SceneTSDCodeGen.make_path` doesn't strip `res://` from scene paths, producing `ERROR: Could not create directory: './typings/res:/'`. This was fixed on the [main branch](https://github.com/godotjs/GodotJS/blob/main/scripts/jsb.editor/src/jsb.editor.codegen.ts) (method renamed to `make_scene_path` with `res://` stripping) but no Godot 4.4 build includes the fix yet. The errors are harmless and don't affect runtime. To suppress them, go to **Editor → Editor Settings → search `GodotJS`** and set `codegen/generate_scene_dts` to `false`.\n\n### Install \u0026 Build\n\n```bash\nnpm install\nnpm run build          # builds all packages + apps via Turborepo\n```\n\n### Run an example\n\nOpen the GodotJS editor and open any app's `project.godot`, for example `apps/v-on/project.godot`. Press **F5** to run the scene.\n\n## Development Workflow\n\n### 1. Open the Godot project\n\nOpen one of the example apps (e.g. `apps/v-model/project.godot`) in the GodotJS editor. On first open, GodotJS auto-generates TypeScript declarations for all engine classes into the `typings/` directory (`godot0.gen.d.ts` … `godot8.gen.d.ts`, `godot.mix.d.ts`, etc.).\n\n### 2. Generate Vue component types\n\n```bash\ncd apps/v-model\nnpm run gen:types\n```\n\nThis runs `vue-godot gen-types`, which reads the Godot typings and produces `typings/godot.vue-components.gen.d.ts` — a `GlobalComponents` augmentation that gives Volar full autocomplete and type checking for Godot node tags in `.vue` templates.\n\nRe-run this whenever Godot typings are regenerated (e.g. after a Godot version upgrade).\n\n### 3. Write Vue components\n\nEdit `.vue` files under `vue/src/`. Use Godot node class names as tags directly in templates:\n\n```vue\n\u003ctemplate\u003e\n  \u003cHBoxContainer\u003e\n    \u003cTextEdit :text=\"text\"\u003e\u003c/TextEdit\u003e\n    \u003cLabel :text=\"text\"\u003e\u003c/Label\u003e\n  \u003c/HBoxContainer\u003e\n\u003c/template\u003e\n\n\u003cscript setup lang=\"ts\"\u003e\nimport { ref } from 'vue'\nconst text = ref('')\n\u003c/script\u003e\n```\n\n- **Props** map to Godot node properties (`:text`, `:visible`, `:size`, etc.)\n- **Events** map to Godot signals (`@pressed`, `@text_changed`, etc. via `v-on`)\n- All standard Vue features work: `ref()`, `computed()`, `watch()`, `v-if`, `v-for`, template refs, etc.\n\n### 4. Write the entry point\n\n`vue/src/main.ts` is the entry point. It creates a Vue app and mounts it onto a Godot `Control` node:\n\n```ts\nimport { createApp } from '@vue-godot/runtime-tscn'\nimport { Control } from 'godot'\nimport Test from './Test.vue'\n\nexport default class App extends Control {\n  _ready() {\n    const app = createApp(Test)\n    app.mount(this)\n  }\n}\n```\n\nThis class is attached to a `Control` node in the Godot scene (`.tscn` file).\n\n### 5. Build\n\n```bash\nnpm run build          # from repo root — builds everything\n# or\ncd apps/v-model \u0026\u0026 npm run build   # build a single app\n```\n\nVite compiles `vue/src/main.ts` into `dist/app.js` (CJS format, `godot` external). The Godot scene references this file.\n\n### 6. Run in Godot\n\nPress **F5** in the GodotJS editor. Godot loads `dist/app.js`, the `_ready()` method fires, and Vue renders its component tree into the Godot scene.\n\n### Iteration loop\n\n```\nEdit .vue / .ts  →  npm run build  →  F5 in Godot  →  see changes\n```\n\n## Creating a New App\n\n1. Copy an existing app directory (e.g. `apps/v-model`) to `apps/\u003cyour-app\u003e`\n2. Update `package.json` name field\n3. Update `project.godot` project name\n4. Open `apps/\u003cyour-app\u003e/project.godot` in the GodotJS editor to generate fresh typings\n5. Run `npm run gen:types` to generate Vue component types\n6. Edit `vue/src/` with your components\n7. `npm run build` and press **F5** in Godot\n\n## Packages\n\n| Package                   | Description                                          |\n| ------------------------- | ---------------------------------------------------- |\n| `@vue-godot/runtime-tscn` | Vue custom renderer for Godot scene tree             |\n| `@vue-godot/html`         | HTML-like Vue components built on Godot nodes        |\n| `@vue-godot/cli`          | CLI tool for vue-godot projects                      |\n\n### `@vue-godot/cli`\n\n```bash\nvue-godot \u003ccommand\u003e [options]\n```\n\n#### `create` / `integrate`\n\nBoth `create` (new project) and `integrate` (existing Godot project) accept a `--html` flag that configures `@vue-godot/html` automatically — setting up the Vite compiler config and plugin registration so lowercase HTML tags (`\u003cdiv\u003e`, `\u003cimg\u003e`, etc.) work as Godot-backed components with zero renaming.\n\n```bash\nvue-godot create my-app --html\nvue-godot integrate --html\n```\n\n#### `gen-types`\n\nGenerate Vue `GlobalComponents` type augmentation from GodotJS typings.\n\n```bash\nvue-godot gen-types [--typings \u003cdir\u003e] [--out \u003cfile\u003e] [--ancestor \u003cclass\u003e] [--vue-src \u003cdir\u003e]\n```\n\n| Option       | Default                                   | Description                                      |\n| ------------ | ----------------------------------------- | ------------------------------------------------ |\n| `--typings`  | `./typings`                               | Directory containing `godot*.gen.d.ts` files     |\n| `--out`      | `\u003ctypings\u003e/godot.vue-components.gen.d.ts` | Output file path                                 |\n| `--ancestor` | `Control`                                 | Base class — only descendants are included       |\n| `--vue-src`  | `./vue/src`                               | Vue source dir — generates `env.d.ts` shim there |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fportwatcher%2Fvue-godot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fportwatcher%2Fvue-godot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fportwatcher%2Fvue-godot/lists"}