ProtoTool

The top-level tool rendering component. Accepts a schema and an optional doc-key, renders the full tool UI, and handles all Y.js plumbing internally.

ProtoTool

The main entry point component. Given a PrototypeSchema, it renders the complete tool UI: form, results, visualizations, collections, and action toolbar. All Y.js persistence is handled internally.

Props

PropTypeDefaultDescription
schemaPrototypeSchemarequiredThe tool schema object
docY.DocPass an existing Y.Doc to share state with another component
docKeystringschema.keyY.js document key — override to run multiple independent instances
disableSyncbooleanfalseForce local-only mode for this tool, regardless of the global protokit.serverSync config

Basic usage

<template>
  <ClientOnly>
    <ProtoTool :schema="breakEvenSchema" />
  </ClientOnly>
</template>

Multiple instances of the same schema

<template>
  <!-- Two independent instances with separate storage -->
  <div class="grid grid-cols-2 gap-6">
    <ClientOnly>
      <ProtoTool :schema="breakEvenSchema" doc-key="break-even-optimistic" />
    </ClientOnly>
    <ClientOnly>
      <ProtoTool :schema="breakEvenSchema" doc-key="break-even-conservative" />
    </ClientOnly>
  </div>
</template>

Local-only / demo tools

Add disable-sync to suppress server sync for a specific tool, regardless of the global protokit.serverSync config. The tool still saves to the user's local IndexedDB — inputs survive page refresh. Only the server push is skipped.

<!-- Public demo — persists locally, never pushes to server -->
<ClientOnly>
  <ProtoTool :schema="demoSchema" disable-sync />
</ClientOnly>

This is the right choice for:

  • Public marketing pages with embedded demo tools (you don't want every visitor's data on your server)
  • Scratch pad tools that are intentionally ephemeral beyond the current browser
  • Isolated test instances in development

Rendering logic

ProtoTool renders sections in this order:

  1. FormProtoForm with schema fields or sections
  2. Results badge — from schema.results.badge
  3. Stats grid — from schema.results.stats via ProtoStatGrid
  4. Visualizations — one ProtoViz per entry in schema.visualizations
  5. Collections — one ProtoCrudList per entry in schema.collections
  6. Action toolbarProtoActionBar if schema.actions is defined
  7. Reset button — if showReset is true

If schema.layout is defined, ProtoTool delegates entirely to ProtoDashboard, which respects the custom tab/row/column layout.

Custom layout delegation

// When schema.layout is defined:
const mySchema = definePrototype({
  key: 'interviews',
  layout: {
    tabs: [
      { id: 'questions',  label: 'Questions',},
      { id: 'interviews', label: 'Interviews',},
      { id: 'patterns',   label: 'Patterns',},
    ]
  },
  // rest of schema…
})

ProtoTool detects schema.layout and renders ProtoDashboard instead of the default sequential layout.

ClientOnly wrapper

Always wrap ProtoTool in <ClientOnly> — it uses IndexeddbPersistence which requires browser APIs. Provide a fallback skeleton:

<ClientOnly>
  <ProtoTool :schema="mySchema" />
  <template #fallback>
    <div class="space-y-4 animate-pulse">
      <div class="h-10 bg-muted rounded" />
      <div class="h-10 bg-muted rounded" />
      <div class="h-24 bg-muted rounded" />
    </div>
  </template>
</ClientOnly>

Using usePrototype for custom layout

If the built-in rendering doesn't fit your design, use usePrototype directly and compose your own UI:

<script setup lang="ts">
const props = defineProps<{ schema: PrototypeSchema }>()

const { state, derived, collections, computeContext, isReady, reset } =
  usePrototype(props.schema)

const badge = computed(() =>
  props.schema.results?.badge?.(computeContext.value))
</script>

<template>
  <ClientOnly>
    <div v-if="!isReady">Loading…</div>
    <template v-else>
      <!-- Completely custom layout -->
      <aside>
        <ProtoForm :schema="props.schema" :state="state" />
      </aside>
      <main>
        <UBadge v-if="badge" :color="badge.color">{{ badge.label }}</UBadge>
        <!-- Custom charts, tables, whatever -->
      </main>
    </template>
  </ClientOnly>
</template>

Need a Landing Page?

Modern landing pages with optional modules (blog, docs, forms, i18n). Let's discuss your project.

Build Your MVP

Full-stack SaaS development. Expert in database design, multi-tenancy, and scalable architecture.

Deployment Help

Dockerize your backend, set up CI/CD pipelines, deploy to Cloudflare or Hetzner. Early-stage setup.

Suggest a SaaS Tool

Missing a calculator or tool? Suggest what you'd like to see on our site.