# Package with System Dependencies

This guide shows how to create a package that requires system-level dependencies (e.g., Node.js, Python, AWS CLI). When your package is installed, aux4 automatically installs the required system packages using the appropriate package manager for the user's operating system.

## Package Structure

```text
my-package/
├── .aux4         # Package metadata with system dependencies
├── LICENSE
├── README.md
└── lib/
    └── script.js
```

## Step 1: Create the Package

### Create the .aux4 file

Add the `system` field to specify system-level dependencies:

```json
{
  "scope": "myorg",
  "name": "pdf-generator",
  "version": "1.0.0",
  "description": "Generate PDF documents",
  "license": "MIT",
  "system": [
    [
      "test:node --version",
      "brew:node",
      "apt:nodejs",
      "dnf:nodejs",
      "apk:nodejs"
    ],
    [
      "test:gs --version",
      "brew:ghostscript",
      "apt:ghostscript",
      "dnf:ghostscript",
      "apk:ghostscript"
    ]
  ],
  "profiles": [
    {
      "name": "main",
      "commands": [
        {
          "name": "pdf",
          "execute": [
            "profile:pdf"
          ],
          "help": {
            "text": "PDF generation commands"
          }
        }
      ]
    },
    {
      "name": "pdf",
      "commands": [
        {
          "name": "generate",
          "execute": [
            "node ${packageDir}/lib/generate-pdf.js ${input} ${output}"
          ],
          "help": {
            "text": "Generate a PDF from input file",
            "variables": [
              {
                "name": "input",
                "text": "Input file",
                "arg": true
              },
              {
                "name": "output",
                "text": "Output PDF file",
                "default": "output.pdf"
              }
            ]
          }
        }
      ]
    }
  ]
}
```

## System Dependency Format

Each system dependency is an array with:
1. A test command to check if the dependency is installed
2. Package manager and package name pairs for different systems

```json
{
  "system": [
    [
      "test:<command to verify installation>",
      "<package-manager>:<package-name>",
      "<package-manager>:<package-name>"
    ]
  ]
}
```

### Test Command

The test command verifies if the dependency is already installed. If the command succeeds (exit code 0), the dependency is skipped.

```json
"test:node --version"
"test:python3 --version"
"test:aws --version"
"test:gs --version"
```

### Supported Package Managers

- [`brew`](https://hub.aux4.io/r/public/packages/aux4/system-installer-brew): Homebrew (macOS)
- [`apt`](https://hub.aux4.io/r/public/packages/aux4/system-installer-apt): APT (Debian/Ubuntu)
- [`dnf`](https://hub.aux4.io/r/public/packages/aux4/system-installer-dnf): DNF (Fedora/RHEL)
- [`yum`](https://hub.aux4.io/r/public/packages/aux4/system-installer-yum): YUM (CentOS/RHEL)
- [`apk`](https://hub.aux4.io/r/public/packages/aux4/system-installer-apk): APK (Alpine Linux)
- [`npm`](https://hub.aux4.io/r/public/packages/aux4/system-installer-npm): Node Package Manager
- [`pkgx`](https://hub.aux4.io/r/public/packages/aux4/system-installer-pkgx): pkgx package manager
- [`linux`](https://hub.aux4.io/r/public/search?q=linux): Generic alias used by all Linux package managers (apt, dnf, yum, apk)

### Using the linux Alias

The `linux` alias is a convenience that works with any Linux package manager:

```json
{
  "system": [
    [
      "test:node --version",
      "brew:node",
      "linux:nodejs"
    ]
  ]
}
```

This is equivalent to specifying all Linux package managers individually.

## Step 2: Create the Script

Create `lib/generate-pdf.js`:

```javascript
const input = process.argv[2];
const output = process.argv[3];

console.log(`Generating PDF from ${input} to ${output}`);
// PDF generation logic here
```

## Step 3: Create Supporting Files

### LICENSE

```bash
cat > LICENSE << 'EOF'
MIT License
...
EOF
```

**Tip:** You can also use [aux4/license](https://hub.aux4.io/r/public/packages/aux4/license) to generate your LICENSE file:

```bash
aux4 license use \
  --name mit \
  --owner "MyOrg" \
  --year 2024 \
  --project "pdf-generator"
```

### README.md

````bash
cat > README.md << 'EOF'
# PDF Generator

Generate PDF documents from various input formats.

## System Requirements

This package requires:
- Node.js
- Ghostscript

These are installed automatically based on your operating system.

## Usage

```bash
aux4 pdf generate input.txt --output result.pdf
```
EOF
````

## Step 4: Build the Package

```bash
aux4 aux4 pkger build ./out .
```

## Step 5: Install from File

```bash
aux4 aux4 pkger install --fromFile ./out/myorg_pdf-generator_1.0.0.zip
```

During installation, aux4:
1. Runs each test command
2. If the test fails, installs the package using the appropriate package manager
3. Skips installation if the dependency is already present

## Step 6: Publish

```bash
aux4 aux4 login
aux4 aux4 pkger publish ./out/myorg_pdf-generator_1.0.0.zip
```

## Step 7: Install from aux4 Hub

```bash
aux4 aux4 pkger install myorg/pdf-generator
```

## Common System Dependencies

### Node.js

```json
[
  "test:node --version",
  "brew:node",
  "apt:nodejs",
  "dnf:nodejs",
  "apk:nodejs"
]
```

### Python 3

```json
[
  "test:python3 --version",
  "brew:python3",
  "apt:python3",
  "dnf:python3",
  "apk:python3"
]
```

### AWS CLI

```json
[
  "test:aws --version",
  "brew:awscli",
  "pkgx:aws"
]
```

### jq

```json
[
  "test:jq --version",
  "brew:jq",
  "apt:jq",
  "dnf:jq",
  "apk:jq"
]
```

### npm Packages

For global npm packages:

```json
[
  "test:jest --version",
  "npm:jest"
]
```

## Combining aux4 and System Dependencies

You can use both `dependencies` (aux4 packages) and `system` (system packages) together:

```json
{
  "scope": "myorg",
  "name": "full-stack-tool",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": [
    "aux4/config",
    "aux4/validator"
  ],
  "system": [
    [
      "test:node --version",
      "brew:node",
      "linux:nodejs"
    ],
    [
      "test:docker --version",
      "brew:docker",
      "apt:docker.io"
    ]
  ],
  "profiles": [...]
}
```

---

## See Also

- [Simple Package](/packaging/simple)
- [Package with Dependencies](/packaging/dependencies)
- [Multi-Platform Package](/packaging/multi-platform)
- [Creating System Installers](/packaging/system-installer)
