# How to Build and Package Nautilus Wallet for Chrome and Firefox Extensions

> Learn to build and package Nautilus Wallet for Chrome and Firefox extensions. Set environment variables and run build scripts to generate browser extensions in dist/

- Repository: [Nautilus Team/nautilus-wallet](https://github.com/nautls/nautilus-wallet)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Building Nautilus Wallet requires setting three environment variables—`NETWORK`, `TARGET`, and `MODE`—before running the Vite-based build scripts defined in [`package.json`](https://github.com/nautls/nautilus-wallet/blob/main/package.json), which generate browser-specific extensions in the `dist/` directory ready for packaging.**

Nautilus Wallet is a Vite-powered web extension that supports both Chrome and Firefox browsers across Mainnet and Testnet networks. Understanding the build procedure is essential for developers who need to package the extension for distribution through the Chrome Web Store or Mozilla Add-ons. This guide walks through the environment configuration, build scripts, and manifest generation process based on the actual source code in the `nautls/nautilus-wallet` repository.

## Understanding the Build Environment Variables

The build pipeline relies on three critical environment variables consumed by Vite during the compilation process. These variables determine the target blockchain network, browser platform, and build mode.

### NETWORK, TARGET, and MODE Configuration

- **NETWORK**: Specifies `"mainnet"` or `"testnet"` to select the blockchain network. Defaults to `"mainnet"` if unset.
- **TARGET**: Defines the browser platform as `"chrome"` or `"firefox"`. Defaults to `"chrome"` if unset.
- **MODE**: Controls the build environment as `"development"` or `"staging"`, influencing the manifest title and description. Defaults to `"development"` when not specified.

## Build Scripts and Configuration

The repository uses npm scripts defined in [`package.json`](https://github.com/nautls/nautilus-wallet/blob/main/package.json) to orchestrate the build process with the correct environment variable combinations.

### npm Scripts in package.json

Located at lines 10-15 in [`package.json`](https://github.com/nautls/nautilus-wallet/blob/main/package.json), the build scripts map specific network and browser combinations to Vite commands:

```json
"build:mainnet:chrome": "vite build",
"build:mainnet:firefox": "TARGET=firefox vite build",
"build:testnet:chrome": "NETWORK=testnet vite build",
"build:testnet:firefox": "TARGET=firefox NETWORK=testnet vite build"

```

### Vite Configuration Pipeline

The [`vite.config.ts`](https://github.com/nautls/nautilus-wallet/blob/main/vite.config.ts) file (lines 18-27) extracts the environment variables into a JavaScript `env` object and injects them into the bundle via `define: defEnv(env)`. 

The critical extension bundling logic resides in lines 55-66, where the **vite-plugin-web-extension** integration:

1. Invokes `buildManifest(env.NETWORK, env.TARGET, mode)` to generate browser-specific manifest files
2. Supplies additional entry points including content scripts, popup HTML, and background scripts
3. Sets the `browser` option to `env.TARGET` to ensure Chrome-compatible or Firefox-compatible output

## Generating Browser-Specific Manifests

The manifest generation logic centralizes browser compatibility handling in a dedicated TypeScript module.

### The buildManifest Function

Located in [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts) (lines 42-98), the `buildManifest` function composes the final manifest based on three factors:

- **Network configuration**: Affects the extension title, description, and icon set through `buildTitle`, `buildDescription`, and `buildIcons` helper functions
- **Browser platform**: Conditionally adds Chrome-specific fields (`side_panel`, `version_name`) or Firefox-specific fields (`browser_specific_settings`, `sidebar_action`)
- **Build mode**: "Staging" mode modifies the title and description for canary builds

### Chrome vs Firefox Manifest Differences

The manifest generator handles platform-specific requirements automatically:

**Chrome extensions** receive:
- `side_panel` configuration for the side panel API
- `version_name` field for detailed version tracking

**Firefox extensions** receive:
- `browser_specific_settings` with strict minimum version requirements
- `sidebar_action` configuration for Firefox's sidebar API

## Step-by-Step Build Instructions

Follow these commands to build and package Nautilus Wallet for distribution.

First, install dependencies using pnpm:

```bash
pnpm i

```

Build a production Chrome extension for Mainnet:

```bash
pnpm run build:mainnet:chrome

```

Build a production Firefox extension for Testnet:

```bash
pnpm run build:testnet:firefox

```

Package the build for upload to browser stores. Navigate to the output directory and create a zip archive:

```bash
cd dist
zip -r ../nautilus-wallet-chrome-mainnet.zip *

```

The `dist/` directory contains all necessary artifacts including [`manifest.json`](https://github.com/nautls/nautilus-wallet/blob/main/manifest.json), compiled scripts, HTML entry points, and network-specific icon sets.

## Customizing the Build

To modify extension permissions or add new content scripts, edit [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts) and adjust the `buildManifest` return object. Changes reflect automatically on the next build cycle.

## Summary

- **Environment variables** (`NETWORK`, `TARGET`, `MODE`) control the build target and network configuration
- **npm scripts** in [`package.json`](https://github.com/nautls/nautilus-wallet/blob/main/package.json) provide convenient shortcuts for common build combinations
- **vite.config.ts** orchestrates the build pipeline and integrates `vite-plugin-web-extension`
- **src/extension/manifest.ts** generates browser-specific manifests with platform-appropriate fields
- **Output** lands in `dist/` and is ready for zipping and uploading to the Chrome Web Store or Mozilla Add-ons

## Frequently Asked Questions

### What build tool does Nautilus Wallet use?

Nautilus Wallet uses **Vite** as its primary build tool, augmented by the `vite-plugin-web-extension` plugin. This combination handles TypeScript compilation, bundling, and browser-specific manifest generation in a single pipeline defined in [`vite.config.ts`](https://github.com/nautls/nautilus-wallet/blob/main/vite.config.ts).

### Can I build for both Chrome and Firefox from the same codebase?

Yes. The build system uses the `TARGET` environment variable to switch between Chrome and Firefox configurations. The `buildManifest` function in [`src/extension/manifest.ts`](https://github.com/nautls/nautilus-wallet/blob/main/src/extension/manifest.ts) automatically includes browser-specific fields like `side_panel` for Chrome or `browser_specific_settings` for Firefox based on this variable.

### Where are the compiled extension files located after building?

All compiled assets are placed in the `dist/` directory at the project root. This folder contains the generated [`manifest.json`](https://github.com/nautls/nautilus-wallet/blob/main/manifest.json), bundled JavaScript files, HTML entry points, and network-specific icon sets. You should zip the contents of this folder (not the folder itself) when preparing for store submission.

### How do I create a Testnet build instead of Mainnet?

Set the `NETWORK` environment variable to `"testnet"` before running the build command. You can use the predefined npm script `build:testnet:chrome` or `build:testnet:firefox`, or manually invoke `NETWORK=testnet vite build` to generate a Testnet-configured extension with appropriate titles and icons.