Articles

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:

Use server execution for:

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:

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.