04.05.26
How to Embed a Real Coding Tutorial in Your Docs
A practical checklist for adding an editable project, terminal, persistence, previews, and server fallback to documentation.
The best coding tutorials are not just code blocks. They let the reader edit files, run commands, see output, and inspect the result. That used to mean sending the reader to a local setup guide or a remote container. A browser-first runtime makes another option practical: put the dev loop inside the docs page.
This article is a checklist for building that kind of tutorial with Verklet.
1. Start with the runtime boundary
Decide which work should happen in the browser and which work may need a server backend.
Use the browser backend for:
- JavaScript and TypeScript examples.
- Simple Node.js commands.
- Supported Python through Pyodide.
- Generated files, SVGs, JSON, and static artifacts.
- Quick previews and interactive exercises.
Use server execution for:
uv.- Native Python wheels.
- Native Linux tools.
- Subprocess-heavy examples.
- Workspaces that should not depend on browser storage.
For most tutorials, backend: 'auto' is the right default because the
tutorial starts cheap and promotes only when it needs native capability.
2. Boot with a project ID
Each integration uses a public projectId from your Verklet account.
The project ID lets Verklet serve compatible runtime assets and registry
configuration for the SDK version installed in your app.
import { Runtime } from '@verklet/sdk';
const runtime = await Runtime.boot({
projectId: 'prj_your_project_id',
backend: 'auto',
persistenceKey: 'docs-tutorial-intro',
});
The persistenceKey is what lets the tutorial restore the reader's files
after a reload.
3. Serve the required browser headers
The browser backend uses SharedArrayBuffer for synchronous filesystem
behavior. Your runtime route needs cross-origin isolation:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Same-origin assets should also return:
Cross-Origin-Resource-Policy: same-origin
Scope these headers to the routes that need the runtime. COOP and COEP can break third-party embeds that do not return compatible headers.
4. Mount a real project
A tutorial should mount files the reader can understand. Keep the first project small enough to scan, but real enough to run.
await runtime.mount({
'package.json': {
file: {
contents: JSON.stringify({
scripts: { dev: 'node server.js' },
dependencies: {},
}),
},
},
'server.js': {
file: {
contents: `
import http from 'node:http';
http.createServer((_req, res) => {
res.end('Hello from the tutorial');
}).listen(3000);
`,
},
},
});
Once files are mounted, the editor and terminal should operate on the same runtime filesystem. Avoid making the code block, editor, and terminal separate sources of truth.
5. Wire the terminal to process events
The terminal should stream stdout and stderr as the process runs. It should also show exit state and allow cancellation where the command supports it.
const process = await runtime.spawn('npm', ['run', 'dev']);
process.output.pipeTo(
new WritableStream({
write(chunk) {
terminal.write(chunk);
},
}),
);
For tutorials, clear process state matters. Readers should know whether the command is still running, exited successfully, or failed.
6. Show the preview in the page
When a process opens a port, expose it as a preview surface in your docs. The reader should not need to copy a URL or open a tunnel.
The important UX rule is simple: keep the editor, terminal, and preview visible together. The article explains the concept; the embedded runtime lets the reader prove it.
7. Make fallback explicit
Some readers will arrive in browsers, privacy modes, or corporate environments where a full browser runtime is not available. Detect capabilities and give a clear fallback:
import { detectCapabilities } from '@verklet/sdk';
const caps = await detectCapabilities();
if (!caps.crossOriginIsolated || !caps.sharedArrayBuffer) {
// Render a static code sample or ask the reader to open a supported route.
}
For server-capable tutorials, you can also choose to start with
backend: 'server' when the whole lesson depends on native tooling.
8. Keep the lesson state recoverable
Readers reload pages. Laptops sleep. Sessions get interrupted. A good embedded tutorial should restore what it can.
Use persistenceKey for browser snapshots. Keep lesson IDs stable. Let
the reader reset the exercise when they want a clean copy.
That turns the tutorial from a fragile demo into a real workspace.
The result
A real coding tutorial has five visible parts:
- Explanation.
- Editable files.
- Terminal output.
- Preview.
- Reset and restore behavior.
The runtime should make those pieces feel like one environment. That is the difference between documentation that shows code and documentation that lets the reader work.