Getting Started
This guide will walk you through creating your first Cloudillo application.
Prerequisites
- Node.js 18+ and pnpm installed
- Basic knowledge of TypeScript/JavaScript
- Familiarity with React (optional, for UI apps)
Installation
For Standalone Apps
pnpm add @cloudillo/coreFor React Apps
pnpm add @cloudillo/core @cloudillo/reactFor Real-Time Database
pnpm add @cloudillo/rtdbFor Collaborative Editing
pnpm add @cloudillo/core yjs y-websocketYour First App: Hello Cloudillo
Let’s create a simple app that displays the current user’s profile.
Step 1: Initialize the App
Create src/index.ts:
import { getAppBus } from '@cloudillo/core'
async function main() {
// Get the singleton message bus
const bus = getAppBus()
// Initialize with your app name
await bus.init('hello-cloudillo')
console.log('Initialized successfully!')
console.log('Access Token:', bus.accessToken)
console.log('User ID:', bus.idTag)
console.log('Tenant ID:', bus.tnId)
console.log('Roles:', bus.roles)
}
main().catch(console.error)Step 2: Fetch User Profile
import { getAppBus, createApiClient } from '@cloudillo/core'
async function main() {
const bus = getAppBus()
await bus.init('hello-cloudillo')
// Create an API client
const api = createApiClient({
idTag: bus.idTag!,
authToken: bus.accessToken
})
// Fetch the current user's profile
const profile = await api.profiles.getOwn()
console.log('Profile:', profile)
console.log('Name:', profile.name)
console.log('ID Tag:', profile.idTag)
console.log('Profile Picture:', profile.profilePic)
}
main().catch(console.error)Step 3: Create a Post
import { getAppBus, createApiClient } from '@cloudillo/core'
async function main() {
const bus = getAppBus()
await bus.init('hello-cloudillo')
const api = createApiClient({
idTag: bus.idTag!,
authToken: bus.accessToken
})
// Create a new post
const newPost = await api.actions.create({
type: 'POST',
content: {
text: 'Hello from my first Cloudillo app!',
title: 'My First Post'
}
})
console.log('Post created:', newPost)
}
main().catch(console.error)React Example
For React applications, use the provided hooks:
import React from 'react'
import { useCloudillo, useAuth, useApi } from '@cloudillo/react'
function App() {
// useCloudillo handles initialization
const { token } = useCloudillo('hello-cloudillo')
if (!token) return <div>Loading...</div>
return <Profile />
}
function Profile() {
const [auth] = useAuth() // Returns tuple [auth, setAuth]
const { api } = useApi() // Returns { api, authenticated, setIdTag }
const [profile, setProfile] = React.useState(null)
React.useEffect(() => {
if (!api) return
api.profiles.getOwn().then(setProfile)
}, [api])
if (!api) return <div>No API client</div>
if (!profile) return <div>Loading...</div>
return (
<div>
<h1>Welcome, {profile.name}!</h1>
<p>ID: {auth?.idTag}</p>
{profile.profilePic && (
<img src={profile.profilePic} alt="Profile" />
)}
</div>
)
}
export default AppReal-Time Database Example
Here’s how to use the real-time database:
import { getAppBus, getRtdbUrl } from '@cloudillo/core'
import { RtdbClient } from '@cloudillo/rtdb'
async function main() {
const bus = getAppBus()
await bus.init('rtdb-example')
// Create RTDB client
const rtdb = new RtdbClient({
dbId: 'my-database-file-id',
auth: { getToken: () => bus.accessToken },
serverUrl: getRtdbUrl(bus.idTag!, 'my-database-file-id', bus.accessToken!)
})
// Connect to the database
await rtdb.connect()
// Get a collection reference
const todos = rtdb.collection('todos')
// Subscribe to real-time updates
todos.onSnapshot((snapshot) => {
console.log('Todos updated:', snapshot.docs.map(doc => doc.data()))
})
// Create a document using batch
const batch = rtdb.batch()
batch.create(todos, {
title: 'Learn Cloudillo',
completed: false,
createdAt: Date.now()
})
await batch.commit()
// Query documents
const incompleteTodos = await todos.query({
filter: { equals: { completed: false } },
sort: [{ field: 'createdAt', ascending: false }]
})
console.log('Incomplete todos:', incompleteTodos)
}
main().catch(console.error)Collaborative Editing Example
Create a collaborative text editor:
import { getAppBus, openYDoc } from '@cloudillo/core'
import * as Y from 'yjs'
async function main() {
const bus = getAppBus()
await bus.init('collab-editor')
// Create a Yjs document
const yDoc = new Y.Doc()
// Open collaborative document (format: ownerTag:documentId)
const { provider } = await openYDoc(yDoc, 'owner.cloudillo.net:my-doc-id')
// Get shared text
const yText = yDoc.getText('content')
// Listen for changes
yText.observe(() => {
console.log('Text changed:', yText.toString())
})
// Insert text
yText.insert(0, 'Hello, collaborative world!')
// See awareness (other users' cursors/selections)
provider.awareness.on('change', () => {
const states = provider.awareness.getStates()
console.log('Connected users:', states.size)
})
}
main().catch(console.error)Microfrontend Integration
If you’re building an app to run inside the Cloudillo shell:
import { getAppBus, createApiClient } from '@cloudillo/core'
async function main() {
// Get the singleton message bus
const bus = getAppBus()
// init() automatically handles the shell protocol
await bus.init('my-microfrontend')
// Create an API client
const api = createApiClient({
idTag: bus.idTag!,
authToken: bus.accessToken
})
// The shell provides via bus properties:
// - bus.idTag (user's identity)
// - bus.tnId (tenant ID)
// - bus.roles (user roles)
// - bus.darkMode (theme preference)
// - bus.access ('read' or 'write')
// Your app logic here...
}
main().catch(console.error)Error Handling
All API calls can throw errors. Handle them appropriately:
import { getAppBus, createApiClient } from '@cloudillo/core'
const bus = getAppBus()
await bus.init('my-app')
try {
const api = createApiClient({
idTag: bus.idTag!,
authToken: bus.accessToken
})
const profile = await api.profiles.getOwn()
} catch (error) {
if (error instanceof Error) {
console.error('Error:', error.message)
}
}Next Steps
Now that you’ve created your first Cloudillo app, explore more features:
- Authentication - Learn about token-based authentication
- Client Libraries - Deep dive into available libraries
- REST API - Comprehensive API reference
- Actions - Implement social features
- RTDB - Build real-time apps
- CRDT - Collaborative editing patterns
- Microfrontends - Build shell-integrated apps
Common Patterns
Handling Dark Mode
import { getAppBus } from '@cloudillo/core'
const bus = getAppBus()
await bus.init('my-app')
// Check dark mode preference
if (bus.darkMode) {
document.body.classList.add('dark-theme')
}Using Query Parameters
import { getAppBus, createApiClient } from '@cloudillo/core'
const bus = getAppBus()
await bus.init('my-app')
const api = createApiClient({
idTag: bus.idTag!,
authToken: bus.accessToken
})
// List actions with filters
const posts = await api.actions.list({
type: 'POST',
status: 'A', // Active
limit: 20
})Uploading Files
import { getAppBus, createApiClient } from '@cloudillo/core'
const bus = getAppBus()
await bus.init('my-app')
const api = createApiClient({
idTag: bus.idTag!,
authToken: bus.accessToken
})
// Upload a file using the uploadBlob helper
const result = await api.files.uploadBlob(
'gallery', // preset
'image.png', // fileName
imageBlob, // file data
'image/png' // contentType
)
console.log('Uploaded file:', result.fileId)Build and Deploy
Development
Most apps run as microfrontends inside the Cloudillo shell. Use your preferred build tool (Rollup, Webpack, Vite):
# Using Rollup (like the example apps)
pnpm build
# Using Vite
vite buildProduction
Deploy your built app to any static hosting:
# The built output goes to the shell's apps directory
cp -r dist /path/to/cloudillo/shell/public/apps/my-appTroubleshooting
“Failed to initialize”
Make sure you’re either:
- Running inside the Cloudillo shell (as a microfrontend), or
- Providing authentication manually for standalone apps
“CORS errors”
Ensure your Cloudillo server is configured to allow requests from your app’s origin.
“WebSocket connection failed”
Check that:
- The WebSocket URL is correct (wss:// for production)
- The server is running and accessible
- Your authentication token is valid
Example Apps
Check out the example apps in the Cloudillo repository:
- Quillo - Rich text editor with Quill
- Prello - Presentation tool
- Sheello - Spreadsheet application
- Formillo - Form builder
- Todollo - Task management
All use the same patterns described in this guide.