<img src="src/assets/bolt-express-darkmode.svg" alt="Bolt Express" title="Bolt Express" width="400" />

A lightning-fast boilerplate for building Express Addons in Svelte, React, or Vue built on Vite + TypeScript + Sass

![npm](https://img.shields.io/npm/v/bolt-express)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/hyperbrew/bolt-express/blob/master/LICENSE)
[![Chat](https://img.shields.io/badge/chat-discord-7289da.svg)](https://discord.gg/PC3EvvuRbc)

## Features

- Lightning Fast Hot Reloading on changes
- Setup with TypeScript Definitions for Express in Frontend, Backend, and Manifest
- Optimized Build Size
- Easy Smart Bundling in Frontend UI and Backend Code contexts
- Spin a up a new project in Svete, React, or Vue
- Easily configure in express.config.ts
- Easy Package to Zip archive with sidecar assets
- GitHub Actions ready-to-go for Zip Releases

## Backers

Huge thanks to our backers who have made this project possible!

### Founding Backers

_Founding backers have made substantial contribution to the project at the start which has made this project possible._

<a href="https://developer.adobe.com/fund-for-design/" target="_blank">
<img src="https://developer.adobe.com/fund-for-design/media_16349b44cedb9a674b4b4acee670cb09ec8e0e4b0.png?width=1200&format=pjpg&optimize=medium" style="border-radius:25px" alt="Express" title="Express" width="300" /></a>

...

If you're interested in supporting this open-source project, please [contact the Hyper Brew team](https://hyperbrew.co/contact/).

## Support

### Free Support

If you have questions with getting started using Bolt Express, feel free to ask and discuss in our free Discord community [Discord Community](https://discord.gg/PC3EvvuRbc).

### Paid Support

If your team is interested in paid consulting or development with Bolt Express, please [contact the Hyper Brew team](https://hyperbrew.co/contact/). More info on our [Custom Addon Development & Consulting Services](https://hyperbrew.co/landings/boost-development)

## Can I use Bolt Express in my free or commercial project?

Yes! Bolt Express is **100% free and open source**, being released under the MIT license with no attribution required. This means you are free to use it in your free or commercial projects.

We would greatly appreciate it if you could provide a link back to this tool's info page in your product's site or about page:

Bolt Express Info Page Link: https://hyperbrew.co/resources/bolt-express

**Built with Bolt Express** button graphics:

**PNG Files**

<div style="display:flex;gap:1rem;">
<a href="./src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_White_V01.png" target="_blank">
<img src="./src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_White_V01.png" width="200" /></a>

<a href="./src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_Black_V01.png" target="_blank">
<img src="./src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_Black_V01.png" width="200" /></a>

</div>

**SVG Files**

<div style="display:flex;gap:1rem;">
<a href="src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_White_V01.svg" target="_blank">
<img src="src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_White_V01.svg" width="200" /></a>

<a href="src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_Black_V01.svg" target="_blank">
<img src="src/assets/built-with-bolt-express/Built_With_BOLT_Express_Logo_Black_V01.svg" width="200" /></a>

</div>

## Prerequisites

- [Node.js 18](https://nodejs.org/en/) or later
- Package manager either
  - NPM (comes with Node.js)
  - [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) ( ensure by running `yarn set version classic` )
  - [PNPM](https://pnpm.io/installation) ( ensure by running `pnpm --version` )
- Express Desktop App

## Quick Start

**Create your new Bolt Express project (follow CLI prompts)**

- yarn - `yarn create bolt-express`
- npm - `npx create-bolt-express@latest`
- pnpm - `pnpm create bolt-express`

**Change directory to the new project**

- `cd project`

**Install Dependencies** (if not already done by create command)

- yarn - `yarn`
- npm - `npm i`
- pnpm - `pnpm i`

**Build the addon** (must run before `dev`, can also run after for panel to work statically without the process)

- yarn `yarn build`
- npm `npm run build`
- pnpm `pnpm build`

**Setup Keys for development** _(Only Once Per Dev Machine)_

> The first time you debug an Express Addon on a machine you need to setup auth keys by following the CLI prompts. Once you've complted this once with Bolt Express or directly with `@adobe/create-ccweb-add-on` you don't need to do it again on that machine.

- yarn `yarn cert`
- npm `npm run cert`
- pnpm `pnpm cert`

**Run the addon in hot reload mode for development**

> The first time you run `yarn dev` you will be promted to make a dev cert.
>
> - On Windows, press OK on the popup dialog.
> - On MacOS, enter your password in the CLI when prompted and press enter to create the cert.
>
> You won't need to do this in the future.

- yarn `yarn dev`
- npm `npm run dev`
- pnpm `pnpm dev`

**Bundle your addon** and specified assets from `copyZipAssets` to a zip archive in the `./zip` folder

- yarn `yarn zip`
- npm `npm run zip`
- pnpm `pnpm zip`

### Add Addon to Express

1. Open Express in your browser\* (Chrome, Edge, and chromium-based browsers require additional steps, see more below)
2. Open Document
3. Select Add-ons from left sidebar
4. Select "Your add-ons"
5. Toggle "Add-on testing"
6. With correct serve port number, check "I Understand..." and press "Connect"

#### Note on Chrome, Edge, and Chromium-based browsers

In order to test and debug on Chromium-based browsers including Chrome, Edge, Brave, and others, you must either allow "Acces other apps and services on this device" or disable "Local Access Restriction".

Route A: Allow local access (recommended)

- Launch your browser
- Navigate to express.adobe.com
- You will be prompted with a permission dialog reading: `express.adobe.com wants to access other apps and services on this device`.
- Press "Allow"
  - If you don't see a popup, set manually by selecting the Settings Icon (left of URL bar) > Site Settings > Apps on Device > Allow
- Continue with previous steps to load your addon

Route B: Disable Local Access Restriction (not recommended)

_\*It is important to turn this setting back on when you're not debugging to keep yourself secure._

- Go to `chrome://flags/#local-network-access-check` (some browsers use different prefixes)
- Set "Local Network Access Checks" to `Disabled`
- Restart Chrome
- Continue with previous steps to load your addon

More Details from Adobe: https://developer.adobe.com/express/add-ons/docs/guides/getting-started/local-development/known-issues-limitations#chrome-local-network-access-restriction

### Load and Debug Addon

1. Launch your addon by clicking on the icon of your Addon in the "In Development" section of "Your Add-ons"
2. Open the Dev Tools by right click > Inspect

### Start Coding

- Write frontend UI code in `src/main.svelte` / `src/main.tsx` / `src/main.vue`
- Write backend express code in `src-code/code.ts`

---

## Sending Messages between the Frontend and Backend

Bolt Express makes messaging between the frontend UI and backend code layers simple and type-safe.

### 1. Call Backend Functions from the Frontend

**Define the function** - `src-code/code.ts`

Write your functions on the backend.

```ts
const sandboxApi = {
  myFunction: (a: string, b: number) => {
    // do stuff
    return true;
  },
};
```

**Call the Function** - `src/main.svelte` / `src/main.tsx` / `src/main.vue`

Import the `sandbox` variable to call the sandbox functions from the frontend with full type-safety.

```ts
import { sandbox } from "./utils/utils";

const helloWorld = async () => {
  let result = await sandbox.myFunction("hello", 400);
  console.log(result);
};
```

### 2. Call Frontend Functions from the Backend

Write and export your functions in on the frontend.

**Define the function** - `src/utils/ui-apis.ts`

```ts
//* All exported functions are callable from the sandbox backend

const selectionChanged = () => {
  console.log("[UI] Selection Changed!");
};

const defaultExports = { selectionChanged };

export type UIAPIs = typeof defaultExports;
export default defaultExports;
```

**Call the Function** - `src-code/code.ts`

Call those functions in the sandbox backend with full type-safety.

```ts
//* Trigger Custom UI API functions with the uiAPis object

editor.context.on(constants.EditorEvent.selectionChange, () => {
  uiApis.selectionChanged();
});
```

---

### Info on Build Process

Frontend code is built to the `dist` directory.

The backend code is bundled into a single `code.js` file.

The `manifest.json` is generated from the `express.config.ts` file with type-safety. This is configured when running `yarn create bolt-express`, but you can make additional modifications to the `express.config.ts` file after initialization.
