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