Skip to content
Kunkun

Custom UI Command

Custom UI command is just a web app. You can use any front-end framework (React, Vue, Angular, Svelte, etc) to build arbitrarily complex UI, as long as it can be built into static files (e.g. SSG, CSR, but not SSR).

For example, you can create a transparent window with a 3D model floating on your screen.

Here is an example of KK’s git-skyline extension,

KK provides multiple scaffolding templates to help you get started with your extension development.

Supported templates:

  • React
  • Next.js
  • Vue
  • Nuxt.js
  • Svelte
  • SvelteKit

Installation

Terminal window
npm init kunkun@latest # choose a template

After creating a template project, you need to edit package.json.

You don’t have to use the template provided, you can always start from scratch with pnpm create vite.

You can also convert an existing web app into a KK extension by adding kunkun config to package.json, with a few lines of config.

Development

Add Dev Extension to Kunkun

Kunkun needs to know where your extension is located in order to load it. It’s very easy to add an extension for development.

KK provides a built-in command: Add Dev Extension. Open it, on the page you can pick the extension folder. KK will register the path to the extension.

Now go back to the main search in home page, you should see the extension loaded. Dev extensions should have a DEV tag.

Modern frontend frameworks all use dev server in development for HMR, so we need to load from dev server URL rather than static files during development to take advantage of HMR. The development experience will be the same as developing a web app.

There is a built-in command: Toggle Dev Extension Live Load Mode. After turning it on, you will see a Live badge on the dev extension command. KK will load the extension from the dev server URL, which is "devMain" in package.json.

Also see Load Mode Section for more details.

Edit Manifest

KK uses package.json to define an extension.

See Manifest for more details.

You need to edit the name, description, identifier and icon of your extension.

customUiCmds

Sample Config

package.json
"kunkun": {
...
"customUiCmds": [
{
"main": "/",
"dist": "build",
"devMain": "http://localhost:5173/dev-extensions/template-ext-sveltekit/build",
"name": "Sveltekit Template Home Page",
"cmds": []
},
{
"main": "about",
"dist": "build",
"devMain": "http://localhost:5173/dev-extensions/template-ext-sveltekit/build/about",
"name": "Sveltekit Template About Page",
"cmds": []
}
],
...
}
  • dist is the build output folder.
    • For Vite, it is dist.
    • For SvelteKit, it is build.
    • For Next.js, it is out.
  • devMain is the development server URL.
  • name is the name of the command.

Permissions

KK provides many APIs within @kksh/api package. See API Docs for more details.

Most of them requires adding corresponding permissions in package.json.

For example, if you want to read clipboard text, you need to add clipboard:read-text permission in package.json, under kunkun.permissions field.

See Extension Permissions for a full list of permissions, and API docs for each API to see how to add permissions.

Some permissions are just a single string, some are scoped permissions.

Start Coding

It is recommended to use pnpm for development because when the extension is built in our CI, it is also built with pnpm.

Developing custom command is the same as developing a web app, HMR is supported.

Load Mode

Each custom UI command can have a devMain URL. This is the URL of the development server.

To enable dev mode, toggle setting: Settings -> General -> Dev Extension Load Mode to Development Mode.

Or simply use the builtin command: Toggle Dev Extension Live Load Mode

When dev mode is enabled, you should see Live badge beside the extension commands in KK, and KK will load the devMain URL from your development server.

When mode is Production Mode, KK loads built extension from main field in package.json.

For example, given the config above, it loads build/index.html and build/about.html.

Helper Buttons

Custom command by default injects some buttons (back button, move button and refresh button) on top of your extension.

They are useful when your extension is not ready yet. Without these buttons, you may not be able to navigate back to the main menu or move the app window.

See Iframe UI API, for how to move or hide these buttons.

Theme

The scaffolded project uses @kksh/react or @kksh/vue or @kksh/svelte as the UI component library.

When these libraries, you can easily keep your extensions’ theme consistent with KK.

import { ui } from "@kksh/api/ui/iframe"
import { updateTheme } from "@kksh/vue"
// or
import { updateTheme } from "@kksh/react"
// or
import { updateTheme } from "@kksh/svelte"
ui.getTheme().then((theme) => {
updateTheme(theme)
})

Window Customization

Under uiCmds field, each UI command can have custom window style. All Tauri window styles are supported. You can read more in Tauri’s documentation. The attributes are passed to WebviewWindow class from Tauri to create a Window.

Go to Developer/Manifest Doc to see all avaialble window styles with intellisense in the code playground. In Sample Package JSON, in a UI Command, type double quote in a window object. Then intellisense will display all available window styles.

...
"customUiCmds": [
"window": {
"titleBarStyle": "overlay"
},
...
]
...

Advanced Usage

Although I previously mentioned that KK supports any SSG/CSR web apps as extensions, this doesn’t mean you can’t run a web server in the extension.

If you request shell permission in the manifest file, you can run a web server process in the extension (e.g. with Node, Bun, Deno runtime if installed locally, read more about runtime) and communicate with the frontend. You can then implement pretty much anything you want.

Verify

To verify the extension, you need to build it and run the verification command.

To make sure the build environment is consistent, docker is required to run the build command.

Terminal window
npx @kksh/cli build # requires docker
npx @kksh/cli verify --publish

These commands verify whether the extension can be loaded and published to the extension store.

To verify the functionality in production build,

  1. Set Dev Extension Load Mode to Production Mode in settings, general tab.

  2. Run npm run build

  3. Try to load the dev extension in KK, i.e. Search for your dev extension and select it to see if the UI can be loaded.

  4. Make sure files field in package.json only includes necessary files. e.g. "files": ["dist"].

  5. Run npm pack to generate a tarball file.

    • Decompress the tarball file to see if only necessary files are included.
  6. Go to settings page, developer tab, drag and drop the tarball file to install the extension.

    • The tarball file is decompressed to the dev extension path.
    • You may want to change the dev extension path as the new extension will be installed in the dev extension path as well, where your dev project is. And 2 extensions with the same identifier will be loaded.
  7. Check to see if the extension UI can be loaded in KK.

Publish

For now, send a PR to KunkunExtensions. Add the source code in extensions/ folder of this repo.

To update the extension and republish, just update the version in package.json and send a PR again.

When the version is updated, CI will auto publish the extension to the extension store.