# Simple JS Package

This guide extends the [Simple Package](/packaging/simple) walkthrough with an actual script instead of plain shell commands — a Node.js script that runs the same way on every platform, no compilation needed.

## Package Structure

```text
my-package/
├── .aux4         # Package metadata and commands (REQUIRED)
├── LICENSE       # License file (REQUIRED)
├── README.md     # Package documentation (REQUIRED)
├── RELEASE.md    # Release notes for this version (recommended)
└── lib/          # Script files (optional)
    └── slug.js
```

## Step 1: Create the Package

### Create the directory structure

```bash
mkdir -p slug/lib
cd slug
```

### Create the script

```bash
cat > lib/slug.js << 'EOF'
const text = process.argv[2] || "";
const slug = text
  .toLowerCase()
  .trim()
  .replace(/[^a-z0-9]+/g, "-")
  .replace(/^-+|-+$/g, "");
console.log(slug);
EOF
```

### Create the .aux4 file

Reference the script with `${packageDir}`, which resolves to the package's installation directory (`~/.aux4.config/packages/<scope>/<name>/`):

```json
{
  "scope": "myorg",
  "name": "slug",
  "version": "1.0.0",
  "description": "Convert text into a URL-friendly slug",
  "license": "MIT",
  "profiles": [
    {
      "name": "main",
      "commands": [
        {
          "name": "slug",
          "execute": [
            "node ${packageDir}/lib/slug.js \"${text}\""
          ],
          "help": {
            "text": "Convert text into a URL-friendly slug",
            "variables": [
              {
                "name": "text",
                "text": "The text to slugify",
                "arg": true
              }
            ]
          }
        }
      ]
    }
  ]
}
```

**Quoting matters here:** `${text}` is wrapped in `\"..\"` inside the execute string. Without the quotes, a multi-word value gets word-split by the shell before it reaches `process.argv` — the script would only ever see the first word.

### Create the LICENSE and README.md files

Same as the [Simple Package](/packaging/simple) guide — see its Step 1 for the full LICENSE text and the `aux4/license` shortcut.

## Step 2: Test Locally

```bash
aux4 slug "Hello World! This is aux4"
```

```text
hello-world-this-is-aux4
```

## Step 3: Build the Package

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

```text
out/
└── myorg_slug_1.0.0.zip
```

The script is bundled into the zip automatically — no separate build step is needed for Node.js, since it runs directly from source.

## Step 4: Install from File (Local Testing)

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

```bash
aux4 slug "Local Install Test!"
```

```text
local-install-test
```

## Step 5: Publish the Package

```bash
aux4 aux4 login
aux4 aux4 pkger publish ./out/myorg_slug_1.0.0.zip
```

## Step 6: Install from aux4 Hub

```bash
aux4 aux4 pkger install myorg/slug
```

## Step 7: Use the Package

```bash
aux4 slug "Ready To Ship"
```

```text
ready-to-ship
```

## Other Languages

The same pattern works for any interpreted language — reference the interpreter and the script's path under `${packageDir}`:

```json
"execute": ["python3 ${packageDir}/lib/slug.py \"${text}\""]
```

If your package needs system-level dependencies (e.g., `node` or `python3` itself must be present), see [Package with System Dependencies](/packaging/system-dependencies). If you'd rather ship a compiled binary instead of an interpreted script — so users don't need Node/Python installed at all — see [Multi-Platform Package](/packaging/multi-platform).

---

## See Also

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