From 423a4ee0e95ff9dbf3e5aa041edba267f514a262 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Mon, 10 Nov 2025 12:28:36 +0100 Subject: [PATCH 1/6] feat: Scaffold 'create-typegpu' Update pnpm-lock.yaml Add files Not private --- packages/create-typegpu/README.md | 1 + packages/create-typegpu/index.js | 3 +++ packages/create-typegpu/package.json | 33 ++++++++++++++++++++++++ packages/create-typegpu/src/index.ts | 26 +++++++++++++++++++ packages/create-typegpu/tsconfig.json | 5 ++++ packages/create-typegpu/tsdown.config.ts | 8 ++++++ 6 files changed, 76 insertions(+) create mode 100644 packages/create-typegpu/README.md create mode 100755 packages/create-typegpu/index.js create mode 100644 packages/create-typegpu/package.json create mode 100644 packages/create-typegpu/src/index.ts create mode 100644 packages/create-typegpu/tsconfig.json create mode 100644 packages/create-typegpu/tsdown.config.ts diff --git a/packages/create-typegpu/README.md b/packages/create-typegpu/README.md new file mode 100644 index 0000000000..b0bdeb853b --- /dev/null +++ b/packages/create-typegpu/README.md @@ -0,0 +1 @@ +# create-typegpu diff --git a/packages/create-typegpu/index.js b/packages/create-typegpu/index.js new file mode 100755 index 0000000000..b5585bdb14 --- /dev/null +++ b/packages/create-typegpu/index.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +import './dist/index.mjs'; diff --git a/packages/create-typegpu/package.json b/packages/create-typegpu/package.json new file mode 100644 index 0000000000..e65f4b36a0 --- /dev/null +++ b/packages/create-typegpu/package.json @@ -0,0 +1,33 @@ +{ + "name": "create-typegpu", + "type": "module", + "version": "0.0.0", + "description": "A CLI tool for bootstrapping TypeGPU projects.", + "license": "MIT", + "bin": { + "create-typegpu": "./index.js" + }, + "files": [ + "dist", + "index.js" + ], + "engines": { + "node": ">=20.0.0" + }, + "scripts": { + "dev": "tsdown --watch", + "build": "tsdown", + "test:types": "tsc", + "prepublishOnly": "npm run build" + }, + "dependencies": { + "arg": "^5.0.2", + "arktype": "catalog:", + "consola": "^3.4.0", + "execa": "^9.6.0" + }, + "packageManager": "pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67", + "devDependencies": { + "tsdown": "^0.16.1" + } +} diff --git a/packages/create-typegpu/src/index.ts b/packages/create-typegpu/src/index.ts new file mode 100644 index 0000000000..2f57abce00 --- /dev/null +++ b/packages/create-typegpu/src/index.ts @@ -0,0 +1,26 @@ +import { consola } from 'consola'; +import { execa } from 'execa'; + +type ProjectType = 'Vite' | 'React Native'; + +consola.box('Creating TypeGPU project...'); +const projectType = await consola.prompt('Project type:', { + type: 'select', + options: ['Vite', 'React Native'], +}) as ProjectType; + +const ProjectSetups = { + 'Vite': async () => { + await execa({ stdio: 'inherit' })`npm create vite`; + }, + 'React Native': async () => { + console.error('React Native setup not implemented yet'); + process.exit(1); + }, +}; + +// Bootstrapping the project +await ProjectSetups[projectType](); + +// Installing TypeGPU dependencies +await execa({ stdio: 'inherit' })`npm install typegpu`; diff --git a/packages/create-typegpu/tsconfig.json b/packages/create-typegpu/tsconfig.json new file mode 100644 index 0000000000..5f257dc0f0 --- /dev/null +++ b/packages/create-typegpu/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/create-typegpu/tsdown.config.ts b/packages/create-typegpu/tsdown.config.ts new file mode 100644 index 0000000000..489d886229 --- /dev/null +++ b/packages/create-typegpu/tsdown.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'tsdown'; + +export default defineConfig(() => ({ + entry: ['src/index.ts'], + target: 'node20', + minify: true, + plugins: [], +})); From 0b4fdf8dc459e7c86c19f407ed8eff6bac265034 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Tue, 7 Jul 2026 14:36:55 +0200 Subject: [PATCH 2/6] Redirect to @typegpu/cli Update pnpm-lock.yaml Add files Not private --- packages/create-typegpu/bin.mjs | 57 ++++++++++++++++++++++++ packages/create-typegpu/index.js | 3 -- packages/create-typegpu/package.json | 27 ++++------- packages/create-typegpu/src/index.ts | 26 ----------- packages/create-typegpu/tsdown.config.ts | 8 ---- pnpm-lock.yaml | 6 +++ 6 files changed, 72 insertions(+), 55 deletions(-) create mode 100644 packages/create-typegpu/bin.mjs delete mode 100755 packages/create-typegpu/index.js delete mode 100644 packages/create-typegpu/src/index.ts delete mode 100644 packages/create-typegpu/tsdown.config.ts diff --git a/packages/create-typegpu/bin.mjs b/packages/create-typegpu/bin.mjs new file mode 100644 index 0000000000..f7351650c6 --- /dev/null +++ b/packages/create-typegpu/bin.mjs @@ -0,0 +1,57 @@ +#!/usr/bin/env node +import { spawn } from 'node:child_process'; +import pkg from './package.json' with { type: 'json' }; + +/** + * Used to extract the version of `typegpu` that was used to + * trigger the CLI, which then allows us to download the latest + * version matching the major and minor of the `typegpu` package. + */ +const versionPattern = /^(\d+)\.(\d+)\.(\d+)/; + +const result = versionPattern.exec(pkg.version); +const [_, major, minor] = result; + +if (major === undefined || minor === undefined) { + throw new Error(`TypeGPU version doesn't match the expected major.minor.patch format`); +} + +/** + * Targeting the latest version with the same major and minor as `typegpu` + */ +const semver = `^${major}.${minor}.0`; + +function asyncSpawn(...args) { + return new Promise((resolve, _reject) => { + const child = spawn(...args); + + child.on('exit', (code, signal) => { + if (signal) { + process.kill(process.pid, signal); + process.exit(0); + return; + } + + resolve(code); + }); + }); +} + +(async () => { + const code = await asyncSpawn('npx', [`@typegpu/cli@${semver}`, ...process.argv.slice(2)], { + stdio: ['inherit', 'inherit', 'ignore'], + }); + + if (code !== 0) { + console.warn( + `Couldn't find @typegpu/cli version matching ${semver}, falling back to latest...`, + ); + // Fallback to latest + const code = await asyncSpawn('npx', [`@typegpu/cli@latest`, ...process.argv.slice(2)], { + stdio: 'inherit', + }); + process.exit(code ?? 0); + } + + process.exit(code ?? 0); +})(); diff --git a/packages/create-typegpu/index.js b/packages/create-typegpu/index.js deleted file mode 100755 index b5585bdb14..0000000000 --- a/packages/create-typegpu/index.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -import './dist/index.mjs'; diff --git a/packages/create-typegpu/package.json b/packages/create-typegpu/package.json index e65f4b36a0..4f1b00afcd 100644 --- a/packages/create-typegpu/package.json +++ b/packages/create-typegpu/package.json @@ -1,33 +1,24 @@ { "name": "create-typegpu", - "type": "module", "version": "0.0.0", "description": "A CLI tool for bootstrapping TypeGPU projects.", "license": "MIT", "bin": { - "create-typegpu": "./index.js" + "create-typegpu": "./bin.mjs" }, "files": [ - "dist", - "index.js" + "bin.mjs" ], - "engines": { - "node": ">=20.0.0" - }, + "type": "module", "scripts": { - "dev": "tsdown --watch", - "build": "tsdown", "test:types": "tsc", "prepublishOnly": "npm run build" }, - "dependencies": { - "arg": "^5.0.2", - "arktype": "catalog:", - "consola": "^3.4.0", - "execa": "^9.6.0" - }, - "packageManager": "pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67", "devDependencies": { - "tsdown": "^0.16.1" - } + "typescript": "catalog:types" + }, + "engines": { + "node": ">=20.0.0" + }, + "packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499" } diff --git a/packages/create-typegpu/src/index.ts b/packages/create-typegpu/src/index.ts deleted file mode 100644 index 2f57abce00..0000000000 --- a/packages/create-typegpu/src/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { consola } from 'consola'; -import { execa } from 'execa'; - -type ProjectType = 'Vite' | 'React Native'; - -consola.box('Creating TypeGPU project...'); -const projectType = await consola.prompt('Project type:', { - type: 'select', - options: ['Vite', 'React Native'], -}) as ProjectType; - -const ProjectSetups = { - 'Vite': async () => { - await execa({ stdio: 'inherit' })`npm create vite`; - }, - 'React Native': async () => { - console.error('React Native setup not implemented yet'); - process.exit(1); - }, -}; - -// Bootstrapping the project -await ProjectSetups[projectType](); - -// Installing TypeGPU dependencies -await execa({ stdio: 'inherit' })`npm install typegpu`; diff --git a/packages/create-typegpu/tsdown.config.ts b/packages/create-typegpu/tsdown.config.ts deleted file mode 100644 index 489d886229..0000000000 --- a/packages/create-typegpu/tsdown.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from 'tsdown'; - -export default defineConfig(() => ({ - entry: ['src/index.ts'], - target: 'node20', - minify: true, - plugins: [], -})); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f2fb169d7..e701a8436a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -484,6 +484,12 @@ importers: specifier: ^2.8.3 version: 2.8.3 + packages/create-typegpu: + devDependencies: + typescript: + specifier: npm:tsover@^6.0.2 + version: tsover@6.0.2 + packages/eslint-plugin: dependencies: '@typescript-eslint/utils': From c07313d5e81f65b6c0883ac1958f3e2da145acf9 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Thu, 9 Jul 2026 16:55:26 +0200 Subject: [PATCH 3/6] Update README and package.json --- packages/create-typegpu/README.md | 21 +++++++++++++++++++++ packages/create-typegpu/package.json | 14 +++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/create-typegpu/README.md b/packages/create-typegpu/README.md index b0bdeb853b..6650d8d27c 100644 --- a/packages/create-typegpu/README.md +++ b/packages/create-typegpu/README.md @@ -1 +1,22 @@ # create-typegpu + +This package is a proxy for the `@typegpu/cli`[https://github.com/software-mansion/TypeGPU/tree/main/packages/typegpu-cli], and allows you to +spin up new TypeGPU projects with the `npm create typegpu` command. + +```sh +npx @typegpu/cli@latest + +# Alternate ways to invoke the CLI: +npx typegpu@latest +npm create typegpu +``` + +## TypeGPU is created by Software Mansion + +[![swm](https://logo.swmansion.com/logo?color=white&variant=desktop&width=150&tag=typegpu-github 'Software Mansion')](https://swmansion.com) + +Since 2012 [Software Mansion](https://swmansion.com) is a software agency with +experience in building web and mobile apps. We are Core React Native +Contributors and experts in dealing with all kinds of React Native issues. We +can help you build your next dream product – +[Hire us](https://swmansion.com/contact/projects?utm_source=typegpu&utm_medium=readme). diff --git a/packages/create-typegpu/package.json b/packages/create-typegpu/package.json index 4f1b00afcd..52fbc3fcf0 100644 --- a/packages/create-typegpu/package.json +++ b/packages/create-typegpu/package.json @@ -1,8 +1,17 @@ { "name": "create-typegpu", - "version": "0.0.0", + "version": "0.0.1", "description": "A CLI tool for bootstrapping TypeGPU projects.", + "homepage": "https://typegpu.com", + "bugs": { + "url": "https://github.com/software-mansion/TypeGPU/issues" + }, "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/software-mansion/TypeGPU.git#main", + "directory": "packages/create-typegpu" + }, "bin": { "create-typegpu": "./bin.mjs" }, @@ -11,8 +20,7 @@ ], "type": "module", "scripts": { - "test:types": "tsc", - "prepublishOnly": "npm run build" + "test:types": "tsc" }, "devDependencies": { "typescript": "catalog:types" From 067400e7409f26474a894b4ff0e11d319cfc0868 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Thu, 9 Jul 2026 17:04:21 +0200 Subject: [PATCH 4/6] Fix tsconfig.json --- packages/create-typegpu/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-typegpu/tsconfig.json b/packages/create-typegpu/tsconfig.json index 5f257dc0f0..2f5845b1fb 100644 --- a/packages/create-typegpu/tsconfig.json +++ b/packages/create-typegpu/tsconfig.json @@ -1,5 +1,5 @@ { "extends": "../../tsconfig.base.json", - "include": ["src/**/*"], + "include": ["bin.mjs"], "exclude": ["node_modules", "dist"] } From 9c772590a29f22f4d50c246a25388b6fa2f36d32 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Thu, 9 Jul 2026 17:08:20 +0200 Subject: [PATCH 5/6] Always targeting the latest CLI --- packages/create-typegpu/bin.mjs | 40 ++++----------------------- packages/create-typegpu/package.json | 1 + packages/create-typegpu/tsconfig.json | 3 ++ pnpm-lock.yaml | 3 ++ 4 files changed, 12 insertions(+), 35 deletions(-) diff --git a/packages/create-typegpu/bin.mjs b/packages/create-typegpu/bin.mjs index f7351650c6..d626998324 100644 --- a/packages/create-typegpu/bin.mjs +++ b/packages/create-typegpu/bin.mjs @@ -1,27 +1,9 @@ #!/usr/bin/env node -import { spawn } from 'node:child_process'; -import pkg from './package.json' with { type: 'json' }; - -/** - * Used to extract the version of `typegpu` that was used to - * trigger the CLI, which then allows us to download the latest - * version matching the major and minor of the `typegpu` package. - */ -const versionPattern = /^(\d+)\.(\d+)\.(\d+)/; - -const result = versionPattern.exec(pkg.version); -const [_, major, minor] = result; - -if (major === undefined || minor === undefined) { - throw new Error(`TypeGPU version doesn't match the expected major.minor.patch format`); -} +// @ts-check -/** - * Targeting the latest version with the same major and minor as `typegpu` - */ -const semver = `^${major}.${minor}.0`; +import { spawn } from 'node:child_process'; -function asyncSpawn(...args) { +function asyncSpawn(/** @type {Parameters} */ ...args) { return new Promise((resolve, _reject) => { const child = spawn(...args); @@ -38,20 +20,8 @@ function asyncSpawn(...args) { } (async () => { - const code = await asyncSpawn('npx', [`@typegpu/cli@${semver}`, ...process.argv.slice(2)], { - stdio: ['inherit', 'inherit', 'ignore'], + const code = await asyncSpawn('npx', [`@typegpu/cli@latest`, ...process.argv.slice(2)], { + stdio: 'inherit', }); - - if (code !== 0) { - console.warn( - `Couldn't find @typegpu/cli version matching ${semver}, falling back to latest...`, - ); - // Fallback to latest - const code = await asyncSpawn('npx', [`@typegpu/cli@latest`, ...process.argv.slice(2)], { - stdio: 'inherit', - }); - process.exit(code ?? 0); - } - process.exit(code ?? 0); })(); diff --git a/packages/create-typegpu/package.json b/packages/create-typegpu/package.json index 52fbc3fcf0..188105e51f 100644 --- a/packages/create-typegpu/package.json +++ b/packages/create-typegpu/package.json @@ -23,6 +23,7 @@ "test:types": "tsc" }, "devDependencies": { + "@types/node": "catalog:types", "typescript": "catalog:types" }, "engines": { diff --git a/packages/create-typegpu/tsconfig.json b/packages/create-typegpu/tsconfig.json index 2f5845b1fb..a0d7c79db9 100644 --- a/packages/create-typegpu/tsconfig.json +++ b/packages/create-typegpu/tsconfig.json @@ -1,5 +1,8 @@ { "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": ["@types/node"] + }, "include": ["bin.mjs"], "exclude": ["node_modules", "dist"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e701a8436a..d756bba56c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -486,6 +486,9 @@ importers: packages/create-typegpu: devDependencies: + '@types/node': + specifier: ^24.10.0 + version: 24.10.0 typescript: specifier: npm:tsover@^6.0.2 version: tsover@6.0.2 From 697cbadd68d48f8d6d02ff224fecbafc424c3df3 Mon Sep 17 00:00:00 2001 From: Iwo Plaza Date: Thu, 9 Jul 2026 18:58:36 +0200 Subject: [PATCH 6/6] Review fixes --- packages/create-typegpu/README.md | 2 +- packages/create-typegpu/bin.mjs | 23 ++++++++++++++++------- packages/create-typegpu/package.json | 4 ++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/packages/create-typegpu/README.md b/packages/create-typegpu/README.md index 6650d8d27c..7cf1b84742 100644 --- a/packages/create-typegpu/README.md +++ b/packages/create-typegpu/README.md @@ -1,6 +1,6 @@ # create-typegpu -This package is a proxy for the `@typegpu/cli`[https://github.com/software-mansion/TypeGPU/tree/main/packages/typegpu-cli], and allows you to +This package is a proxy for the [`@typegpu/cli`](https://github.com/software-mansion/TypeGPU/tree/main/packages/typegpu-cli), and allows you to spin up new TypeGPU projects with the `npm create typegpu` command. ```sh diff --git a/packages/create-typegpu/bin.mjs b/packages/create-typegpu/bin.mjs index d626998324..902a719c0a 100644 --- a/packages/create-typegpu/bin.mjs +++ b/packages/create-typegpu/bin.mjs @@ -4,24 +4,33 @@ import { spawn } from 'node:child_process'; function asyncSpawn(/** @type {Parameters} */ ...args) { - return new Promise((resolve, _reject) => { + return new Promise((resolve, reject) => { const child = spawn(...args); child.on('exit', (code, signal) => { if (signal) { process.kill(process.pid, signal); - process.exit(0); return; } - resolve(code); + resolve(code ?? 0); + }); + + child.on('error', (err) => { + reject(err); }); }); } (async () => { - const code = await asyncSpawn('npx', [`@typegpu/cli@latest`, ...process.argv.slice(2)], { - stdio: 'inherit', - }); - process.exit(code ?? 0); + const npxCommand = process.platform === 'win32' ? 'npx.cmd' : 'npx'; + try { + const code = await asyncSpawn(npxCommand, ['@typegpu/cli@latest', ...process.argv.slice(2)], { + stdio: 'inherit', + }); + process.exit(code); + } catch (err) { + console.error('Failed to run @typegpu/cli via npx:', err); + process.exit(1); + } })(); diff --git a/packages/create-typegpu/package.json b/packages/create-typegpu/package.json index 188105e51f..cd1c29a849 100644 --- a/packages/create-typegpu/package.json +++ b/packages/create-typegpu/package.json @@ -20,14 +20,14 @@ ], "type": "module", "scripts": { - "test:types": "tsc" + "test:types": "tsc --p ./tsconfig.json --noEmit" }, "devDependencies": { "@types/node": "catalog:types", "typescript": "catalog:types" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" }, "packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499" }