# app.json configuration
## Function
`app.json` is the desktop application configuration file for `bt_app`. It describes the application name, window, entry, run mode, icon, main script, and packaging resources.
`app.json` is the only configuration source. When `app.json` does not exist in the project root directory but `index.html` exists, `bt_app` will automatically write the default `app.json` before starting; `
` and custom labels in `index.html` will not overwrite the application configuration.
## Complete example
```json
{
"app": {
"id": "org.example.diary",
"name": "Diary",
"title": "My Diary",
"version": "1.0.0",
"description": "BT Desktop Diary Example",
"copyright": "Copyright 2026 BT",
"mode": "static",
"entry": "index.html",
"icon": "icon.ico",
"storage": "app",
"file_associations": [
{
"extensions": ["md", "markdown"],
"icon": "icons/markdown.ico",
"description": "Markdown Document",
"context_menu": "Open with Diary"
}
],
"main": "main.bt"
},
"window": {
"width": 900,
"height": 700,
"resizable": true,
"fullscreen": false,
"hide_titlebar": false,
"transparent": false,
"always_on_top": false
},
"dev": {
"watch": true,
"delay": 500,
"devtools": true,
"console": true
},
"resources": [
"app.json",
"index.html",
"icon.ico",
"main.bt",
"assets/**"
],
"exclude": [
"assets/test/**",
"assets/*.bak"
]
}
```
## app fields
| Field | Type | Required | Default value | Valid range or optional value | Description |
|---|---|---|---|---|---|
| ASCII letters, numbers, `_`, `-`, starting and ending with letters or numbers | Application identification that remains stable across versions. Used for WebView profile, credential and application data isolation when explicitly configured and should not be modified due to changes in display name or output file name. |
| `app.name` | string | No | `BTApp` | A single file name fragment; cannot contain path or Windows file name illegal characters | Application internal name, also the default packaging output file name. |
| `app.title` | string | no | `BT 桌面应用` | non-empty text | window title. The name of the application that users see is usually written here. |
| `app.version` | string | No | `1.0.0` | Non-empty text | Apply version and write BTR software information. |
| `app.description` | string | No | None | Non-empty text or omitted | Application description. `FileDescription` meta-information written to the exe when Windows packages it. |
| `app.copyright` | string | No | None | Non-empty text or omitted | Copyright statement. `LegalCopyright` meta-information written to the exe when Windows packages it. |
| `app.mode` | string | No | `static` | `static`, `server`, `remote` | Run mode. |
| `app.entry` | string | No | Determined by mode | `static` is the safe relative path within the project; `server` and `remote` are HTTP/HTTPS URL | window entry. `static` defaults to `index.html`, `server` defaults to `http://127.0.0.1:18280`, and `remote` defaults to `https://example.com`. |
| `app.icon` | string | No | Built-in icon | Safe relative `.ico` path within the project | Used for running window icons, BTR toolbar display and Windows packaging exe icons. |
| `app.storage` | string | No | `app` | `app`, `private`, `global` | WebView storage policy. `app` uses an independent persistent profile according to the application identity; `private` uses a unique temporary profile for each startup; `global` uses the old global shared profile. |
| `app.file_associations` | object[] | No | `[]` | See table below | Windows business file association list. Only registered by the packaged exe application; external BTR does not register the associations declared in it. |
| `app.main` | string/boolean/null | No | Automatically try `main.bt` | Safe relative to `.bt` path, `false`, empty string, `true` or `null` | Front-end `bt.call()` callable BT main script. The string indicates the specified script; `false` or an empty string indicates not to be executed; other default forms automatically search for `main.bt`. |
It is recommended to explicitly write `app.id` from the time of project creation. It is still compatible with the old behavior when not written: the runtime generates a default ID based on the current `app.name`, and continues to use the data location saved by name in the old version; once the stable ID is explicitly set, subsequent modifications to `app.name` or `app.title` will not change the application profile and data directory.
## app.file_associations field
Each association object can declare multiple extensions at the same time. After the packaged application is started, it will register itself as an open program with these extensions and add the resource manager right-click menu; the file path will be passed in as a startup parameter and can be read through `window.bt.app.args()`.
| Field | Type | Required | Default value | Valid range or optional value | Meaning |
|---|---|---|---|---|---|
| |
| `icon` | string | No | `app.icon` | Relative path within the project, only supports `.ico` files | File type-specific icons. The independent icon resource group of the exe is embedded when building, and the associated files in the resource manager use this icon; the right-click menu still displays the main application icon. |
| `description` | string | No | ` 文档` | Non-empty text, NUL not allowed | File type specification shown in Windows. |
| `context_menu` | string | No | `以 打开` | Non-empty text, NUL not allowed | File Explorer right-click menu text. |
```json
{
"app": {
"name": "M++",
"title": "M++",
"file_associations": [
{
"extensions": ["md"],
"icon": "markdown.ico",
"description": "Markdown Document",
"context_menu": "with M++ Open "
}
]
}
}
```
`file_associations[].icon` and `app.icon` have different functions: the former represents the file type icon, and the latter represents the application icon in exe, window and taskbar. The associated icon will be directly embedded in a single file exe, and there is no need to write additional `resources`; when omitted, the application main icon will continue to be reused, and it is compatible with old configurations.
The Windows association is written as `HKEY_CURRENT_USER\\Software\\Classes`, does not require administrator rights, and will not modify other users. The system will respect default apps that the user has explicitly selected in Windows settings; in this case, the right-click menu and "Open with" will still appear, and the user can set the new app as the default in the system settings. bt_app does not delete the signature-protected `UserChoice`, nor does it snatch back other default programs that the user subsequently selected on each launch.
## window field
| Field | Type | Required | Default value | Description |
|---|---|---|---|---|
| `window.width` | number | No | `800` | The initial width of the main window, in logical pixels. Writing `0` will fall back to the default value. |
| `window.height` | number | No | `500` | The initial height of the main window, in logical pixels. Writing `0` will fall back to the default value. |
| `window.resizable` | boolean | No | `true` | Whether to allow the user to resize the window. |
| `window.fullscreen` | boolean | No | `false` | Whether to start in full screen. |
| `window.hide_titlebar` | boolean | No | `false` | Whether to hide the system title bar. After hiding, the page itself needs to provide interactions such as dragging and closing; Windows without title bar windows will close the system shadow that produces a 1px white border. |
| `window.transparent` | boolean | No | `false` | Whether to enable both native window and WebView transparent backgrounds when creating. When set to `true`, `hide_titlebar: true` must be set at the same time; the application must be restarted after modification, and hot reloading will not switch the transparent state. |
| `window.always_on_top` | boolean | No | `false` | Whether to keep the window on top, suitable for floating tools, monitoring panels and other scenarios. |
When the main window is started, the WebView will be created in a borderless, shadowless and hidden state. After the non-transparent page starts loading, bt_app's built-in borderless loading animation will be displayed; after the first page is loaded, bt_app will apply the final border and system projection corresponding to `hide_titlebar`. The transparent window will not draw a rectangular loading background, but will remain hidden until the first frame of the page is completed. This timing is handled uniformly by the runtime, which prevents the Windows non-client area borders and the default white background of WebView from flashing before the first frame of the page. There is no need to create an additional startup mask for the project page.
### Transparent window
Transparent window is suitable for floating tools, rounded corner panels, desktop widgets and PNG interfaces with Alpha channel. It is not a runtime API, but a window creation time configuration:
```json
{
"window": {
"width": 320,
"height": 180,
"resizable": false,
"fullscreen": false,
"hide_titlebar": true,
"transparent": true,
"always_on_top": true
}
}
```
The page root node must remain transparent, and only let the actual interface container draw the background and rounded corners:
```css
html,
body {
margin: 0;
width: 100%;
height: 100%;
background: transparent;
}
.app-shell {
width: 100%;
height: 100%;
border-radius: 24px;
background: rgba(24, 28, 42, 0.92);
}
```
`transparent: true` will turn off the rectangular native shadow, the shadow needs to be drawn by HTML/CSS and reserve transparent margins within the window size. PNG and HTML elements can use semi-transparent pixels; fully transparent rounded corners still belong to the hit range of the native rectangular window and will not automatically click through to the underlying application.
## dev field
| Field | Type | Required | Default value | Description |
|---|---|---|---|---|
| `dev.watch` | boolean | No | `true` | Whether to monitor resource changes and automatically refresh the page when the development directory is running. The packaged Bundle does not take effect when running. |
| `dev.delay` | number | No | `500` | Anti-shake time after file change, in milliseconds. Saving multiple files continuously will only refresh once. |
| `dev.devtools` | boolean | No | `false` | Whether to allow opening the WebView developer tools. After opening, you can press `F12` or `Ctrl+Shift+I` to open it, or you can call `window.bt.window.open_devtools()`. It is recommended to enable it only during the development stage; hot reloading of file changes will not automatically pop up the developer tools. |
| `dev.console` | boolean | No | `true` | Whether to enable the debug console. When packaged, it is `false`, which will change the Windows exe to a GUI subsystem, and the console will not pop up when double-clicked. |
Development mode supports `F5`, `Ctrl+R` and `Cmd+R` to refresh the current page. When `dev.watch=true` is used, the page will be automatically refreshed after the files hit by `resources - exclude` are saved, added, deleted or renamed. `dev.watch=false` will not monitor normal resource changes, but it will still monitor `app.json` so that it can automatically recover after modifying the configuration. `window.transparent` affects both native windows and WebView, and can only be applied when the window is created; `bt_app` needs to be restarted after changing this field.
When the development directory encounters `app.json` parsing failure, missing entry files, missing `app.main`, or abnormal script execution, a unified error page will be displayed in the window and continue to monitor file changes; it will be automatically reloaded after repair. The hot reload error status will inherit the console settings in the last effective configuration, and the console will not be forced to pop up due to entering the error page.
## resources field
| Field | Type | Required | Default value | Description |
|---|---|---|---|---|
| `resources` | string[] | No | |
| `exclude` | string[] | No | `[]` | Resource rules that exclude packaging and development monitoring, have a higher priority than `resources`. |
will also automatically complete necessary resources when building:
- `app.json` will be automatically added when `app.json` exists in the current directory.
- `static` mode automatically adds the entry file pointed to by `app.entry`.
- `app.main` If `main.bt` exists in automatic mode, `main.bt` will be added automatically.
- This script is automatically added when the `app.main` string is specified.
- The main script is not required when `app.main` is `false` or an empty string; `main.bt` remaining from `resources` in the old configuration will be skipped if the file does not exist.
- Automatically add `server.bt` when `server.bt` exists in the current directory.
- Automatically add icon files when `app.icon` is configured.
The final resource collection is calculated according to `resources - exclude`, which is used for both packaging and development mode file monitoring. The `dist/` build output directory will never enter the resource product. `resources` and `exclude` can only write relative paths within the project, not absolute paths, and cannot include `..`. If ordinary files do not exist, packaging will fail; ordinary directories will recursively collect files in the directory; `assets/**` will recursively collect files in the directory.
## The default generated app.json
project root directory does not have `app.json`, but when `index.html` exists, the following default configuration will be generated: `app.json` in the
```json
{
"app": {
"id": "org.btlang.bt_app",
"name": "BT-APP",
"title": "BT-APP",
"version": "1.0.0",
"description": " BT desktop software ",
"copyright": "Copyright 2026 BT",
"mode": "static",
"entry": "index.html",
"storage": "app",
"main": "main.bt"
},
"window": {
"width": 800,
"height": 500,
"resizable": true,
"fullscreen": false,
"hide_titlebar": false,
"transparent": false,
"always_on_top": false
},
"dev": {
"watch": true,
"delay": 500,
"devtools": true,
"console": true
},
"resources": [
"app.json",
"index.html",
"assets/**"
],
"exclude": []
}
```
default configuration points to `main.bt`. If `main.bt` is not already in the directory, the runner will create an empty file to ensure that the project can be started directly. The default resources will include `assets/**`, which is suitable for common Vue/Vite build products. When you need to package other directories or files, please manually write them to `resources`. bt_app no longer automatically scans resources from HTML tags.
## mode running mode
### static
This mode is a static HTML loading method, and `app.entry` needs to be configured as the entry HTML file path, such as index.html.
### server
This mode will execute the `server.bt` script in the current directory and start the Web service. `app.entry` needs to be configured with the complete URL of the Web service, such as `http://127.0.0.1:18280`.
Tip: Please ensure that the `server.bt` script file exists and the BT Web service can be started correctly.
### remote
This mode will directly open the remote URL, and `app.entry` needs to be configured as the remote URL, such as `https://example.com`.
### Running mechanism
The above three running modes will automatically execute the `app.main` script in the current directory and inject the `window.bt` object for interaction with the BT script.
- This script will not be executed if `app.main` is configured as `false`.
- If the `app.main` configuration does not exist, automatically find the `main.bt` script in the current directory and execute it.
## Notes
- `app.name` and `app.title` are different: `name` is the file name of the packaged output, and `title` is the title of the program window.
- `app.icon` only accepts icon files in `.ico` format.
- `app.file_associations[].icon` also only accepts `.ico` files within the project; the build will fail if the file does not exist.
- `app.file_associations` is only registered when a Windows packaged application starts; simply executing `bt_app.exe build` does not modify the development machine's file associations.
- `window.transparent=true` must match `window.hide_titlebar=true`, and the background of `html` and `body` is set to `transparent` by the page.
- `index.html` only serves as the page entry and does not assume configuration responsibilities.