AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
Shared Vite, Vitest, Capacitor, tsup, TypeScript and Biome configuration for browser games.
Developer toolsTypeScript · JavaScriptGitHub @jbcomOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Shared build conventions for browser games: Vite 8, Vitest browser testing, Capacitor, tsup, TypeScript and Biome configs
Taken from the repository README
Loading the full README.
Read the full README ↗Shared build conventions for browser games. One dependency gives a project its Vite 8 config, its Vitest unit and real-browser test fragments, a Capacitor config, a tsup library build, and the TypeScript and Biome base configs, so a dozen game repositories stop drifting apart.
base, Rolldown code-splitting groups for
heavy vendors (three.js, Rapier, Phaser, Tone.js) or your own vendor chunks, HMR
watch-ignore, and an optional @ alias.server.hostname keeps
server.androidScheme.tsconfig.base.json and biome.base.json to extend.pnpm add -D build-preset vite vitest @vitest/browser-playwright playwright game-harness
game-harness provides the browser test config in the quick start below.
tsup is an optional peer: install it only if you use build-preset/tsup.
// vite.config.ts
import { defineGamePreset } from "build-preset/vite";
import path from "node:path";
export default defineGamePreset({
appName: "my-game",
srcDir: path.resolve(import.meta.dirname, "src"),
heavyDeps: { three: true, rapier: true },
});
// vitest.browser.config.ts: browser tests come from game-harness, the owner of browser QA
import { defineBrowserTestConfig } from "game-harness/vitest";
import { defineConfig } from "vitest/config";
const browserTest = defineBrowserTestConfig({
include: ["tests/browser/**/*.browser.test.ts"],
});
export default defineConfig({
optimizeDeps: { include: browserTest.__optimizeDepsInclude ?? [] },
test: browserTest,
});
// tsconfig.json
{ "extends": "build-preset/tsconfig.base.json" }
// biome.json
{ "extends": ["build-preset/biome.base.json"] }
heavyDeps toggles fixed groups. A game that splits vendor code by when it loads names its own
chunks. In declaration order, the first chunk matching a module takes it; chunks outrank
heavyDeps:
defineGamePreset({
appName: "example-game",
chunks: {
three: ["three"], // the title preloads these three...
r3f: ["@react-three/fiber"],
drei: ["@react-three/drei"],
rapier: ["@react-three/rapier", "@dimforge/rapier3d-compat"], // ...the room loads these
post: ["@react-three/postprocessing", "postprocessing", "n8ao"],
tone: ["tone"],
},
});
A string is an npm package name; a RegExp is tested against the module id. See
the Vite page for the precedence rules.
| Import | Exports |
|---|---|
build-preset | Everything below except /tsup (a thin barrel; prefer the subpaths) |
build-preset/vite | defineGamePreset, staticRouteExport, StaticRouteExportOptions, HeavyDepsOptions, VendorChunks, ChunkPattern |
build-preset/vitest | defineUnitTest, defineBrowserTest, defaultBrowserLaunchArgs |
build-preset/capacitor | defineCapacitorPreset, mergeCapacitorConfig, androidVersionGradleSnippet |
build-preset/tsup | libraryBuild |
build-preset/tsconfig.base.json, build-preset/biome.base.json | Shared configuration to extends |
The build-preset init-android command prints the CI-parameterized versionName and
versionCode block to paste into android/app/build.gradle.
See the API reference for every option and the architecture notes for why the presets behave as they do.
defineBrowserTest and defaultBrowserLaunchArgs are deprecated: browser QA has one owner, and it
is game-harness (defineBrowserTestConfig from game-harness/vitest). They stay for existing
consumers and are removed in the next major.
defineBrowserTest is headed-only. It constructs the Vitest Playwright provider itself and puts
--mute-audio in provider.options.launchOptions.args, so a silent run does not depend on a
consumer remembering to copy a launch-argument array. It throws on a headless option and on any
hidden --headless Chromium argument. Muting the audio does not change a player's saved audio
preference: the consumer still asserts a non-persistent runtime mute route in its own tests.
| Supported | |
|---|---|
| Node.js | 22, 24 and 26 (CI verifies each on Linux; Windows on 26) |
| Vite | ^8.2.1 |
| Vitest | ^4.1.10 or ^5.0.0 |
@vitest/browser-playwright | ^4.1.10 or ^5.0.0, matching Vitest |
| Playwright | >=1.62.1 <2 |
| tsup (optional) | ^8.5.0 |
The Vitest 4 and Vitest 5 lines are both exercised by the packed-consumer smoke in CI.
mise install # Node 26 and pnpm 12, or `corepack enable`
pnpm install
pnpm verify # Biome, markdownlint, tsc, tests with coverage, build, publint, attw, packed-consumer smoke
pnpm docs:build # the Sourcey documentation site
See CONTRIBUTING.md. Releases are automated by Release Please and published to npm with provenance from GitHub Actions.