A minimal scaffold for building applications on Ratio1's distributed storage network.
┌─────────────┐ ┌───────────────┐ ┌─────────────────┐
│ Browser │─────▶│ Next.js API │─────▶│ Edge Node │
│ UI │ │ (SDK) │ │ R1FS + CStore │
└─────────────┘ └───────────────┘ └─────────────────┘
Data Flow:
Upload: Browser ──file──▶ API ──▶ R1FS.addFile() ──▶ CID
Announce: API ──CID+metadata──▶ CStore.hset()
Discover: API ──▶ CStore.hgetall() ──▶ file list ──▶ Browser
Download: Browser ──CID──▶ API ──▶ R1FS.getFile() ──▶ stream
This starter kit demonstrates the core pattern for building on Ratio1:
- Store files in R1FS (distributed file storage) → receive a CID
- Announce metadata via CStore (distributed key-value store)
- Discover & retrieve files from any node in the network
Use this as a foundation for your own applications - the Ratio1 integration code is designed to be reusable.
- Node.js 18+
- npm or pnpm
- Local Ratio1 services (sandbox or R1EN)
npm installcp .env.example .env.localEdit .env.local with your settings (see Environment Configuration below).
Sandbox mode (recommended for local development):
npm run sandboxStandard mode (uses .env.local settings):
npm run devThe app will be available at http://localhost:3333.
On first run with R1EN_CSTORE_AUTH_BOOTSTRAP_ADMIN_PWD set:
- Username:
admin - Password: (value of
R1EN_CSTORE_AUTH_BOOTSTRAP_ADMIN_PWD)
Remove R1EN_CSTORE_AUTH_BOOTSTRAP_ADMIN_PWD from .env.local after first login.
The simplest way to develop locally. The sandbox provides local R1FS and CStore services.
-
Install and start the sandbox:
# Install r1-plugins-sandbox (see: https://github.com/Ratio1/r1-plugins-sandbox) # Start with default ports: r1-plugins-sandbox --cstore-addr :41234 --r1fs-addr :41235
-
Run the app in sandbox mode:
npm run sandbox
The sandbox script automatically sets the correct URLs:
- CStore:
http://localhost:41234 - R1FS:
http://localhost:41235
For testing against real network conditions with a local edge node.
- Start an R1EN container (Docker image details to be provided)
- Configure
.env.local:R1EN_CHAINSTORE_API_URL=http://localhost:31234 R1EN_R1FS_API_URL=http://localhost:31235
- Run the app:
npm run dev
All configuration is via environment variables. The same code works across all environments - only URLs change.
| Variable | Description | Example |
|---|---|---|
R1EN_CHAINSTORE_API_URL |
CStore service URL | http://localhost:41234 |
R1EN_R1FS_API_URL |
R1FS service URL | http://localhost:41235 |
R1EN_CSTORE_AUTH_HKEY |
Hash key for user credentials | my-app-auth |
R1EN_CSTORE_AUTH_SECRET |
Password hashing secret | <random-string> |
| Variable | Description | Default |
|---|---|---|
CSTORE_HKEY |
Hash key for file metadata | ratio1-drive-test |
MAX_FILE_SIZE_MB |
Max upload size | 10 |
AUTH_SESSION_COOKIE |
Session cookie name | r1-session |
AUTH_SESSION_TTL_SECONDS |
Session lifetime | 86400 (24h) |
DEBUG |
Enable debug logging | false |
See .env.example for complete documentation.
A distributed, content-addressed file storage system:
- Files are stored on edge nodes and addressed by CID (Content Identifier)
- Similar to IPFS, optimized for the Ratio1 network
- Supports optional encryption with user-provided secret keys
SDK methods: r1fs.addFile(), r1fs.getFile(), r1fs.addFileBase64(), r1fs.getFileBase64()
A distributed key-value store for metadata and coordination:
- Used to announce/discover file metadata across the network
- Supports simple key-value and hash-based storage
- All values are JSON strings
SDK methods: cstore.setValue(), cstore.getValue(), cstore.hset(), cstore.hget(), cstore.hgetall()
1. UPLOAD: client.r1fs.addFile(file) → returns { cid, ee_node_address }
2. ANNOUNCE: client.cstore.hset({
hkey: 'my-app-files',
key: ee_node_address,
value: JSON.stringify([{ cid, filename, owner, ... }])
})
3. DISCOVER: client.cstore.hgetall({ hkey: 'my-app-files' })
→ returns { node1: '[...]', node2: '[...]', ... }
4. DOWNLOAD: client.r1fs.getFile({ cid, secret })
→ returns file data
r1fs-starter/
├── app/ # Next.js App Router
│ ├── api/ # Backend API routes
│ │ ├── upload/ # File upload (R1FS + CStore)
│ │ ├── download/ # File download (R1FS)
│ │ ├── files/ # List files (CStore)
│ │ ├── cstore-status/ # CStore health check
│ │ └── r1fs-status/ # R1FS health check
│ ├── login/ # Login page
│ └── page.tsx # Main dashboard
├── components/ # React UI components
├── lib/
│ ├── ratio1-client.ts # SDK client singleton (REUSE THIS!)
│ ├── config.ts # Environment configuration
│ ├── types.ts # TypeScript interfaces
│ ├── auth/ # Authentication utilities
│ ├── contexts/ # React contexts
│ └── services/ # Client-side API helpers
└── .env.example # Environment template
lib/ratio1-client.ts- Centralized SDK initialization. Reuse this pattern in your apps.lib/config.ts- Environment-aware configuration. Demonstrates the zero-diff approach.app/api/upload/route.ts- Complete upload flow: R1FS store → CStore announce.app/api/files/route.ts- Discovery flow: CStore query → parse → transform.
- Clone and customize - Replace the demo UI with your domain-specific interface
- Keep the integration - The
lib/ratio1-client.tsandlib/config.tswork as-is - Use your own HKEY - Change
CSTORE_HKEYto namespace your app's data - Extend the API - Add your own routes following the patterns in
app/api/
docker build -t r1fs-starter .
docker run -p 3333:3333 \
-e R1EN_CHAINSTORE_API_URL=http://host.docker.internal:41234 \
-e R1EN_R1FS_API_URL=http://host.docker.internal:41235 \
-e R1EN_CSTORE_AUTH_HKEY=my-auth \
-e R1EN_CSTORE_AUTH_SECRET=my-secret \
r1fs-starterdocker-compose up -d- Next.js 15 with App Router
- React 19
- TypeScript
- Tailwind CSS
- @ratio1/edge-sdk-ts - R1FS + CStore SDK
- @ratio1/cstore-auth-ts - Authentication helper
MIT
For more information about the Ratio1 network, visit ratio1.ai.