
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-onchain
Advanced tools
Your application on-chain forever! No servers, no hosting fees, no downtime. Welcome to the decentralized web.
react-onchain makes this a reality. It's a CLI tool that inscribes your entire application on-chain using the BSV blockchain and 1Sat Ordinals. Every fileβHTML, CSS, JavaScript, imagesβbecomes an immutable ordinal inscription.
The best part? Most apps deploy for less than a penny. Your React app becomes censorship-resistant, permanently accessible, and truly decentralizedβall for the cost of a fraction of a cent.
react-onchain is fully open source and decentralized. Anyone can add support for additional indexers and content providers by implementing the service interfaces in src/lib/service-providers/.
See src/lib/service-providers/IndexerService.ts for the base interface and src/lib/service-providers/gorilla-pool/ for a reference implementation.
For users:
No installation needed! Just use npx:
npx react-onchain deploy
For developers/contributors:
Clone and build from source:
git clone https://github.com/danwag06/react-onchain.git
cd react-onchain
npm install
npm run build
Or install globally for development:
npm install -g .
If your app uses React Router for client-side routing, add this one line to your Router component:
import { BrowserRouter as Router } from 'react-router-dom';
function App() {
return (
<Router basename={(window as any).__REACT_ONCHAIN_BASE__ || '/'}>{/* Your routes */}</Router>
);
}
That's it! This single line makes your React Router app work with on-chain deployments AND locally with zero configuration.
window.__REACT_ONCHAIN_BASE__ = /content/{txid}_{vout} (for content providers like ordfs.network)'/''/'Why is this needed? React Router needs to know the base path when your app is deployed to a subpath (like /content/{txid}_{vout}). This one-liner automatically detects and configures it.
# For Vite
npm run build
# For Create React App
npm run build
# For Next.js (static export)
npm run build && npm run export
β οΈ Use an Ordinals-Compatible Wallet
Use a wallet that supports 1Sat Ordinals (we recommend yours.org) to ensure your inscription UTXOs aren't accidentally spent. Regular wallets may not recognize 1-satoshi ordinal outputs and could spend them as regular funds, destroying your inscriptions permanently.
Simply run the deploy command - the CLI will guide you through an interactive setup:
npx react-onchain deploy
The interactive prompts will ask you for:
The destination address is automatically derived from your payment key.
The CLI will output the entry point URL. For example, using ordfs.network as a content provider:
https://app.reactonchain.com/content/<txid>_<vout>
After your first deployment, a .env file is automatically created with your configuration. This means subsequent deployments are even simpler - just run:
npx react-onchain deploy
The CLI will:
.envdeployment-manifest.jsonAll configuration is automatically managed for you!
# Deploy application (interactive prompts)
npx react-onchain deploy
# Inscribe a single file
npx react-onchain inscribe <file>
# Query version history (on-chain)
npx react-onchain version:history [versioningOriginInscription]
# Get version details (on-chain)
npx react-onchain version:info <version> [versioningOriginInscription]
# Get inscription info (on-chain)
npx react-onchain version:summary [versioningOriginInscription]
# View deployment history (local)
npx react-onchain manifest:history
The recommended way to deploy is using the interactive CLI, which guides you through the setup:
npx react-onchain deploy
The CLI will:
.envFirst deployment example:
? Select build directory: ./dist
? Enter payment private key (WIF): **********************
? Enable versioning? Yes
? Enter version tag (e.g., 1.0.0): 1.0.0
? Enter version description: Initial release
? Enter application name: MyDApp
π Deployment Configuration
ββββββββββββββββββββββββββββββββββββββ
Build directory: ./dist
Fee rate: 100 sats/KB
Version: 1.0.0
Description: Initial release
App name: MyDApp (new versioning inscription)
β οΈ This will inscribe files to the blockchain and spend satoshis.
? Proceed with deployment? Yes
π Deploying to BSV Blockchain...
Subsequent deployments:
npx react-onchain deploy
The CLI auto-loads everything from .env and only prompts for the new version information!
For automation or CI/CD pipelines, you can bypass interactive prompts using flags:
| Flag | Alias | Description | Default |
|---|---|---|---|
--build-dir <directory> | -b | Build directory to deploy | ./dist |
--payment-key <wif> | -p | Payment private key in WIF format (destination auto-derived) | Prompted |
--sats-per-kb <number> | -s | Satoshis per KB for fees | 100 |
--dry-run | Test deployment without broadcasting | false | |
--version-tag <string> | Version identifier (e.g., "1.0.0") | Prompted | |
--version-description <string> | Changelog or release notes | Prompted | |
--app-name <string> | Application name for new versioning inscription | Prompted | |
--change <address> | -c | Change address (optional, for UTXO change outputs) | Auto |
--manifest <file> | -m | Output manifest file path | Auto |
--ordinal-content-url <url> | Ordinal content delivery URL | Auto | |
--ordinal-indexer-url <url> | Ordinal indexer API URL | Auto |
Automated deployment example:
# First deployment with flags (no prompts)
npx react-onchain deploy \
--build-dir ./dist \
--payment-key L1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t1u2v3w4x5y6z \
--version-tag "1.0.0" \
--version-description "Initial release" \
--app-name "MyDApp"
# Subsequent deployment (config auto-loaded from .env)
npx react-onchain deploy \
--version-tag "1.1.0" \
--version-description "Bug fixes"
# Dry run (test without spending)
npx react-onchain deploy --dry-run
# Custom fee rate
npx react-onchain deploy --sats-per-kb 100
Note: When flags are provided, interactive prompts are automatically skipped. This is perfect for CI/CD automation.
The inscribe command allows you to inscribe individual files to the BSV blockchain. Unlike the deploy command which handles entire React applications, inscribe is a lower-level utility for inscribing single files directly.
npx react-onchain inscribe <file> [options]
| Flag | Short | Description | Default |
|---|---|---|---|
--payment-key <wif> | -p | Payment private key in WIF format | From PAYMENT_KEY in .env |
--protocol <type> | Protocol: b (B:// protocol) or 1sat (1Sat Ordinals) | b | |
--destination <address> | -d | Destination address for the inscription | Payment key address |
--sats-per-kb <number> | -s | Satoshis per KB for transaction fees | From config (defaults to env) |
--content-type <type> | -t | MIME content type | Auto-detected from extension |
Basic usage (with .env configuration):
npx react-onchain inscribe ./image.png
Inscribe with all options specified:
npx react-onchain inscribe ./document.pdf \
--payment-key "your-wif-key-here" \
--protocol b \
--destination "1A2B3C..." \
--sats-per-kb 50 \
--content-type "application/pdf"
Using 1Sat Ordinals protocol:
npx react-onchain inscribe ./rare-nft.png --protocol 1sat
Inscribe a video file:
npx react-onchain inscribe ./video.mp4 --sats-per-kb 10
The command auto-detects content types for 40+ file extensions:
.html, .css, .js, .mjs, .json, .webmanifest.png, .jpg, .jpeg, .gif, .svg, .webp, .ico, .bmp, .tiff.woff, .woff2, .ttf, .eot, .otf.mp4, .webm, .mov, .avi, .mkv, .m4v, .ogg.mp3, .wav, .m4a, .aac, .flac, .ogg.pdf, .txt, .xml, .csv, .md.wasm, .zip, .tar, .gz, .7zFor unknown extensions, it defaults to application/octet-stream.
The command displays:
The inscribe command is useful for:
This is a simpler, more direct alternative to the deploy command when you just need to put a single file on-chain.
After successful deployment, you'll see detailed information about inscribed files:
β‘ Inscribing to BSV Blockchain
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β assets/react-CHdo91hT.svg β 494c43a6...
β vite.svg β 712d1b3c...
β assets/index-B7tBotfE.js β 896b0d05...
β assets/index-COcDBgFa.css β 58b02b11...
β index.html β f16f3780...
β versioning-metadata β 7b1c2bc4...
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Deployment Complete! β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π New Inscriptions
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. index.html 6.03 KB f16f3780...
2. versioning-metadata 1.25 KB 7b1c2bc4...
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SUBTOTAL 7.28 KB 2 files
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π¦ Cached Files (Reused)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. assets/react-CHdo91hT.svg 4.03 KB 494c43a6...
2. vite.svg 1.46 KB 712d1b3c...
3. assets/index-B7tBotfE.js 223.33 KB 896b0d05...
4. assets/index-COcDBgFa.css 1.35 KB 58b02b11...
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SUBTOTAL 230.17 KB 4 files
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Total
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
TOTAL 237.45 KB 6 files
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Deployment Stats
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
New files: 2 (7.28 KB)
Cached files: 4
Total files: 6 (237.45 KB)
Inscription cost: ~8 satoshis
Transactions: 2
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π¦ Versioning
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Origin Inscription: f852b8a7...
Version: 1.0.1
Version redirect: β Enabled
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β¨ Entry Point (example using ordfs.network)
https://ordfs.network/content/f16f3780...
π Files Saved
β’ deployment-manifest.json
β’ .env (configuration for next deployment)
Notice the "Cached Files (Reused)" section? react-onchain intelligently reuses files from previous deployments when content hasn't changed. This dramatically reduces costs for subsequent deployments - you only pay to inscribe what actually changed!
In the example above:
Point your domain to your deployment using DNS redirects or URL rewrites. Each deployment is permanent and accessible at its unique URLβyou control which version users see via DNS.
Key Point: Accessing /content/<origin> directly will automatically redirect to the latest deployed version (no configuration needed).
URL Behavior:
/content/<origin> β Loads the latest version/content/<origin>?version=1.2.0 β Redirects to version specifiedAll deployments are automatically versioned with on-chain history tracking. Users can access specific versions via URL parameters, enabling safe rollbacks and version pinning.
The interactive CLI guides you through deploying your first version:
npx react-onchain deploy
You'll be prompted for all necessary information:
? Select build directory: ./dist
? Payment key (WIF format): **********************
? App name (for versioning): MyDApp
? Version tag: 1.0.0
? Version description: Initial release
After deployment, a .env file is automatically created containing all your configuration (payment key, build directory, app name, and versioning inscription). The destination address is automatically derived from your payment key. This file is in .gitignore to protect your private keys.
Or use flags for automation:
npx react-onchain deploy \
--build-dir ./dist \
--payment-key <WIF> \
--app-name "MyDApp" \
--version-tag "1.0.0" \
--version-description "Initial release"
After your first deployment, subsequent versions are incredibly simple:
npx react-onchain deploy
The CLI will:
.env and deployment-manifest.jsonOr with flags:
npx react-onchain deploy \
--version-tag "1.1.0" \
--version-description "Added dark mode and bug fixes"
Version redirect script is automatically injected starting with the second deployment, enabling ?version= URL parameters.
https://app.reactonchain.com/content/<ORIGIN>) - always serves latest location<ENTRY_POINT_URL>?version=1.0.0 - redirects to specific versionPoint your domain to always serve the latest version via your chosen content provider:
# Example: DNS/CDN redirect to always get latest (using app.reactonchain.com)
https://app.reactonchain.com/content/<ORIGIN>
Or point to the entry point and let users control versions via ?version= parameter.
# View all versions (inscription auto-read from manifest if not provided)
npx react-onchain version:history [INSCRIPTION_ORIGIN]
# Get specific version details (inscription auto-read from manifest if not provided)
npx react-onchain version:info <VERSION> [INSCRIPTION_ORIGIN]
# Get inscription information (inscription auto-read from manifest if not provided)
npx react-onchain version:summary [INSCRIPTION_ORIGIN]
Advanced: Version Command Options:
All version commands (version:history, version:info, version:summary) support:
| Flag | Description |
|---|---|
-m, --manifest <file> | Path to manifest file (default: deployment-manifest.json) |
-l, --limit <number> | Limit number of versions to display (history only) |
-f, --from-version <version> | Start displaying from a specific version (history only) |
-a, --all | Show all versions, ignores limit (history only) |
Note: Versioning inscription origin is auto-loaded from the manifest file. All commands accept an optional [inscription] positional argument to override.
A JSON manifest is generated after deployment:
{
"timestamp": "2025-10-27T02:00:00.000Z",
"entryPoint": "/content/abc123_0",
"files": [
{
"originalPath": "index.html",
"txid": "abc123...",
"vout": 0,
"urlPath": "/content/abc123_0",
"size": 2450
}
],
"totalFiles": 4,
"totalCost": 45678,
"totalSize": 162130,
"transactions": ["abc123...", "def456...", "ghi789...", "jkl012..."]
}
The manifest file automatically maintains a complete history of all your deployments. Each new deployment is appended to the history, creating a permanent local record.
View your deployment history:
npx react-onchain manifest:history
The history includes:
Benefits:
Note: The manifest stores complete deployment history locally. This complements the on-chain inscription metadata which has unlimited version history. All deployments remain permanently on-chain.
You can use react-onchain programmatically:
import { deployToChain } from 'react-onchain';
const config = {
buildDir: './dist',
paymentKey: 'your-wif-key', // Destination address is auto-derived from this key
version: '1.0.0',
versionDescription: 'Initial release',
appName: 'MyApp',
satsPerKb: 50,
dryRun: false,
};
const result = await deployToChain(config);
console.log(`Entry point: ${result.entryPointUrl}`);
console.log(`Total files: ${result.inscriptions.length}`);
console.log(`Total size: ${result.totalSize} bytes`);
console.log(`Total cost: ${result.totalCost} satoshis`);
console.log(`Versioning origin: ${result.versioningOriginInscription}`);
.html, .htm.css.js, .mjs.json.png, .jpg, .jpeg, .gif, .svg, .webp, .ico.woff, .woff2, .ttf, .eot, .otf.txt, .xmlInscription costs depend on:
Typical costs at 100 sats/KB:
| App Type | Size | Files | Cost (sats) | Cost (USD)* |
|---|---|---|---|---|
| Simple SPA | 200 KB | 5-10 | ~20,000 | ~$0.008 |
| Medium App | 500 KB | 20-30 | ~50,000 | ~$0.02 |
| Large App | 1 MB | 50-100 | ~100,000 | ~$0.04 |
| Complex App | 2 MB | 100+ | ~200,000 | ~$0.08 |
*Based on $40 BSV price
.map files from deploymentreact-onchain uses a domain-driven modular architecture organized by business capability:
react-onchain/
βββ src/
β βββ core/ # Domain-based business logic
β β βββ analysis/ # Build analysis & dependency graphs
β β β βββ analyzer.ts
β β β βββ analyzer.types.ts
β β β βββ index.ts
β β βββ caching/ # File caching & reuse analysis
β β β βββ analyzer.ts
β β β βββ index.ts
β β βββ chunking/ # File chunking for large files
β β β βββ chunker.ts
β β β βββ chunking.types.ts
β β β βββ index.ts
β β βββ html/ # HTML inscription (1-sat ordinal chain)
β β β βββ inscriber.ts
β β β βββ index.ts
β β βββ inscription/ # Blockchain inscription operations
β β β βββ parallelInscriber.ts
β β β βββ utxoSplitter.ts
β β β βββ inscription.types.ts
β β β βββ utils.ts
β β β βββ index.ts
β β βββ orchestration/ # Wave-based deployment coordination
β β β βββ orchestrator.ts # High-level orchestration
β β β βββ jobBuilder.ts # Wave job preparation
β β β βββ waveProcessor.ts # Wave execution
β β β βββ orchestration.types.ts
β β β βββ index.ts
β β βββ rewriting/ # URL rewriting (HTML/CSS/JS)
β β β βββ htmlRewriter.ts
β β β βββ cssRewriter.ts
β β β βββ jsRewriter.ts
β β β βββ jsonRewriter.ts
β β β βββ svgRewriter.ts
β β β βββ utils.ts
β β β βββ templates/
β β β β βββ versionRedirect.template.js
β β β β βββ basePathFix.template.js
β β β β βββ webpackPublicPathFix.template.js
β β β βββ index.ts
β β βββ versioning/ # On-chain version management
β β β βββ versioningHandler.ts # Version metadata management
β β β βββ inscriber.ts # Version inscription operations
β β β βββ versioning.types.ts
β β β βββ utils.ts
β β β βββ index.ts
β β βββ service-worker/ # Service worker generation
β β β βββ generator.ts # SW code generation
β β β βββ inscriber.ts # SW inscription operations
β β β βββ types.ts
β β β βββ ChunkFetcher.ts
β β β βββ RangeCalculator.ts
β β β βββ StreamAssembler.ts
β β β βββ index.ts
β β βββ utils.ts # Shared core utilities
β βββ lib/ # Configuration & services
β β βββ config.ts # Environment & configuration
β β βββ service-providers/
β β βββ IndexerService.ts # Indexer abstraction
β β βββ gorilla-pool/
β β β βββ indexer.ts
β β β βββ constants.ts
β β βββ index.ts
β βββ cli/ # Command-line interface
β β βββ cli.ts # CLI entry point
β β βββ utils.ts
β β βββ commands/
β β βββ deploy/
β β β βββ index.ts
β β β βββ input.ts
β β β βββ display.ts
β β β βββ progress.ts
β β βββ version/
β β β βββ index.ts
β β β βββ display.ts
β β βββ manifest/
β β βββ index.ts
β β βββ display.ts
β βββ utils/ # Shared utilities
β β βββ constants.ts
β β βββ errors.ts
β β βββ errorLogger.ts
β β βββ retry.ts
β βββ tests/ # Test suite
β β βββ analyzer.test.ts
β β βββ chunker.test.ts
β β βββ sw-local-test.ts
β βββ index.ts # Public API exports
βββ dist/ # Compiled JavaScript
βββ package.json
Key Architecture Patterns:
index.ts files in each domain.types.ts filesIndexerService interfacenpm run build)Ensure your payment address has sufficient BSV for inscriptions.
Point to the correct build directory (usually ./dist or ./build).
index.html at the rootContributions are welcome! Please follow these guidelines:
This project uses Prettier for consistent code formatting.
Format code before committing:
npm run format
Check if code is formatted correctly:
npm run format:check
VS Code Setup:
If you're using VS Code, formatting on save is already configured in .vscode/settings.json.
git checkout -b feature/your-feature-namenpm run formatnpm run buildFor questions or discussions, please open an issue on GitHub.
ISC
FAQs
Deploy applications to the BSV blockchain.
We found that react-onchain demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.