Undernames for Environments and Versioning
In the previous guide, you deployed your application to your base ArNS name. Now you'll learn how to manage multiple versions and environments using undernames - subdomains under your ArNS name.`
What You'll Learn
- Strategic versioning patterns for managing multiple environments
- Package.json workflows for dev → staging → production
- GitHub Actions automation for environment-based deployments
- Instant rollbacks using the ArNS app interface
- Best practices for TTL configuration and testing
Understanding Undernames
Undernames let you create multiple versions under one ArNS name - like subdomains in traditional DNS, but permanent and decentralized.
Structure:
your-arns-name (your ArNS name)
├─ @ (base) → your-arns-name.arweave.net
├─ dev → dev_your-arns-name.arweave.net
├─ staging → staging_your-arns-name.arweave.net
└─ v2 → v2_your-arns-name.arweave.netKey benefits:
- Unlimited undernames with one ArNS registration
- Each undername points to a different deployment (transaction ID)
- All versions remain permanently accessible
- Instant rollbacks by updating pointers in the ArNS app
Common Versioning Patterns
Pattern 1: Environment-Based Versioning
Best for: Most production applications
This pattern creates separate environments for your development workflow:
@ (production) → Current production release
staging → Pre-release testing environment
dev → Active development buildsAdd environment scripts to your project:
In your my-permaweb-app project from the previous guide, update package.json to add environment-specific deployment commands:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"deploy": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out",
"deploy:dev": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --undername dev --ttl-seconds 60",
"deploy:staging": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --undername staging --ttl-seconds 60",
"deploy:prod": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --ttl-seconds 3600"
}
}Replace your-arns-name with your actual ArNS name.
{
"scripts": {
"dev": "vite",
"build": "vite build",
"deploy": "vite build && permaweb-deploy deploy --arns-name your-arns-name",
"deploy:dev": "vite build && permaweb-deploy deploy --arns-name your-arns-name --undername dev --ttl-seconds 60",
"deploy:staging": "vite build && permaweb-deploy deploy --arns-name your-arns-name --undername staging --ttl-seconds 60",
"deploy:prod": "vite build && permaweb-deploy deploy --arns-name your-arns-name --ttl-seconds 60"
}
}Replace your-arns-name with your actual ArNS name.
Pattern 2: Version Archives
Best for: Applications needing long-term version history
This pattern extends Pattern 1 by archiving each production release to a version-specific undername for permanent access:
@ (production) → v2.0 (current release)
staging → v2.1 (next release testing)
dev → Latest development
v2-0-0 → Version 2.0.0 (archived)
v2-1-0 → Version 2.1.0 (archived)Add archive script:
Create a script that automatically archives based on your package.json version:
const { execSync } = require('child_process');
const packageJson = require('../package.json');
// Get version from package.json (e.g., "2.1.0")
const version = packageJson.version.replace(/\./g, '-'); // "2-1-0"
console.log(`Archiving version ${version}...`);
// Deploy to version-specific undername (build already done by npm script)
execSync(
`permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --undername v${version} --ttl-seconds 3600`,
{ stdio: 'inherit' }
);
console.log(`✓ Archived at: https://v${version}_your-arns-name.arweave.net`);Then add to package.json:
{
"scripts": {
"deploy:dev": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --undername dev --ttl-seconds 60",
"deploy:staging": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --undername staging --ttl-seconds 60",
"deploy:prod": "next build && permaweb-deploy deploy --arns-name your-arns-name --deploy-folder out --ttl-seconds 3600",
"deploy:archive": "next build && node scripts/deploy-archive.js"
}
}const { execSync } = require('child_process');
const packageJson = require('../package.json');
// Get version from package.json (e.g., "2.1.0")
const version = packageJson.version.replace(/\./g, '-'); // "2-1-0"
console.log(`Archiving version ${version}...`);
// Deploy to version-specific undername (build already done by npm script)
execSync(
`permaweb-deploy deploy --arns-name your-arns-name --undername v${version} --ttl-seconds 3600`,
{ stdio: 'inherit' }
);
console.log(`✓ Archived at: https://v${version}_your-arns-name.arweave.net`);Then add to package.json:
{
"scripts": {
"deploy:dev": "vite build && permaweb-deploy deploy --arns-name your-arns-name --undername dev --ttl-seconds 60",
"deploy:staging": "vite build && permaweb-deploy deploy --arns-name your-arns-name --undername staging --ttl-seconds 60",
"deploy:prod": "vite build && permaweb-deploy deploy --arns-name your-arns-name --ttl-seconds 3600",
"deploy:archive": "vite build && node scripts/deploy-archive.js"
}
}Now whenever you run deploy:archive a version specific immutable deployment of your app we be create and hosted permanently.
For example, version 2.1.0 would be accessible forever at https://v2-1-0_your-arns-name.arweave.net.
Pattern 3: Component Architecture
Best for: Monorepos with multiple deployable parts
This pattern deploys different parts of your application to separate undernames:
@ (marketing) → Marketing website
app → Main application
docs → Documentation site
admin → Admin panelExample package.json:
{
"scripts": {
"deploy:marketing": "permaweb-deploy deploy --arns-name your-arns-name --deploy-folder ./marketing/dist --ttl-seconds 3600",
"deploy:app": "permaweb-deploy deploy --arns-name your-arns-name --undername app --deploy-folder ./app/dist --ttl-seconds 60",
"deploy:docs": "permaweb-deploy deploy --arns-name your-arns-name --undername docs --deploy-folder ./docs/dist --ttl-seconds 1800",
"deploy:all": "npm run deploy:marketing && npm run deploy:app && npm run deploy:docs"
}
}Each component can be deployed independently or all at once with npm run deploy:all.
Automating Environment Deployments
Building on the GitHub Actions workflow from the previous guide, let's create environment-specific workflows that deploy based on branch activity.
Deploy automatically when pushing to the develop branch:
name: Deploy to Dev
on:
push:
branches: [develop]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Deploy to Dev
run: npm run deploy:dev
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}Usage: Push to develop branch → Auto-deploys to dev_your-arns-name.arweave.net
Deploy automatically when pushing to the staging branch:
name: Deploy to Staging
on:
push:
branches: [staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Deploy to Staging
run: npm run deploy:staging
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}Usage: Push to staging branch → Auto-deploys to staging_your-arns-name.arweave.net
Deploy to production and create version archive on push to main:
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Configure in GitHub Settings
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Deploy to Production
run: npm run deploy:prod
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
- name: Archive Version
run: npm run deploy:archive
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}Usage: Push to main branch → Auto-deploys to your-arns-name.arweave.net and archives to v{version}_your-arns-name.arweave.net
Version archives
Every production deployment automatically creates a permanent archive based on your package.json version. For example, version 2.1.0 is archived at v2-1-0_your-arns-name.arweave.net.
Typical git workflow:
# Feature development
git checkout develop
git add .
git commit -m "Add new feature"
git push origin develop # Auto-deploys to dev
# Promote to staging
git checkout staging
git merge develop
git push origin staging # Auto-deploys to staging
# Promote to production
git checkout main
git merge staging
git push origin main # Auto-deploys to productionInstant Rollbacks with ArNS App
One of the key benefits of undernames is instant rollbacks. Since all versions are permanently stored on Arweave, you can instantly switch between them using the ArNS app.
To rollback to a previous version:
Navigate to arns.app and find your ArNS name. You'll see all undernames and their transaction IDs.
Find the undername with the version you want to rollback to (e.g., v2-0-0 or staging) and copy its transaction ID.
Click on the @ (base) record, paste the transaction ID, and save. Production now serves that version - instant rollback!
Why rollbacks are instant
You're just updating a pointer to existing data. The old version is already on Arweave, permanent and accessible. No re-upload needed!
For more details on managing undernames, see Managing ArNS via UI.
Summary
You now know how to manage multiple environments using ArNS undernames:
- Environment patterns for dev → staging → production workflows
- Version archives for permanent access to all releases
- GitHub Actions automation for branch-based deployments
- Instant rollbacks through the ArNS app interface
In our next guides we're explore other tools you can use to host websites on AR.IO Network without needing to configure permaweb-deploy.
How is this guide?
Deploying with Permaweb-Deploy
Learn how to deploy permanent web applications to Arweave using the permaweb-deploy CLI tool with Next.js and React
One Click Deployments with Arlink
Learn how to deploy decentralised applications to Arweave using Arlink's visual web interface with automated builds and ArNS integration.