Portal is a decentralized publishing platform that lets you build your own website with true ownership, built on Arweave and AO. This project consists of two main applications: an editor for content management, and an engine for dynamic portal rendering.
Portal has two persistence modes:
process(default) preserves the existing AO process-backed implementation.baseuses immutable Arweave transactions without AO processes. A small genesis manifest establishes the portal and its initial roles; subsequentportal-releasetransactions contain only changed fields or pointers to independently stored post revisions. Clients reconstruct the current portal by validating and folding authorized releases in Arweave order.
Compact releases let multiple admins and contributors publish changes without re-uploading every post. Concurrent releases from the same earlier state are merged in transaction order, while role changes take effect before later releases are authorized. Scalar settings, including the blog/docs layout mode, use direct values; users, categories, topics, links, domains, uploads, and themes use identity-keyed item operations; and pages, fonts, and post preview definitions use leaf-level object patches. Anonymous ordered arrays use compact index/splice operations, while post releases contain only immutable post transaction pointers. Legacy whole-field releases remain readable.
Both modes use up.arweave.net for uploads up to 100 KB. Larger uploads are submitted as L1 Arweave transactions and paid from the connected wallet's AR balance.
The project is organized into two main applications:
- Content creation and management interface
- Portal configuration and setup
- User management and permissions
- Design customization tools
- Media library management
- Dynamic portal rendering engine
- Theme system integration
- Zone-based layout system
- Profile and post management
- Customizable building blocks
- Framework-free blog feed, post routes, and documentation navigation
- Preserves portal light/dark colors and configured fonts while using Lunar's documentation geometry for docs
- Supports scalar
blogand Lunar-styledocslayouts while ignoring legacy page-builder data - Ships as one self-contained JavaScript bundle referenced through
reference@1.0
# Install dependencies
npm installStart the development servers:
# Start editor application (port 3000)
npm run start:editor
# Start engine application (port 5000)
npm run start:engine
# Start stripped-back engine application (port 4100)
npm run start:engine-lite
# Start either application in Arweave-only base mode
npm run start:editor:base
npm run start:engine:baseBuild the applications for production:
# Build editor application
npm run build:editor
# Build engine application
npm run build:engine
# Build the single-file lite engine
npm run build:engine-lite
# Build the Arweave-only base-mode applications
npm run build:editor:base
npm run build:engine:base# Deploy editor to main
npm run deploy:editor:main
# Deploy editor to staging
npm run deploy:editor:staging
# Deploy engine
npm run deploy:engine
# Upload Engine Lite and update the stable reference@1.0 pointer
PATH_TO_WALLET=/path/to/wallet.json npm run publish:engine-lite
# Override the reference to update
PATH_TO_WALLET=/path/to/wallet.json npm run publish:engine-lite -- --reference <reference-id>
# Bootstrap a separate new reference (normally unnecessary)
PATH_TO_WALLET=/path/to/wallet.json npm run publish:engine-lite -- --new-referenceThe current Engine Lite reference@1.0 mapping is recorded in deployments/engine-lite.json.
New portals store that stable ID as EngineReference; their HTML loader resolves its current value at runtime. The publish command updates the recorded reference by default and refreshes the fallback transaction in the deployment file.
Development Guide to follow while working on the Project - https://github.com/permaweb/portal/blob/main/docs/styleguide.md
src/
├── apps/
│ ├── editor/ # Editor application
│ ├── engine/ # Full engine application
│ └── engine-lite/ # Blog and documentation engine
├── components/ # Shared UI components
│ ├── atoms/ # Basic UI elements
│ ├── molecules/ # Composed components
│ └── organisms/ # Complex components
├── helpers/ # Utility functions and configs
├── hooks/ # Custom React hooks
├── providers/ # Context providers
├── wallet/ # Wallet integration
└── wrappers/ # Component wrappers
VITE_APP- Set toeditor,viewer, orengineto specify which application to build/serveVITE_PORTAL_MODE- Set tobasefor transaction/manifest persistence; defaults toprocessVITE_ENABLE_AO- Set tofalseto disable AO connection initialization (base-mode scripts set this automatically)VITE_ARIO_TESTNET- Set totrueto enable testnet mode (uses tario instead of ARIO)
The application supports testnet mode for development and testing:
- Mainnet: Uses ARIO for domain purchases
- Testnet: Uses tario tokens for domain purchases
-
Start in testnet mode:
npm run start:editor:testnet
-
Get tario tokens - Use the https://faucet.arweave.net/ faucet to get test tokens
-
Purchase domains - Domain registration will use tario tokens instead of turbo credits
ISC