Getting Started
This guide will teach you how to get started with deploying an app to Orrin Apps. It covers the Orrin CLI, the Orrin SDK, and the nuances of developing a standalone app.
Prerequisites
The first step is ensuring you have the correct, and up to date, packages installed.
1. Install Orrin CLI
pip3 install orrin-cli
2. Python SDK (Backend)
pip3 install orrin-sdk
3. Next.js SDK (Frontend)
npm install @orrin-apps/sdk
Configuration
Once installed, configure the CLI with your developer API key and email address for correspondence. Run the following command:
orrin config configure-dev
This command prompts you to enter your email and confirm it, then enter your Developer API Key.
Developer Account
A developer API key can be received in the Orrin Dashboard. If you do not have a developer account, you will be prompted to create one.
When you create a developer account, it’s automatically linked to your Orrin account. Your Orrin username will be displayed on your app’s marketplace listing and used to identify your developer status, granting access to the developer portal.
Architecture Note
Orrin Apps keeps the backend and frontend separate. All communication between your UI and the backend logic is handled by Stellr's servers.
An app is created upon a backend submission. You must submit a backend first. Without a backend, the UI is "stateless" and cannot be linked.
The Backend
Orrin Apps utilizes Python for all backend functionality. Functions exposed to the frontend are called actions. The Orrin SDK enforces an allowlist of libraries to ensure security and stability.
Allowed Libraries
Initialization
Import the OrrinSDK class and create an instance. The constructor takes 3 required arguments:
| Argument | Type | Description |
|---|---|---|
| developer_api_key | str | Your Developer API key from the dashboard. |
| app_name | str | Unique name of the app. No spaces allowed. |
| desc | str | A brief (1-sentence) description. |
from orrinsdk import OrrinSDK orrin_sdk = OrrinSDK( developer_api_key='<your_api_key>', app_name='<YourAppName>', desc='<DescriptionOfYourApp>' )
Registering Actions
Use the @action decorator to register a function. The action name determines the entrypoint and must match the function name.
| Argument | Type | Description |
|---|---|---|
| name | str | Required. Must explicitly match function name. |
| required_payload | list | List of dicts defining arguments (if no default value). |
| extra_metadata | dict | Optional context dictionary. |
Defining Payload Schema
# Structure for required_payload list items: { "name": "<argument_name>", "type": "<argument_type>" # Use "any" for no restrictions }
Example Action Registration
# Assuming orrin_sdk is initialized @orrin_sdk.action('test') def test(): return {"Message": "Done!"}
Example Action Registration with Arguments
# Assuming orrin_sdk is initialized @orrin_sdk.action( 'test', required_payload=[{"name": "a", "type": "any"}] ) def test(a): return {"Message": f"{a}"}
Example Action Registration with Extra Metadata
# Assuming orrin_sdk is initialized @orrin_sdk.action( 'test', required_payload=[{"name": "a", "type": "any"}], extra_metadata={"usage": "use for testing"} ) def test(a): return {"Message": f"{a}"}
* Actions must return a Python dictionary.
Finalizing
Code execution happens in the abstract until you invoke finalize(). This method bundles your configuration and sends it to the server. Add this to the very end of your script.
orrin_sdk.finalize()
Upon success, you will receive an App ID. Keep this safe! You will need it to link your Frontend.
The Frontend
Orrin Apps utilizes Next.js as the frontend framework. The Next.js SDK provides an OrrinProvider to handle authentication and API communication.
Step 1: Create Client
Create a file (e.g., client.ts) to initialize your Orrin Client.
import { OrrinClient } from "@orrin-apps/sdk" export const client = new OrrinClient({ apiKey: "<your_api_key>", appID: "<app_id>" // The App ID received after uploading backend });
Step 2: Create Providers Wrapper
Since OrrinProvider utilizes context, create a client-side wrapper (e.g., providers.tsx).
"use client"; import { OrrinProvider } from "@orrin-apps/sdk"; import { client } from "./client"; export function Providers({ children }: { children: React.ReactNode }) { return ( <OrrinProvider client={client}> {children} </OrrinProvider> ); }
Step 3: Update Layout
Wrap your application in layout.tsx.
import { Providers } from "./providers"; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en"> <body> <Providers>{children}</Providers> </body> </html> ); }
Using Actions
To call backend functions, use the useAction hook. It returns an execution function and a loading state.
- execute: Function to trigger action & pass payload.
- loading: Boolean state for UI feedback.
// Inside a component const { execute, loading } = useAction("test"); // Execution example const response = execute({"a": "test!"});
Full Component Example*
// Example usage export default function Home() { const { execute, loading } = useAction( "test" ); const [toShow, setToShow] = useState<string>(""); useEffect(() => { const d = async () => { try { const b = await execute({ "a": "lol" }); setToShow(b.result["message"]); } catch (e) { alert(e); } } d() }, []); return (<p>{toShow}</p>) }
* You do not need to name the destructured variables from useAction as they are seen in the example. Apply your naming convention to the variables so you know what they do.
The response will be wrapped in a result object: { "result": { ...your_backend_return } }.
If the backend has not been authorized, execute will return a 400 response with backend_not_authorized as the message.
Deployment
Next.Config.ts Requirement
Your next.config.ts file must be configured for static export with a specific base path matching your App Name.
const nextConfig = { output: 'export', trailingSlash: true, basePath: '/<YourAppName>/current', // Must match Backend App Name reactStrictMode: true, }; module.exports = nextConfig;
1. Generate ZIP
From the root of your Next.js directory, run:
orrin ui generate-zip
This builds the project, exports it, and zips the static content.
2. Upload & Link
Upload the UI and link it to the app created by your backend code:
orrin ui upload --app <AppName>