npm package: @involvex/msix-packager-cli
Description: A utility to create MSIX packages from Node.js applications with MCP server support, Node.js Single Executable Application (SEA) bundling using @vercel/ncc and postject, and enhanced build options
Author: involvex
Latest version: 1.4.1

# Node- 📦 Generate MSIX packages from Node.js applications

- ⚡ Single Executable Application (SEA) bundling using @vercel/ncc and postject
- 🔐 Code signing support with certificate store integration
- ⚙️ Configurable manifest generation
- 🖥️ CLI and programmatic API
- 📁 Asset bundling for static files, views, and configurations
- 🛡️ Automatic fallback to PKG-based executables if SEA failsackager

A utility to create and sign MSIX packages from Node.js applications for Windows deployment.

## Features

- 📦 Generate MSIX packages from Node.js applications
- � Single Executable Application (SEA) bundling using Node.js native technology
- �🔐 Code signing support with certificate store integration
- ⚙️ Configurable manifest generation
- 🖥️ CLI and programmatic API
- 📁 Asset bundling for static files, views, and configurations
- � Automatic fallback to traditional Node.js launchers if SEA fails

## Single Executable Application (SEA) Support

This packager uses Node.js's official **Single Executable Application** technology with modern bundling:

### SEA Implementation:

- **@vercel/ncc**: Bundles your application and all dependencies into a single JavaScript file
- **Node.js SEA Config**: Uses `--experimental-sea-config` to create preparation blobs
- **postject**: Injects the application blob into a Node.js binary using official SEA markers
- **Smart Entry Point**: Detects SEA vs development mode and handles paths correctly

### SEA Benefits:

- **Self-contained**: No need for separate Node.js runtime installation
- **Optimized**: NCC creates highly optimized bundles with tree-shaking
- **Fast startup**: Embedded code loads faster than file-based modules
- **Security**: Bundled code is embedded within the executable binary
- **Portability**: Single .exe file contains everything needed
- **Official**: Uses Node.js's official SEA implementation (not third-party solutions)

### TypeScript Support:

- **Built-in TypeScript**: @vercel/ncc automatically handles TypeScript transpilation
- **No Build Step**: TypeScript files are processed directly by NCC
- **Type Safety**: Full TypeScript development experience with production SEA builds
- **tsconfig.json**: Automatically uses your existing TypeScript configuration
- **Auto-detection**: Automatically detects .ts files and TypeScript projects
- **All Features**: Supports interfaces, generics, decorators, and advanced TypeScript features

### Fallback Strategy:

If SEA creation fails, the packager automatically falls back to PKG-based executable creation, ensuring your application can still be packaged.

## Installation

```bash
npm install -g @involvex/msix-packager-cli
```

## Quick Start

### CLI Usage

```bash
node-msix package --input ./my-app --name "My App" --publisher "CN=My Publisher" --output ./dist
```

### Programmatic Usage

```javascript
const { createMsixPackage } = require("node-msix-packager");

await createMsixPackage({
  inputPath: "./my-app",
  outputPath: "./dist",
  appName: "My App",
  packageName: "MyApp",
  publisher: "CN=My Publisher",
  version: "1.0.0.0",
});
```

## Configuration Options

| Parameter               | Type   | Required | Description                                       |
| ----------------------- | ------ | -------- | ------------------------------------------------- |
| `inputPath`             | string | Yes      | Path to your Node.js application                  |
| `outputPath`            | string | No       | Output directory for MSIX package                 |
| `appName`               | string | Yes      | Application name                                  |
| `publisher`             | string | Yes      | Publisher certificate name (e.g., "CN=MyCompany") |
| `version`               | string | No       | App version (4-part: x.x.x.x)                     |
| `packageName`           | string | No       | Unique package identifier                         |
| `architecture`          | string | No       | Target architecture (x64, x86)                    |
| `certificateThumbprint` | string | No       | Certificate thumbprint for signing                |

## Code Signing

To sign your MSIX package, provide a certificate:

```javascript
await createMsixPackage({
  // ... other options
  certificateThumbprint: "YOUR_CERT_THUMBPRINT",
});
```

## Requirements

- Windows 10/11
- Node.js 14+
- Windows SDK (for makeappx.exe)

## License

MIT

```bash
# Package a Node.js application
node-msix package --input ./my-node-app --output ./dist --name "My App" --publisher "CN=MyCompany"

# Using makeappx-only mode (requires Windows SDK)
node-msix package --input ./my-node-app --name "My App" --publisher "CN=MyCompany" --makeappx-only

# Using configuration file
node-msix package --config ./msix-config.json
```

### CLI Usage (Local Installation)

```bash
# Package a Node.js application
npx node-msix package --input ./my-node-app --output ./dist --name "My App" --publisher "CN=MyCompany"
```

### Programmatic Usage

```javascript
const {
  createMsixPackage,
  createMsixPackageWithMakeAppxOnly,
} = require("node-msix-packager");

const config = {
  inputPath: "./my-node-app",
  outputPath: "./dist",
  appName: "My Application",
  publisher: "CN=MyCompany",
  version: "1.0.0.0",
  description: "My awesome Node.js application",
  executable: "node.exe",
  arguments: "app.js",
  architecture: "x64",
  displayName: "My Application",
  packageName: "MyCompany.MyApplication",
  capabilities: ["internetClient", "privateNetworkClientServer"],
};

// Standard packaging (with fallbacks)
createMsixPackage(config)
  .then(() => console.log("MSIX package created successfully!"))
  .catch((error) => console.error("Error creating package:", error));

// MakeAppx-only packaging (requires Windows SDK)
createMsixPackageWithMakeAppxOnly(config)
  .then(() => console.log("MSIX package created with makeappx!"))
  .catch((error) => console.error("Error creating package:", error));
```

## Configuration Options

### Using Configuration File

Create a `msix-config.json` file in your project root:

```json
{
  "appName": "My Node Application",
  "publisher": "CN=MyCompany",
  "version": "1.0.0.0",
  "description": "My awesome Node.js application",
  "displayName": "My App",
  "packageName": "MyCompany.MyApp",
  "architecture": "x64",
  "capabilities": ["internetClient", "privateNetworkClientServer"],
  "executable": "node.exe",
  "arguments": "app.js",
  "icon": "./assets/icon.png"
}
```

### Configuration Parameters

| Parameter        | Type    | Required | Default              | Description                                       |
| ---------------- | ------- | -------- | -------------------- | ------------------------------------------------- |
| `inputPath`      | string  | Yes      | -                    | Path to your Node.js application                  |
| `outputPath`     | string  | No       | `./dist`             | Output directory for MSIX package                 |
| `appName`        | string  | Yes      | -                    | Application name                                  |
| `publisher`      | string  | Yes      | -                    | Publisher certificate name (e.g., "CN=MyCompany") |
| `version`        | string  | No       | `1.0.0.0`            | App version (must be 4-part: x.x.x.x)             |
| `description`    | string  | No       | -                    | Application description                           |
| `displayName`    | string  | No       | `appName`            | Display name shown to users                       |
| `packageName`    | string  | No       | Generated            | Unique package identifier                         |
| `architecture`   | string  | No       | `x64`                | Target architecture (`x64`, `x86`)                |
| `executable`     | string  | No       | `node.exe`           | Main executable file                              |
| `arguments`      | string  | No       | `app.js`             | Command line arguments                            |
| `icon`           | string  | No       | -                    | Path to application icon                          |
| `capabilities`   | array   | No       | `["internetClient"]` | App capabilities                                  |
| `skipBuild`      | boolean | No       | `false`              | Skip running bun build script                     |
| `installDevDeps` | boolean | No       | `true`               | Install dev dependencies for build                |
| `makeappxOnly`   | boolean | No       | `false`              | Use only makeappx.exe (no fallbacks)              |

### Available Capabilities

- `internetClient` - Access to internet and public networks
- `internetClientServer` - Inbound/outbound access to internet
- `privateNetworkClientServer` - Access to home/work networks
- `documentsLibrary` - Access to Documents library
- `picturesLibrary` - Access to Pictures library
- `videosLibrary` - Access to Videos library
- `musicLibrary` - Access to Music library
  "version": "1.0.0.0",
  "description": "My Node.js application packaged as MSIX",
  "displayName": "My App",
  "packageName": "MyCompany.MyApp",
  "architecture": "x64",
  "capabilities": ["internetClient"],
  "executable": "node.exe",
  "arguments": "app.js",
  "icon": "./assets/icon.png"
  }

```

## Requirements

- Windows 10/11
- Windows SDK (for makeappx.exe)
- Node.js runtime
- PowerShell 5.0+

**Note**: The packager automatically uses Node.js Single Executable Application (SEA) technology to bundle your Node.js application into a single executable, providing optimal performance, security, and compatibility.

## Directory Structure

```

your-node-app/
├── package.json
├── app.js (or main entry point)
├── node_modules/
├── assets/
│ └── icon.png
└── msix-config.json

````

## Examples

See the `examples/` directory for sample applications and configurations:

- **`examples/sample-app/`** - Basic JavaScript Node.js application with Express server
- **`examples/typescript-app/`** - Full TypeScript application demonstrating SEA with NCC bundling

### TypeScript Example

For TypeScript projects, NCC automatically handles transpilation:

```typescript
// src/index.ts
import express, { Application } from 'express';

class TypeScriptSEAApp {
  private app: Application;

  constructor() {
    this.app = express();
    this.setupRoutes();
  }

  private setupRoutes(): void {
    this.app.get('/api/status', (req, res) => {
      res.json({
        status: 'success',
        message: 'TypeScript SEA is running!',
        timestamp: new Date().toISOString()
      });
    });
  }
}

export default TypeScriptSEAApp;
````

Package it with:

```bash
node-msix package --input ./typescript-app --name "TypeScript SEA Demo" --publisher "CN=Demo"
```

The packager automatically:

1. Detects TypeScript files and `tsconfig.json`
2. Uses NCC to bundle and transpile TypeScript code
3. Creates a single executable with embedded TypeScript application
4. Packages everything into an MSIX for distribution

For detailed documentation on makeappx-only packaging, see [`docs/makeappx-only.md`](docs/makeappx-only.md).

## Troubleshooting

### TypeScript Build Errors

If you get errors like `'tsc' is not recognized as an internal or external command`, you have several options:

1. **Install dev dependencies** (Recommended): Set `installDevDeps: true` in your config:

   ```json
   {
     "installDevDeps": true
   }
   ```

2. **Skip the build step**: If your code is already compiled:

   ```json
   {
     "skipBuild": true
   }
   ```

3. **Pre-build your application** before packaging:
   ```bash
   bun run build
   node-msix package --config config.json --skipBuild
   ```

### Common Build Issues

- **Missing TypeScript**: The packager will automatically try to install TypeScript if it detects a tsc build failure
- **Build takes too long**: Use `skipBuild: true` if you've already built your application
- **Memory issues**: Try building your app separately first, then package with `skipBuild: true`
- **SEA creation fails**: The packager will fall back to traditional Node.js launcher approach
- **Executable creation**: Uses Node.js Single Executable Application (SEA) for reliable bundling and optimal performance

### Command Line Options

You can also control build behavior via CLI:

```bash
# Skip build step
node-msix package --config config.json --skip-build

# Force install dev dependencies
node-msix package --config config.json --install-dev-deps
```

## License

MIT