Repository navigation
Integration Guide
Ved Gupta edited this page Oct 15, 2026
·
6 revisions
How to integrate @innovatorved/code-lab (v1.4.0) into React, Next.js, Vite, and static HTML / CDN environments.
npm install @innovatorved/code-lab
# or
bun add @innovatorved/code-lab<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@innovatorved/code-lab@1.4.0/dist/code-lab.css">
<script src="https://cdn.jsdelivr.net/npm/@innovatorved/code-lab@1.4.0/dist/code-lab.js"></script><link rel="stylesheet" href="https://unpkg.com/@innovatorved/code-lab@1.4.0/dist/code-lab.css">
<script src="https://unpkg.com/@innovatorved/code-lab@1.4.0/dist/code-lab.js"></script>Create a reusable CodeLabEditor component:
// CodeLabEditor.tsx
import React, { useEffect, useRef } from 'react';
import CodeLab, { CodeLabWorkbench, CodeLabOptions } from '@innovatorved/code-lab';
import '@innovatorved/code-lab/dist/code-lab.css';
interface CodeLabProps extends CodeLabOptions {
className?: string;
style?: React.CSSProperties;
}
export const CodeLabEditor: React.FC<CodeLabProps> = ({ className, style, ...options }) => {
const containerRef = useRef<HTMLDivElement>(null);
const workbenchRef = useRef<CodeLabWorkbench | null>(null);
useEffect(() => {
if (!containerRef.current) return;
// Mount workbench
workbenchRef.current = CodeLab.mount(containerRef.current, {
...options,
persistState: options.persistState ?? true
});
// Cleanup on unmount
return () => {
if (workbenchRef.current) {
workbenchRef.current.destroy();
workbenchRef.current = null;
}
};
}, [options.id]);
return (
<div
ref={containerRef}
className={className}
style={{ width: '100%', height: '100%', minHeight: '600px', ...style }}
/>
);
};import { CodeLabEditor } from './CodeLabEditor';
export function App() {
return (
<div style={{ height: '100vh', width: '100vw' }}>
<CodeLabEditor
id="react-demo-lab"
title="Distributed KV Store"
mode="sandbox"
language="ts"
entry="index.ts"
files={{
'index.ts': 'console.log("KV Store initialized");',
'store.ts': 'export class Store { private m = new Map(); }'
}}
onRun={(res) => console.log('Run finished:', res)}
/>
</div>
);
}Because Monaco Editor and Web Workers require browser APIs (window, Worker, Blob), use dynamic client loading:
// app/labs/[slug]/page.tsx
'use client';
import dynamic from 'next/dynamic';
const CodeLabEditor = dynamic(
() => import('./CodeLabEditor').then((mod) => mod.CodeLabEditor),
{ ssr: false, loading: () => <div style={{ background: '#0a0a0a', height: '100vh', color: '#888', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>Loading CodeLab IDE...</div> }
);
export default function LabPage({ params }: { params: { slug: string } }) {
return (
<main style={{ height: '100vh' }}>
<CodeLabEditor
id={`lab-${params.slug}`}
title={`Lab: ${params.slug}`}
mode="guided"
language="js"
files={{
'demo.js': 'console.log("Demo running");',
'test.js': 'const { test } = require("node:test"); test("ok", () => {});'
}}
/>
</main>
);
}// main.ts
import CodeLab from '@innovatorved/code-lab';
import '@innovatorved/code-lab/dist/code-lab.css';
const container = document.getElementById('app')!;
const lab = CodeLab.mount(container, {
id: 'vite-sandbox',
title: 'Vite Embedded CodeLab',
mode: 'sandbox',
language: 'ts',
files: {
'index.ts': 'console.log("Vite + CodeLab");'
}
});
// Imperative API access
lab.on('change', () => {
console.log('Files changed:', lab.getFiles());
});CodeLab uses the Geist Monochrome design system with semantic CSS tokens.
To enforce theme programmatically:
CodeLab.mount('#editor', {
theme: 'dark', // 'dark' | 'light' | 'auto'
// ...
});To sync with your website's data-theme attribute, CodeLab automatically inspects:
document.documentElement.getAttribute('data-theme')options.theme-
prefers-color-schememedia query
You can override variables in your stylesheet:
/* Custom theme overrides */
.codelab-workbench {
--cl-bg: #0d1117;
--cl-bg-panel: #161b22;
--cl-border: #30363d;
--cl-fg: #f0f6fc;
}Getting Started
IDE & Runtime Reference