
Security News
arXiv Is Rate Limiting Authors Following a Flood of AI Slop Submissions
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.
@ar.io/deploy
Advanced tools
ARIO Deploy — CLI for deploying apps to the permaweb (Arweave) and updating ArNS
ario-deploy is a Node.js command-line tool designed to streamline the deployment of web applications to the permaweb using Arweave. It uploads your build folder or a single file, creates Arweave manifests, and can optionally update ArNS (Ar.io Name System) records via ANT (Ar.io Name Token) with the transaction ID.
Deploy your app to Arweave in under a minute:
# Install
npm install -g @ar.io/deploy
# Deploy (interactive — prompts for everything)
ario-deploy deploy
# Or one-liner with a Solana wallet + ArNS name
DEPLOY_KEY=<solana-base58-key> ario-deploy deploy --deploy-folder ./dist --arns-name myapp --sig-type solana
Your app is now permanently live at https://myapp.ar.io.
mainnet or devnet, with an optional custom RPC URLInstall the package using pnpm (recommended):
pnpm add -D @ar.io/deploy
Or with npm:
npm install --save-dev @ar.io/deploy
Or with yarn:
yarn add --dev @ar.io/deploy
A deployment uses up to two independent keys:
--wallet / --private-key, or the DEPLOY_KEY env var; chain selected with --sig-type).--arns-wallet / --arns-private-key, or the ARNS_KEY env var).They can be the same Solana wallet or two different wallets — provide each explicitly.
DEPLOY_KEY)Arweave signer (default): Encode your Arweave wallet key in base64 and set it as DEPLOY_KEY:
base64 -i wallet.json | pbcopy
Ethereum/Polygon/KYVE signers: Use your raw private key (no encoding needed) as DEPLOY_KEY.
Solana signer: Use a base58-encoded secret key as DEPLOY_KEY, or a solana-keygen id.json byte-array wallet file via --wallet.
ARNS_KEY)Set a base58-encoded Solana secret key as ARNS_KEY, or pass a solana-keygen id.json file via --arns-wallet (or a base58 string via --arns-private-key). This key must control the ArNS name being updated.
⚠️ Important: Use dedicated wallets for deployments to minimize security risks. Ensure your upload wallet has sufficient Turbo Credits for uploads.
Run the deploy command without arguments to be guided through all deployment options:
ario-deploy deploy
When ArNS details aren't supplied via flags, deploy asks whether you want to
update an ArNS name (defaulting to yes) and, if so, prompts for the details. It
will guide you through:
Pass --arns-name (or --use-arns) to skip the ArNS confirmation, or use the
upload command for an upload-only run. In a non-interactive environment (CI,
or no TTY) deploy does not prompt — supply everything via flags or
DEPLOY_KEY.
Use flags for faster, scriptable deployments:
# Basic deployment with wallet file
ario-deploy deploy --wallet ./wallet.json
# Deployment with ArNS update (separate upload key + Solana ArNS authority key)
ario-deploy deploy --use-arns --arns-name my-app --wallet ./wallet.json --arns-wallet ./arns-id.json
Deploy using private key directly:
ario-deploy deploy --private-key "$(cat wallet.json)"
Deploy using environment variable:
DEPLOY_KEY=$(base64 -i wallet.json) ario-deploy deploy --deploy-folder ./dist
Deploy a specific folder:
ario-deploy deploy --wallet ./wallet.json --deploy-folder ./build
Deploy a single file:
ario-deploy deploy --wallet ./wallet.json --deploy-file ./path/to/file.txt
deploy uploads without updating ArNS by default. You can also use the upload command explicitly for the same Turbo upload, dedupe cache, and payment options as deploy, minus ArNS flags:
ario-deploy deploy --wallet ./wallet.json --deploy-folder ./dist
ario-deploy upload --wallet ./wallet.json --deploy-folder ./dist
ario-deploy upload --wallet ./wallet.json --deploy-file ./dist/index.html
DEPLOY_KEY=$(base64 -i wallet.json) ario-deploy upload --deploy-folder ./dist
Deploy to an undername (subdomain) — the ArNS authority key is a Solana wallet:
ario-deploy deploy --use-arns --arns-name my-app --wallet ./wallet.json --arns-wallet ./arns-id.json --undername staging
Deploy with a custom TTL:
ario-deploy deploy --use-arns --arns-name my-app --wallet ./wallet.json --arns-wallet ./arns-id.json --ttl-seconds 7200
Update ArNS on devnet (or against a custom RPC):
ario-deploy deploy --use-arns --arns-name my-app --wallet ./wallet.json --arns-wallet ./arns-id.json --cluster devnet
ario-deploy deploy --use-arns --arns-name my-app --wallet ./wallet.json --arns-wallet ./arns-id.json --rpc-url https://my-rpc.example.com
Upload using an Ethereum wallet (file):
ario-deploy deploy --sig-type ethereum --wallet ./private-key.txt
Upload using a Solana wallet (base58 private key):
ario-deploy deploy --sig-type solana --private-key "<base58-secret-key>"
Use on-demand payment to automatically fund uploads with ARIO or Base-ETH tokens when your Turbo balance is insufficient:
Deploy with ARIO on-demand payment:
ario-deploy deploy --wallet ./wallet.json --deploy-folder ./dist --on-demand ario --max-token-amount 1.5
Deploy with Base-ETH on-demand payment (using Ethereum signer):
ario-deploy deploy --sig-type ethereum --private-key "0x..." --on-demand base-eth --max-token-amount 0.1
On-Demand Payment Options:
--on-demand: Token to use for on-demand payment (ario or base-eth)--max-token-amount: Maximum token amount to spend (in native token units, e.g., 1.5 for 1.5 ARIO or 0.1 for 0.1 ETH)How it works:
topUpBufferMultiplier: 1.1) for reliabilityToken compatibility:
Uploads go through a bundler service that accepts signed data items and posts them to Arweave. By default, ario-deploy uses the Turbo API and ArDrive’s production bundler (https://upload.ardrive.io). --uploader sets the base URL of the bundler service to use (scheme + host; typically no path).
| When to use | Example value |
|---|---|
| Default (omit flag) | ArDrive production bundler — same as Turbo CLI defaults |
| Arweave bundler | https://turbo.ardrive.io |
| Development / staging | https://upload.services.ar-io.dev |
| Custom or self-hosted | Your own base URL if it implements the Turbo API |
Examples:
# Deploy using Arweave’s bundler service
ario-deploy deploy --wallet ./wallet.json --deploy-folder ./dist --uploader https://turbo.ardrive.io
ario-deploy upload --wallet ./wallet.json --deploy-folder ./dist --uploader https://turbo.ardrive.io
Notes:
https://turbo.ardrive.io), not a path to a specific file or route.deploy (upload by default, optional ArNS update):
--use-arns: Update an ArNS/ANT record after upload. When ArNS details aren't supplied and you're in a TTY, deploy asks by default.--arns-name, -n: The ArNS name to update. Required when using --use-arns; also implies ArNS mode.--cluster, -p: Solana cluster for ArNS updates. Choices: mainnet, devnet. Default: mainnet--rpc-url: Optional Solana RPC URL override for ArNS updates--deploy-folder, -d: Folder to deploy. Default: ./dist--deploy-file, -f: Deploy a single file instead of a folder--undername, -u: ANT undername to update. Default: @--ttl-seconds, -t: TTL in seconds for the ANT record (60-86400). Default: 60Upload key (pays for the upload):
--sig-type, -s: Signer type for the upload key. Choices: arweave, ethereum, polygon, kyve, solana. Default: arweave--wallet, -w: Path to the upload wallet file (JWK for Arweave, private key for Ethereum/Polygon/KYVE, solana-keygen id.json for Solana). Falls back to DEPLOY_KEY.--private-key, -k: Upload private-key string (alternative to --wallet). JWK JSON for Arweave, hex for EVM chains, base58 secret key for Solana.ArNS authority key (controls the name, signs the update — always Solana):
--arns-wallet: Path to the Solana solana-keygen id.json wallet that controls the ArNS name. Falls back to ARNS_KEY.--arns-private-key: Base58 Solana secret key for the ArNS authority (alternative to --arns-wallet). Falls back to ARNS_KEY.--on-demand: Enable on-demand payment with specified token. Choices: ario, base-eth--max-token-amount: Maximum token amount for on-demand payment (used with --on-demand)--no-dedupe: Disable deduplication (do not cache or reuse previous uploads)--dedupe-cache-max-entries: Maximum number of entries to keep in the dedupe cache (LRU). Default: 10000--uploader: Custom Turbo upload service base URL. See the Bundler service section.upload (explicit upload without ArNS): accepts --deploy-folder, --deploy-file, wallet/signer flags, --uploader, --on-demand / --max-token-amount, and dedupe flags only.
By default, ario-deploy caches your deployment log to prevent uploading duplicate (unchanged) files. This saves both time and upload costs by reusing existing data on Arweave.
How it works:
.ario-deploy/transaction-cache.jsonDisable deduplication:
If you need to force a fresh upload of all files (e.g., for debugging or to ensure a completely new deployment):
ario-deploy deploy --wallet ./wallet.json --no-dedupe
Limit cache size:
The dedupe cache uses an LRU (Least Recently Used) eviction strategy. By default, it keeps up to 10,000 entries. You can adjust this limit:
# Keep only the last 1000 file entries
ario-deploy deploy --wallet ./wallet.json --dedupe-cache-max-entries 1000
Cache location:
The cache file is stored at .ario-deploy/transaction-cache.json in your project root. You can:
.gitignore if you don't want to share cache across team membersrm -rf .ario-deploy/Add deployment scripts to your package.json:
{
"scripts": {
"build": "vite build",
"deploy": "pnpm build && ario-deploy deploy --arns-name <ARNS_NAME>",
"deploy:staging": "pnpm build && ario-deploy deploy --arns-name <ARNS_NAME> --undername staging",
"deploy:devnet": "pnpm build && ario-deploy deploy --arns-name <ARNS_NAME> --cluster devnet",
"deploy:on-demand": "pnpm build && ario-deploy deploy --arns-name <ARNS_NAME> --on-demand ario --max-token-amount 1.5"
}
}
These read the upload key from DEPLOY_KEY and the Solana ArNS authority key from ARNS_KEY. Deploy with:
DEPLOY_KEY=$(base64 -i wallet.json) ARNS_KEY=<base58-solana-secret-key> pnpm deploy
Or with on-demand payment:
DEPLOY_KEY=$(base64 -i wallet.json) ARNS_KEY=<base58-solana-secret-key> pnpm deploy:on-demand
The easiest way to integrate ario-deploy into your CI/CD pipeline is using our official GitHub Action.
- uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }} # upload key (pays for the upload)
arns-key: ${{ secrets.ARNS_KEY }} # Solana ArNS authority key
arns-name: myapp
deploy-folder: ./dist
Automatically deploy preview builds for each pull request. The preview mode auto-generates an undername from the PR number and posts a comment with the preview URL:
name: Deploy PR Preview
on:
pull_request:
types: [opened, synchronize]
jobs:
deploy-preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy Preview
uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }}
arns-key: ${{ secrets.ARNS_KEY }}
arns-name: myapp
preview: 'true'
github-token: ${{ secrets.GITHUB_TOKEN }}
deploy-folder: ./dist
When preview is enabled, the action will:
pr-123 from the PR numberDeploy to your base ArNS name when pushing to main:
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy to Permaweb
uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }}
arns-key: ${{ secrets.ARNS_KEY }}
arns-name: myapp
deploy-folder: ./dist
- name: Deploy with ARIO on-demand
uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }}
arns-key: ${{ secrets.ARNS_KEY }}
arns-name: myapp
deploy-folder: ./dist
on-demand: ario
max-token-amount: '2.0'
ArNS updates run against the Solana ARIO programs. Provide the Solana ArNS authority key via arns-key (a base58 Solana secret key); the upload is still paid for by deploy-key. Use cluster to target mainnet (default) or devnet, and rpc-url for a custom RPC endpoint.
- name: Deploy and update ArNS
uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }} # upload key
arns-key: ${{ secrets.ARNS_KEY }} # Solana ArNS authority key
arns-name: myapp
deploy-folder: ./dist
cluster: mainnet
By default, the action caches transaction IDs to avoid re-uploading unchanged files. To disable this:
- name: Deploy without dedupe
uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }}
deploy-folder: ./dist
no-dedupe: 'true'
You can also limit the cache size:
- name: Deploy with limited cache
uses: ar-io/ar-io-deploy@v1.0.0
with:
deploy-key: ${{ secrets.DEPLOY_KEY }}
deploy-folder: ./dist
dedupe-cache-max-entries: '1000'
You can also use the CLI directly in your workflows:
Basic Workflow:
name: Deploy to Permaweb
on:
push:
branches:
- main
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install
- run: pnpm deploy
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
With On-Demand Payment:
name: Deploy to Permaweb with On-Demand Payment
on:
push:
branches:
- main
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install
- run: pnpm build
- name: Deploy with ARIO on-demand
run: ario-deploy deploy --arns-name my-app --on-demand ario --max-token-amount 2.0
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} # upload key (pays for the upload)
ARNS_KEY: ${{ secrets.ARNS_KEY }} # Solana ArNS authority key
# Or upload with Ethereum and Base-ETH on-demand payment (upload only; ArNS requires Solana):
# - name: Upload with Base-ETH on-demand
# run: |
# ario-deploy upload \
# --sig-type ethereum \
# --on-demand base-eth \
# --max-token-amount 0.2
# env:
# DEPLOY_KEY: ${{ secrets.ETH_PRIVATE_KEY }}
Use Claude Code to deploy your app with natural language. Just say "deploy to ar.io" and Claude handles the rest.
mkdir -p .claude/skills
curl -o .claude/skills/deploy.md https://raw.githubusercontent.com/ar-io/ar-io-deploy/main/examples/claude-skill/deploy.md
Then in Claude Code, say:
Claude will build your project, detect the output folder, and run the deploy with the right flags.
./dist, ./build, ./out)DEPLOY_KEY env var or wallet file)@ar.io/deploy if not already availableSee examples/claude-skill/ for the full skill file and customization options.
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run in development mode
pnpm dev
# Run tests
pnpm test
# Run linter
pnpm lint
# Format code
pnpm format
ar-io-deploy/
├── src/
│ ├── commands/ # oclif commands
│ │ ├── deploy.ts
│ │ └── upload.ts
│ ├── types/ # TypeScript type definitions
│ │ └── index.ts
│ ├── utils/ # Utility functions
│ │ ├── constants.ts
│ │ ├── signer.ts
│ │ ├── uploader.ts
│ │ └── __tests__/ # Unit tests
│ └── index.ts # Main entry point
├── bin/ # Executable scripts
│ ├── run.js
│ └── dev.js
├── .changeset/ # Changesets configuration
├── .husky/ # Git hooks
└── dist/ # Build output
--max-token-amount limits to prevent unexpected costsDEPLOY_KEY secret secure and never commit it to your repositoryDEPLOY_KEY environment variable--on-demand with --max-token-amount to automatically fund uploads when balance is lowario with Arweave, base-eth with Ethereum)Contributions are welcome! Please follow these guidelines:
pnpm test && pnpm lintpnpm changesetThis project uses Conventional Commits. Commit messages should follow this format:
type(scope): subject
body (optional)
Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
We use changesets for version management. When making changes:
pnpm changeset
Follow the prompts to describe your changes.
MIT — © Permanent Data Solutions, Inc.
FAQs
ARIO Deploy — CLI for deploying apps to the permaweb (Arweave) and updating ArNS
The npm package @ar.io/deploy receives a total of 477 weekly downloads. As such, @ar.io/deploy popularity was classified as not popular.
We found that @ar.io/deploy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.

Security News
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.

Research
/Security News
A new GhostAction wave hits hundreds of GitHub repos, expanding CI/CD secret theft to cloud and AI credentials in source code and git history.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.