Start with a project file
Place vexascript.json in your project directory. VexaScript searches from the input file or directory upward and uses the nearest configuration file. Relative paths in this file are resolved from the directory containing it.
{
"entrypoint": "src/main.vx",
"outDir": "dist",
"compilerOptions": {
"lib": ["es2025", "dom"],
"types": [],
"baseUrl": ".",
"jsxImportSource": "preact"
},
"importMappings": {
"@app/state": "src/state.vx"
},
"serveMappings": {
"public/assets": "assets"
}
}
The CLI reads the nearest package.json separately for runtime dependencies. Dependencies belong in package.json, not in vexascript.json.
Top-level options
| Option | Type | Purpose |
|---|---|---|
entrypoint |
string | The .vx or .ts entry file used when a CLI command receives a project directory. Required for directory builds, bundles, and native project builds; also used by serve when --bundle is omitted. |
outDir |
string | Output directory for project builds. The default is dist. A command-line --out value takes precedence. |
outputDir |
string | Alias for outDir. Prefer outDir in new projects. |
compilerOptions |
object | TypeScript-compatible options currently consumed by VexaScript. See the dedicated table below. |
importMappings |
object | Maps exact module specifiers to local source files for JavaScript and native compilation, module resolution, and editor navigation. |
imports |
object | Alias for importMappings. Prefer importMappings in new projects. |
nativeImports |
object | Adds or overrides module mappings only for the native C++ backend. |
globalSymbols |
object or string[] | Loads source files whose declarations should be available globally, without imports. |
serveMappings |
object or array | Publishes files or directories at public paths during serve and copies them into project build output. |
Compiler options
VexaScript currently reads the following properties from compilerOptions:
| Option | Type | Purpose |
|---|---|---|
lib |
string[] | Selects built-in declaration libraries. For example, ["es2025", "dom"] makes browser APIs available. |
types |
string[] | Loads ambient declaration packages such as node, react, or react-dom. Use an explicit empty array to disable types inherited from tsconfig.json. |
baseUrl |
string | Base directory for non-relative source imports. It is resolved relative to the configuration file that declares it. |
jsxFactory |
string | Function used to emit JSX elements, such as h. The default is React.createElement. |
jsxFragmentFactory |
string | Value used to emit JSX fragments, such as Fragment. The default is React.Fragment. |
jsxImportSource |
string | When set to "preact", VexaScript maps JSX emission to the classic h and Fragment factories. Automatic JSX runtime emission is not yet supported. |
Relationship with tsconfig.json
VexaScript also searches upward for the nearest tsconfig.json. Its compilerOptions provide defaults, while properties in vexascript.json.compilerOptions override matching properties. Top-level VexaScript options such as entrypoint, outDir, and serveMappings are read only from vexascript.json.
{
"compilerOptions": {
"lib": ["es2025", "dom"],
"types": ["node"],
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
}
}
Module mappings
importMappings maps an exact import specifier to a local source file. Both the specifier and target are strings; targets are resolved relative to vexascript.json.
{
"importMappings": {
"@app/config": "src/config.vx",
"myengine": "runtime/myengine-runtime.vx"
},
"nativeImports": {
"myengine": "native/myengine.vx",
"commander": "native/commander.vx"
}
}
JavaScript builds use importMappings. Native builds start with the same mappings and then apply nativeImports, so a native-specific entry can replace the target for the same specifier.
Global source files
Use globalSymbols for source files whose declarations should be visible without imports. The recommended object form accepts paths and an emit mode:
{
"globalSymbols": {
"paths": ["runtime/browser-globals.vx"],
"emit": "globalThis"
}
}
"globalThis"is the default. Global declarations are emitted ontoglobalThis."assume"makes declarations available to analysis while assuming that the runtime host provides the values.
The shorter array form, "globalSymbols": ["runtime/browser-globals.vx"], uses "globalThis". The object keys files and include are accepted as aliases for paths.
Static and served files
The recommended object form maps a source file or directory to a public path. Source paths are relative to vexascript.json; destination paths are relative to the served or built site root.
{
"entrypoint": "src/main.vx",
"serveMappings": {
"public/assets": "assets",
"node_modules/pixi.js/dist/pixi.js": "vendor/pixi.js"
}
}
vexa serve exposes these mappings directly. A directory build with vexa build . or vexa bundle . copies the same files into outDir.
The legacy array form remains supported:
{
"serveMappings": [
{ "from": "public/assets", "to": "assets" },
{ "from": "vendor/runtime.js", "to": "vendor/runtime.js" }
]
}
Common project shapes
Browser project
{
"entrypoint": "src/main.vx",
"outDir": "dist",
"compilerOptions": {
"lib": ["es2025", "dom"],
"types": []
},
"serveMappings": {
"public/assets": "assets"
}
}
Node.js project
{
"entrypoint": "src/main.vx",
"compilerOptions": {
"types": ["node"]
}
}
Preact project
{
"entrypoint": "src/main.vx",
"compilerOptions": {
"jsxImportSource": "preact",
"lib": ["es2025", "dom"],
"types": []
}
}
CLI precedence
Explicit command-line options take precedence over project defaults. In particular, --out, --jsx-factory, and --jsx-fragment-factory override the corresponding values from the project configuration for that invocation.
See the CLI guide for command-specific flags and the samples for complete projects.