> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/zhcndoc/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# bun publish

Publish a package to the npm registry.

```bash theme={null}
bun publish
```

## Behavior

`bun publish` packages your project into a tarball and publishes it to the npm registry (or a private registry). It:

1. Validates `package.json` (checks for required fields)
2. Runs lifecycle scripts (`prepare`, `prepublish`, `prepublishOnly`)
3. Creates a tarball of your package
4. Uploads the tarball to the registry
5. Runs postpublish scripts

## Prerequisites

### Authentication

You must be logged in to npm:

```bash theme={null}
bunx npm login
```

This stores credentials for publishing.

### Required package.json fields

Your `package.json` must have:

```json theme={null}
{
  "name": "my-package",
  "version": "1.0.0"
}
```

## Publishing modes

### Publish from directory (default)

```bash theme={null}
bun publish
```

Automatically packs and publishes the current directory.

### Publish a tarball

```bash theme={null}
bun publish ./my-package-1.0.0.tgz
```

Publish a pre-built tarball.

## Flags

### `--tag <tag>`

Publish with a specific dist-tag (default: `latest`).

```bash theme={null}
bun publish --tag beta
```

Common tags:

* `latest` (default) - Stable release
* `next` - Pre-release / canary
* `beta` - Beta version
* `alpha` - Alpha version
* `rc` - Release candidate

Users can install tagged versions:

```bash theme={null}
bun add my-package@beta
```

### `--access <public|restricted>`

Set package access level.

```bash theme={null}
# Publish as public (required for unscoped packages)
bun publish --access public

# Publish as restricted (only for scoped packages)
bun publish --access restricted
```

**Note:** Unscoped packages must be public. Scoped packages (`@org/package`) can be public or restricted.

### `--dry-run`

Simulate publishing without actually uploading to the registry.

```bash theme={null}
bun publish --dry-run
```

Shows what would be published:

```
packed 15 files (42.3 KB)
unpacked size: 128 KB
tarball: my-package-1.0.0.tgz
shasum: a1b2c3d4e5...
integrity: sha512-AbCd...

Tag: latest
Access: public
Registry: https://registry.npmjs.org/

[dry-run] Would publish
```

### `--otp <code>`

Provide a one-time password for two-factor authentication.

```bash theme={null}
bun publish --otp 123456
```

If you have 2FA enabled and don't provide `--otp`, Bun will prompt for it.

### `--no-ignore-scripts`

Run lifecycle scripts (enabled by default). Use to explicitly enable scripts.

```bash theme={null}
bun publish --no-ignore-scripts
```

### `--ignore-scripts`

Skip running lifecycle scripts.

```bash theme={null}
bun publish --ignore-scripts
```

### `--cwd <path>`

Run command in specified directory.

```bash theme={null}
bun publish --cwd ./packages/my-package
```

## Lifecycle scripts

Bun runs these scripts in order:

1. **`prepare`** - Before packing, after `npm install`
2. **`prepublishOnly`** - Before packing, only on `bun publish`
3. **`prepack`** - Before tarball is created
4. **`postpack`** - After tarball is created
5. **`publish`** - After publishing (on success)
6. **`postpublish`** - After publishing (on success)

Example in `package.json`:

```json theme={null}
{
  "scripts": {
    "prepare": "bun run build",
    "prepublishOnly": "bun test",
    "postpublish": "echo 'Published!'"
  }
}
```

## Files included

By default, these files are included:

* All files in the project
* Respects `.npmignore` or `files` field in `package.json`

### Using `files` field

```json theme={null}
{
  "files": [
    "dist",
    "README.md",
    "LICENSE"
  ]
}
```

Only specified files/directories are included.

### Always included

* `package.json`
* `README` / `README.md`
* `LICENSE` / `LICENCE`
* `CHANGELOG` / `CHANGELOG.md`

### Always excluded

* `.git`
* `node_modules`
* `.env` files
* `.DS_Store`

## publishConfig

Configure publishing behavior in `package.json`:

```json theme={null}
{
  "publishConfig": {
    "access": "public",
    "tag": "latest",
    "registry": "https://registry.npmjs.org/"
  }
}
```

## Examples

### Basic publish

```bash theme={null}
$ bun publish
bun publish v1.0.0

packed 15 files
unpacked size: 128 KB
packed size: 42.3 KB
shasum: a1b2c3d4e5f6...
integrity: sha512-AbCdEf...

Tag: latest
Access: public  
Registry: https://registry.npmjs.org/

+ my-package@1.0.0
```

### Publish beta version

```bash theme={null}
$ bun publish --tag beta
bun publish v1.0.0

+ my-package@1.0.0-beta.1 (beta)
```

### Publish with dry run

```bash theme={null}
$ bun publish --dry-run
bun publish v1.0.0

packed 15 files (42.3 KB)

Tag: latest
Access: public
Registry: https://registry.npmjs.org/

+ my-package@1.0.0 (dry-run)
```

### Publish with 2FA

```bash theme={null}
$ bun publish
bun publish v1.0.0

This operation requires a one-time password.
Enter OTP: 123456

+ my-package@1.0.0
```

Or provide OTP directly:

```bash theme={null}
bun publish --otp 123456
```

## Publishing workflow

Typical workflow for publishing a new version:

```bash theme={null}
# 1. Update version
bun pm version patch

# 2. Test before publishing
bun test

# 3. Dry run to verify package contents
bun publish --dry-run

# 4. Publish
bun publish

# 5. Tag git release (optional)
git push --follow-tags
```

## Private packages

Publish to a private registry:

```json theme={null}
{
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/",
    "access": "restricted"
  }
}
```

## Scoped packages

Publish scoped packages:

```json theme={null}
{
  "name": "@myorg/my-package",
  "publishConfig": {
    "access": "public"
  }
}
```

```bash theme={null}
bun publish --access public
```

## Prevent accidental publishing

Mark a package as private to prevent publishing:

```json theme={null}
{
  "private": true
}
```

Attempting to publish will fail:

```bash theme={null}
$ bun publish
error: attempted to publish a private package
```

## Verify published package

After publishing, verify:

```bash theme={null}
# View on registry
bun pm view my-package

# Install and test
cd /tmp
bun add my-package
```

## Unpublishing

To unpublish a version:

```bash theme={null}
npx npm unpublish my-package@1.0.0
```

**Note:** You can only unpublish within 72 hours. After that, contact npm support.

## Common errors

### Missing authentication

```
error: missing authentication (run `bunx npm login`)
```

Run `bunx npm login` first.

### Package already exists

```
error: cannot publish over existing version
```

Increment version with `bun pm version patch`.

### Private package

```
error: attempted to publish a private package
```

Remove `"private": true` from `package.json`.

### Unscoped package requires public access

```
error: unable to restrict access to unscoped package
```

Use `--access public` or scope the package.
