Skip to main content

Quick Start

The kernel is framework-agnostic with zero peer dependencies. You can drive it directly, or let the React provider stack assemble Picsart services for you.

Lifecycle at a glance

createRuntime(config) construct the kernel (synchronous)


runtime.load(miniapp, options?) → IMiniappHandle { sid, bootstrap(), unload() }


handle.bootstrap(context?) → IMiniappControls { close(), destroy() }


runtime.destroy() tears down handles, DOM, rendering engine

Standalone kernel

No rendering adapter, no service providers — supply a minimal engine and auth:

import { createRuntime } from '@picsart/runtime/client';
import { fetchMiniappByPackageId } from '@picsart/miniapps-platform-sdk/requests';

const runtime = createRuntime({
container: document.getElementById('editor'),
renderingEngine: noopEngine,
auth: {
getHeaders: () => ({ Authorization: `Bearer ${token}` }),
getRefreshedHeaders: () =>
Promise.resolve({ Authorization: `Bearer ${token}` }),
getStatus: () => ({ token, status: 'resolved' }),
onRedirect: () => {},
},
hostName: 'my-app',
});

const miniapp = await fetchMiniappByPackageId('com.picsart.edit.adjust', {}, {
platform: 'website',
Authorization: `Bearer ${token}`,
});

const handle = await runtime.load(miniapp, {
onReady: () => console.log('Miniapp ready'),
onClose: () => console.log('Miniapp closed'),
});

await handle.bootstrap();

// When done
runtime.destroy();

React host (client-side rendering)

FullRuntimeProviders assembles services from Picsart's React contexts and hands them to your onServicesReady callback, ready to spread into createRuntime:

import { createRuntime, getMiniappDeeplink } from '@picsart/runtime/client';
import { createWebLayeringEngine } from '@picsart/runtime/adapters/web-layering';
import { FullRuntimeProviders } from '@picsart/runtime/providers/react/full';
import setupLayering from '@picsart/web-layering';
import { fetchMiniappByPackageId } from '@picsart/miniapps-platform-sdk/requests';

const App = () => {
const containerRef = useRef(null);

const handleServicesReady = async (services) => {
const engine = createWebLayeringEngine({ setupLayering });

const runtime = createRuntime({
container: containerRef.current,
renderingEngine: engine,
hostName: 'my-app',
...services,
});

const deeplink = getMiniappDeeplink();
const packageId = deeplink?.packageId ?? 'com.picsart.edit.adjust';

const miniapp = await fetchMiniappByPackageId(packageId, {}, {
platform: 'website',
Authorization: services.auth.getHeaders().Authorization,
});

const handle = await runtime.load(miniapp);
await handle.bootstrap();
};

return (
<FullRuntimeProviders
intl={{ language: 'en' }}
authentication={{ disableRefreshCycle: true }}
pulse={{ app: 'my-app' }}
designSystem={{ notifier: { hostType: 'editor' } }}
noNetwork
onServicesReady={handleServicesReady}
>
<div ref={containerRef} id="editor" />
</FullRuntimeProviders>
);
};

The provider tree wraps Intl, authentication, Pulse analytics, design system, error boundary, and offline detection. Each adapter is independently optional — see React Provider Adapters.

Embedded SPA

To ship a miniapp and the runtime together as one synchronously-booting bundle (no manifest fetch, no iframe), use the embedded provider — see Embedded Runtime.

Try the demos

The repository ships runnable demos under examples/. Each has its own package.json and npm ci:

npm run demo:run # standalone kernel + web-layering
npm run demo:providers:run # React provider stack
npm run demo:full-providers # all-in-one FullRuntimeProviders
npm run demo:embedded # embedded runtime